tmf.all: use ITmfTimestamp#toNanos when possible
[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;
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:
34 *<pre>
35 * (root)
36 * \-- Threads
37 * |-- (Thread 1)
38 * | \-- CallStack (stack-attribute)
39 * | |-- 1
40 * | |-- 2
41 * | ...
42 * | \-- n
43 * |-- (Thread 2)
44 * | \-- CallStack (stack-attribute)
45 * | |-- 1
46 * | |-- 2
47 * | ...
48 * | \-- n
49 * ...
50 * \-- (Thread n)
51 * \-- CallStack (stack-attribute)
52 * |-- 1
53 * |-- 2
54 * ...
55 * \-- n
56 *</pre>
57 * where:
58 * <br>
ac31f2fb
PT
59 * (Thread n) is an attribute whose name is the display name of the thread.
60 * Optionally, its value is a long representing the thread id, used for sorting.
e8251298
PT
61 * <br>
62 * CallStack is a stack-attribute whose pushed values are either a string,
63 * int or long representing the function name or address in the call stack.
64 * The type of value used must be constant for a particular CallStack.
65 *
66 * @author Patrick Tasse
e8251298 67 */
0fe46f2a 68public abstract class CallStackStateProvider extends AbstractTmfStateProvider {
e8251298 69
e8251298
PT
70 /** Thread attribute */
71 public static final String THREADS = "Threads"; //$NON-NLS-1$
72 /** CallStack stack-attribute */
73 public static final String CALL_STACK = "CallStack"; //$NON-NLS-1$
74 /** Undefined function exit name */
75 public static final String UNDEFINED = "UNDEFINED"; //$NON-NLS-1$
76
50659279 77 /** CallStack state system ID */
d0c7e4ba 78 private static final @NonNull String ID = "org.eclipse.linuxtools.tmf.callstack"; //$NON-NLS-1$
b489a029
AM
79 /** Dummy function name for when no function is expected */
80 private static final String NO_FUNCTION = "no function"; //$NON-NLS-1$
81
e8251298
PT
82 /**
83 * Default constructor
84 *
85 * @param trace
86 * The trace for which we build this state system
87 */
d0c7e4ba 88 public CallStackStateProvider(@NonNull ITmfTrace trace) {
e2bcc8a5 89 super(trace, ID);
e8251298
PT
90 }
91
e8251298
PT
92 @Override
93 protected void eventHandle(ITmfEvent event) {
b489a029
AM
94 if (!considerEvent(event)) {
95 return;
96 }
d0c7e4ba
AM
97
98 ITmfStateSystemBuilder ss = checkNotNull(getStateSystemBuilder());
99
e8251298 100 try {
b489a029
AM
101 /* Check if the event is a function entry */
102 String functionEntryName = functionEntry(event);
e8251298 103 if (functionEntryName != null) {
16801c72 104 long timestamp = event.getTimestamp().toNanos();
b489a029 105 String thread = getThreadName(event);
ac31f2fb
PT
106 int threadQuark = ss.getQuarkAbsoluteAndAdd(THREADS, thread);
107 Long threadId = getThreadId(event);
108 if (threadId != null) {
109 ss.updateOngoingState(TmfStateValue.newValueLong(threadId), threadQuark);
110 }
111 int callStackQuark = ss.getQuarkRelativeAndAdd(threadQuark, CALL_STACK);
e8251298 112 ITmfStateValue value = TmfStateValue.newValueString(functionEntryName);
ac31f2fb 113 ss.pushAttribute(timestamp, value, callStackQuark);
b489a029
AM
114 return;
115 }
116
117 /* Check if the event is a function exit */
118 String functionExitName = functionExit(event);
119 if (functionExitName != null) {
16801c72 120 long timestamp = event.getTimestamp().toNanos();
b489a029 121 String thread = getThreadName(event);
e8251298 122 int quark = ss.getQuarkAbsoluteAndAdd(THREADS, thread, CALL_STACK);
b489a029
AM
123 ITmfStateValue poppedValue = ss.popAttribute(timestamp, quark);
124 String poppedName = (poppedValue == null ? NO_FUNCTION : poppedValue.unboxStr());
125
126 /*
127 * Verify that the value we are popping matches the one in the
128 * event field, unless the latter is undefined.
129 */
130 if (!functionExitName.equals(UNDEFINED) &&
131 !functionExitName.equals(poppedName)) {
132 Activator.logWarning(NLS.bind(
133 Messages.CallStackStateProvider_UnmatchedPoppedValue,
134 functionExitName,
135 poppedName));
136 }
e8251298 137 }
b489a029 138
e8251298
PT
139 } catch (TimeRangeException e) {
140 e.printStackTrace();
141 } catch (AttributeNotFoundException e) {
142 e.printStackTrace();
143 } catch (StateValueTypeException e) {
144 e.printStackTrace();
145 }
146 }
147
148 /**
b489a029
AM
149 * Check if this event should be considered at all for function entry/exit
150 * analysis. This check is only run once per event, before
151 * {@link #functionEntry} and {@link #functionExit} (to avoid repeating
152 * checks in those methods).
153 *
154 * @param event
155 * The event to check
156 * @return If false, the event will be ignored by the state provider. If
157 * true processing will continue.
e8251298 158 */
b489a029 159 protected abstract boolean considerEvent(ITmfEvent event);
e8251298
PT
160
161 /**
b489a029
AM
162 * Check an event if it indicates a function entry.
163 *
164 * @param event
165 * An event to check for function entry
166 * @return The function name of the function entry, or null if not a
167 * function entry.
168 */
169 protected abstract String functionEntry(ITmfEvent event);
170
171 /**
172 * Check an event if it indicates a function exit.
173 *
174 * @param event
175 * An event to check for function exit
176 * @return The function name, or UNDEFINED, for a function exit, or null if
177 * not a function exit.
e8251298 178 */
b489a029 179 protected abstract String functionExit(ITmfEvent event);
e8251298
PT
180
181 /**
b489a029
AM
182 * Return the thread name of a function entry or exit event.
183 *
184 * @param event
185 * The event
186 * @return The thread name (as will be shown in the view)
e8251298 187 */
b489a029 188 protected abstract String getThreadName(ITmfEvent event);
ac31f2fb
PT
189
190 /**
191 * Return the thread id of a function entry event.
192 *
193 * @param event
194 * The event
195 * @return The thread id, or null if undefined
ac31f2fb
PT
196 */
197 protected Long getThreadId(ITmfEvent event) {
198 return null;
199 }
e8251298 200}
This page took 0.088507 seconds and 5 git commands to generate.