tmf: make CallstackProvider entry and exit return TmfStates
[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
7f86b721
AM
17import org.eclipse.jdt.annotation.NonNullByDefault;
18import org.eclipse.jdt.annotation.Nullable;
b489a029 19import org.eclipse.osgi.util.NLS;
2bdf0193 20import org.eclipse.tracecompass.internal.tmf.core.Activator;
d0c7e4ba 21import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
e894a508 22import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
e894a508
AM
23import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
24import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
2bdf0193
AM
25import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
26import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider;
7f86b721 27import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
2bdf0193 28import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
e8251298
PT
29
30/**
31 * The state provider for traces that support the Call Stack view.
32 *
33 * The attribute tree should have the following structure:
7f86b721
AM
34 *
35 * <pre>
e8251298 36 * (root)
7f86b721
AM
37 * +-- Processes
38 * +-- (PID 1000)
39 * | +-- (TID 1000)
40 * | | +-- CallStack (stack-attribute)
41 * | | +-- 1
42 * | | +-- 2
43 * | | ...
44 * | | +-- n
45 * | +-- (TID 1001)
46 * | +-- CallStack (stack-attribute)
47 * | +-- 1
48 * | +-- 2
49 * | ...
50 * | +-- n
51 * |
52 * +-- (PID 2000)
53 * +-- (TID 2000)
54 * +-- CallStack (stack-attribute)
55 * +-- 1
56 * +-- 2
57 * ...
58 * +-- n
59 * </pre>
60 *
e8251298 61 * where:
7f86b721
AM
62 * <ul>
63 * <li>(PID n) is an attribute name representing a unique process identifier.
64 * </li>
65 * <li>(TID n) is an attribute whose name is the display name of the thread.
ac31f2fb 66 * Optionally, its value is a long representing the thread id, used for sorting.
7f86b721
AM
67 * </li>
68 * <li>"CallStack" is a stack-attribute whose pushed values are either a string,
69 * int or long representing the function name or address in the call stack. The
70 * type of value used must be constant for a particular CallStack.</li>
71 * </ul>
e8251298
PT
72 *
73 * @author Patrick Tasse
e8251298 74 */
7f86b721 75@NonNullByDefault
0fe46f2a 76public abstract class CallStackStateProvider extends AbstractTmfStateProvider {
e8251298 77
c3777c23
MK
78 /**
79 * Thread attribute
80 *
81 * @since 2.0
82 */
7f86b721
AM
83 public static final String PROCESSES = "Processes"; //$NON-NLS-1$
84
e8251298
PT
85 /** CallStack stack-attribute */
86 public static final String CALL_STACK = "CallStack"; //$NON-NLS-1$
7f86b721 87
c3777c23
MK
88 /**
89 * Undefined process ID
90 *
91 * @since 2.0
92 */
7f86b721
AM
93 protected static final int UNDEFINED_PID = -1;
94
e8251298 95 /** Undefined function exit name */
7f86b721 96 protected static final String UNDEFINED = "UNDEFINED"; //$NON-NLS-1$
e8251298 97
50659279 98 /** CallStack state system ID */
7f86b721
AM
99 private static final String ID = "org.eclipse.linuxtools.tmf.callstack"; //$NON-NLS-1$
100
e8251298
PT
101 /**
102 * Default constructor
103 *
104 * @param trace
105 * The trace for which we build this state system
106 */
7f86b721 107 public CallStackStateProvider(ITmfTrace trace) {
e2bcc8a5 108 super(trace, ID);
e8251298
PT
109 }
110
e8251298
PT
111 @Override
112 protected void eventHandle(ITmfEvent event) {
b489a029
AM
113 if (!considerEvent(event)) {
114 return;
115 }
d0c7e4ba
AM
116
117 ITmfStateSystemBuilder ss = checkNotNull(getStateSystemBuilder());
118
e8251298 119 try {
b489a029 120 /* Check if the event is a function entry */
c3777c23 121 ITmfStateValue functionEntryName = functionEntry(event);
e8251298 122 if (functionEntryName != null) {
16801c72 123 long timestamp = event.getTimestamp().toNanos();
7f86b721
AM
124 int pid = getProcessId(event);
125 String threadName = getThreadName(event);
126 int threadQuark = ss.getQuarkAbsoluteAndAdd(PROCESSES, Integer.toString(pid), threadName);
127
128 long threadId = getThreadId(event);
129 ss.updateOngoingState(TmfStateValue.newValueLong(threadId), threadQuark);
130
ac31f2fb 131 int callStackQuark = ss.getQuarkRelativeAndAdd(threadQuark, CALL_STACK);
c3777c23 132 ITmfStateValue value = functionEntryName;
ac31f2fb 133 ss.pushAttribute(timestamp, value, callStackQuark);
b489a029
AM
134 return;
135 }
136
137 /* Check if the event is a function exit */
c3777c23
MK
138 ITmfStateValue functionExitState = functionExit(event);
139 if (functionExitState != null) {
16801c72 140 long timestamp = event.getTimestamp().toNanos();
7f86b721 141 int pid = getProcessId(event);
b489a029 142 String thread = getThreadName(event);
7f86b721 143 int quark = ss.getQuarkAbsoluteAndAdd(PROCESSES, Integer.toString(pid), thread, CALL_STACK);
b489a029 144 ITmfStateValue poppedValue = ss.popAttribute(timestamp, quark);
b489a029
AM
145 /*
146 * Verify that the value we are popping matches the one in the
147 * event field, unless the latter is undefined.
148 */
c3777c23 149 if (!functionExitState.isNull() && !functionExitState.equals(poppedValue)) {
b489a029
AM
150 Activator.logWarning(NLS.bind(
151 Messages.CallStackStateProvider_UnmatchedPoppedValue,
c3777c23
MK
152 functionExitState,
153 poppedValue));
b489a029 154 }
e8251298 155 }
b489a029 156
e8251298
PT
157 } catch (AttributeNotFoundException e) {
158 e.printStackTrace();
e8251298
PT
159 }
160 }
161
7f86b721
AM
162 /**
163 * Restrict the return type for {@link ITmfStateProvider#getNewInstance}.
164 *
165 * @since 2.0
166 */
167 @Override
168 public abstract CallStackStateProvider getNewInstance();
169
e8251298 170 /**
b489a029
AM
171 * Check if this event should be considered at all for function entry/exit
172 * analysis. This check is only run once per event, before
173 * {@link #functionEntry} and {@link #functionExit} (to avoid repeating
174 * checks in those methods).
175 *
176 * @param event
177 * The event to check
178 * @return If false, the event will be ignored by the state provider. If
179 * true processing will continue.
e8251298 180 */
b489a029 181 protected abstract boolean considerEvent(ITmfEvent event);
e8251298
PT
182
183 /**
b489a029
AM
184 * Check an event if it indicates a function entry.
185 *
186 * @param event
187 * An event to check for function entry
c3777c23
MK
188 * @return The state value representing the function being entered, or null
189 * if not a function entry
190 * @since 2.0
b489a029 191 */
c3777c23 192 protected abstract @Nullable ITmfStateValue functionEntry(ITmfEvent event);
b489a029
AM
193
194 /**
195 * Check an event if it indicates a function exit.
196 *
197 * @param event
198 * An event to check for function exit
c3777c23
MK
199 * @return The state value representing the function being exited, or
200 * TmfStateValue#nullValue() if the exited function is undefined,
201 * or null if not a function exit.
202 * @since 2.0
e8251298 203 */
c3777c23 204 protected abstract @Nullable ITmfStateValue functionExit(ITmfEvent event);
e8251298
PT
205
206 /**
7f86b721
AM
207 * Return the process ID of a function entry event.
208 *
209 * Use {@link #UNDEFINED_PID} if it is not known.
b489a029
AM
210 *
211 * @param event
212 * The event
7f86b721
AM
213 * @return The process ID
214 * @since 2.0
e8251298 215 */
7f86b721 216 protected abstract int getProcessId(ITmfEvent event);
ac31f2fb
PT
217
218 /**
219 * Return the thread id of a function entry event.
220 *
221 * @param event
222 * The event
7f86b721
AM
223 * @return The thread id
224 * @since 2.0
ac31f2fb 225 */
7f86b721
AM
226 protected abstract long getThreadId(ITmfEvent event);
227
228 /**
229 * Return the thread name of a function entry or exit event.
230 *
231 * @param event
232 * The event
233 * @return The thread name (as will be shown in the view)
234 */
235 protected abstract String getThreadName(ITmfEvent event);
e8251298 236}
This page took 0.086346 seconds and 5 git commands to generate.