linux: make KernelStateProvider handle aggregate prev_states of sched_switch
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / callstack / CallStackStateProvider.java
CommitLineData
e8251298 1/*******************************************************************************
ed902a2b 2 * Copyright (c) 2013, 2015 Ericsson
e8251298
PT
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
12
2bdf0193 13package org.eclipse.tracecompass.tmf.core.callstack;
e8251298 14
d0c7e4ba
AM
15import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
16
17import org.eclipse.jdt.annotation.NonNull;
b489a029 18import org.eclipse.osgi.util.NLS;
2bdf0193 19import org.eclipse.tracecompass.internal.tmf.core.Activator;
d0c7e4ba 20import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
e894a508
AM
21import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
22import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
23import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
24import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
25import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
2bdf0193
AM
26import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
27import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider;
28import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
29import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
e8251298
PT
30
31/**
32 * The state provider for traces that support the Call Stack view.
33 *
34 * The attribute tree should have the following structure:
35 *<pre>
36 * (root)
37 * \-- Threads
38 * |-- (Thread 1)
39 * | \-- CallStack (stack-attribute)
40 * | |-- 1
41 * | |-- 2
42 * | ...
43 * | \-- n
44 * |-- (Thread 2)
45 * | \-- CallStack (stack-attribute)
46 * | |-- 1
47 * | |-- 2
48 * | ...
49 * | \-- n
50 * ...
51 * \-- (Thread n)
52 * \-- CallStack (stack-attribute)
53 * |-- 1
54 * |-- 2
55 * ...
56 * \-- n
57 *</pre>
58 * where:
59 * <br>
ac31f2fb
PT
60 * (Thread n) is an attribute whose name is the display name of the thread.
61 * Optionally, its value is a long representing the thread id, used for sorting.
e8251298
PT
62 * <br>
63 * CallStack is a stack-attribute whose pushed values are either a string,
64 * int or long representing the function name or address in the call stack.
65 * The type of value used must be constant for a particular CallStack.
66 *
67 * @author Patrick Tasse
e8251298 68 */
0fe46f2a 69public abstract class CallStackStateProvider extends AbstractTmfStateProvider {
e8251298 70
e8251298
PT
71 /** Thread attribute */
72 public static final String THREADS = "Threads"; //$NON-NLS-1$
73 /** CallStack stack-attribute */
74 public static final String CALL_STACK = "CallStack"; //$NON-NLS-1$
75 /** Undefined function exit name */
76 public static final String UNDEFINED = "UNDEFINED"; //$NON-NLS-1$
77
50659279 78 /** CallStack state system ID */
d0c7e4ba 79 private static final @NonNull String ID = "org.eclipse.linuxtools.tmf.callstack"; //$NON-NLS-1$
b489a029
AM
80 /** Dummy function name for when no function is expected */
81 private static final String NO_FUNCTION = "no function"; //$NON-NLS-1$
82
e8251298
PT
83 /**
84 * Default constructor
85 *
86 * @param trace
87 * The trace for which we build this state system
88 */
d0c7e4ba 89 public CallStackStateProvider(@NonNull ITmfTrace trace) {
e2bcc8a5 90 super(trace, ID);
e8251298
PT
91 }
92
e8251298
PT
93 @Override
94 protected void eventHandle(ITmfEvent event) {
b489a029
AM
95 if (!considerEvent(event)) {
96 return;
97 }
d0c7e4ba
AM
98
99 ITmfStateSystemBuilder ss = checkNotNull(getStateSystemBuilder());
100
e8251298 101 try {
b489a029
AM
102 /* Check if the event is a function entry */
103 String functionEntryName = functionEntry(event);
e8251298
PT
104 if (functionEntryName != null) {
105 long timestamp = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
b489a029 106 String thread = getThreadName(event);
ac31f2fb
PT
107 int threadQuark = ss.getQuarkAbsoluteAndAdd(THREADS, thread);
108 Long threadId = getThreadId(event);
109 if (threadId != null) {
110 ss.updateOngoingState(TmfStateValue.newValueLong(threadId), threadQuark);
111 }
112 int callStackQuark = ss.getQuarkRelativeAndAdd(threadQuark, CALL_STACK);
e8251298 113 ITmfStateValue value = TmfStateValue.newValueString(functionEntryName);
ac31f2fb 114 ss.pushAttribute(timestamp, value, callStackQuark);
b489a029
AM
115 return;
116 }
117
118 /* Check if the event is a function exit */
119 String functionExitName = functionExit(event);
120 if (functionExitName != null) {
e8251298 121 long timestamp = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
b489a029 122 String thread = getThreadName(event);
e8251298 123 int quark = ss.getQuarkAbsoluteAndAdd(THREADS, thread, CALL_STACK);
b489a029
AM
124 ITmfStateValue poppedValue = ss.popAttribute(timestamp, quark);
125 String poppedName = (poppedValue == null ? NO_FUNCTION : poppedValue.unboxStr());
126
127 /*
128 * Verify that the value we are popping matches the one in the
129 * event field, unless the latter is undefined.
130 */
131 if (!functionExitName.equals(UNDEFINED) &&
132 !functionExitName.equals(poppedName)) {
133 Activator.logWarning(NLS.bind(
134 Messages.CallStackStateProvider_UnmatchedPoppedValue,
135 functionExitName,
136 poppedName));
137 }
e8251298 138 }
b489a029 139
e8251298
PT
140 } catch (TimeRangeException e) {
141 e.printStackTrace();
142 } catch (AttributeNotFoundException e) {
143 e.printStackTrace();
144 } catch (StateValueTypeException e) {
145 e.printStackTrace();
146 }
147 }
148
149 /**
b489a029
AM
150 * Check if this event should be considered at all for function entry/exit
151 * analysis. This check is only run once per event, before
152 * {@link #functionEntry} and {@link #functionExit} (to avoid repeating
153 * checks in those methods).
154 *
155 * @param event
156 * The event to check
157 * @return If false, the event will be ignored by the state provider. If
158 * true processing will continue.
e8251298 159 */
b489a029 160 protected abstract boolean considerEvent(ITmfEvent event);
e8251298
PT
161
162 /**
b489a029
AM
163 * Check an event if it indicates a function entry.
164 *
165 * @param event
166 * An event to check for function entry
167 * @return The function name of the function entry, or null if not a
168 * function entry.
169 */
170 protected abstract String functionEntry(ITmfEvent event);
171
172 /**
173 * Check an event if it indicates a function exit.
174 *
175 * @param event
176 * An event to check for function exit
177 * @return The function name, or UNDEFINED, for a function exit, or null if
178 * not a function exit.
e8251298 179 */
b489a029 180 protected abstract String functionExit(ITmfEvent event);
e8251298
PT
181
182 /**
b489a029
AM
183 * Return the thread name of a function entry or exit event.
184 *
185 * @param event
186 * The event
187 * @return The thread name (as will be shown in the view)
e8251298 188 */
b489a029 189 protected abstract String getThreadName(ITmfEvent event);
ac31f2fb
PT
190
191 /**
192 * Return the thread id of a function entry event.
193 *
194 * @param event
195 * The event
196 * @return The thread id, or null if undefined
ac31f2fb
PT
197 */
198 protected Long getThreadId(ITmfEvent event) {
199 return null;
200 }
e8251298 201}
This page took 0.087463 seconds and 5 git commands to generate.