btf: fix order of modifiers in BtfEventPropertySource
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / callstack / CallStackStateProvider.java
CommitLineData
e8251298 1/*******************************************************************************
60ae41e1 2 * Copyright (c) 2013, 2014 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
68 * @since 2.0
69 */
0fe46f2a 70public abstract class CallStackStateProvider extends AbstractTmfStateProvider {
e8251298 71
e8251298
PT
72 /** Thread attribute */
73 public static final String THREADS = "Threads"; //$NON-NLS-1$
74 /** CallStack stack-attribute */
75 public static final String CALL_STACK = "CallStack"; //$NON-NLS-1$
76 /** Undefined function exit name */
77 public static final String UNDEFINED = "UNDEFINED"; //$NON-NLS-1$
78
50659279 79 /** CallStack state system ID */
d0c7e4ba 80 private static final @NonNull String ID = "org.eclipse.linuxtools.tmf.callstack"; //$NON-NLS-1$
b489a029
AM
81 /** Dummy function name for when no function is expected */
82 private static final String NO_FUNCTION = "no function"; //$NON-NLS-1$
83
e8251298
PT
84 /**
85 * Default constructor
86 *
87 * @param trace
88 * The trace for which we build this state system
89 */
d0c7e4ba 90 public CallStackStateProvider(@NonNull ITmfTrace trace) {
e8251298
PT
91 super(trace, ITmfEvent.class, ID);
92 }
93
e8251298
PT
94 @Override
95 protected void eventHandle(ITmfEvent event) {
b489a029
AM
96 if (!considerEvent(event)) {
97 return;
98 }
d0c7e4ba
AM
99
100 ITmfStateSystemBuilder ss = checkNotNull(getStateSystemBuilder());
101
e8251298 102 try {
b489a029
AM
103 /* Check if the event is a function entry */
104 String functionEntryName = functionEntry(event);
e8251298
PT
105 if (functionEntryName != null) {
106 long timestamp = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
b489a029 107 String thread = getThreadName(event);
ac31f2fb
PT
108 int threadQuark = ss.getQuarkAbsoluteAndAdd(THREADS, thread);
109 Long threadId = getThreadId(event);
110 if (threadId != null) {
111 ss.updateOngoingState(TmfStateValue.newValueLong(threadId), threadQuark);
112 }
113 int callStackQuark = ss.getQuarkRelativeAndAdd(threadQuark, CALL_STACK);
e8251298 114 ITmfStateValue value = TmfStateValue.newValueString(functionEntryName);
ac31f2fb 115 ss.pushAttribute(timestamp, value, callStackQuark);
b489a029
AM
116 return;
117 }
118
119 /* Check if the event is a function exit */
120 String functionExitName = functionExit(event);
121 if (functionExitName != null) {
e8251298 122 long timestamp = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
b489a029 123 String thread = getThreadName(event);
e8251298 124 int quark = ss.getQuarkAbsoluteAndAdd(THREADS, thread, CALL_STACK);
b489a029
AM
125 ITmfStateValue poppedValue = ss.popAttribute(timestamp, quark);
126 String poppedName = (poppedValue == null ? NO_FUNCTION : poppedValue.unboxStr());
127
128 /*
129 * Verify that the value we are popping matches the one in the
130 * event field, unless the latter is undefined.
131 */
132 if (!functionExitName.equals(UNDEFINED) &&
133 !functionExitName.equals(poppedName)) {
134 Activator.logWarning(NLS.bind(
135 Messages.CallStackStateProvider_UnmatchedPoppedValue,
136 functionExitName,
137 poppedName));
138 }
e8251298 139 }
b489a029 140
e8251298
PT
141 } catch (TimeRangeException e) {
142 e.printStackTrace();
143 } catch (AttributeNotFoundException e) {
144 e.printStackTrace();
145 } catch (StateValueTypeException e) {
146 e.printStackTrace();
147 }
148 }
149
150 /**
b489a029
AM
151 * Check if this event should be considered at all for function entry/exit
152 * analysis. This check is only run once per event, before
153 * {@link #functionEntry} and {@link #functionExit} (to avoid repeating
154 * checks in those methods).
155 *
156 * @param event
157 * The event to check
158 * @return If false, the event will be ignored by the state provider. If
159 * true processing will continue.
c4767854 160 * @since 3.0
e8251298 161 */
b489a029 162 protected abstract boolean considerEvent(ITmfEvent event);
e8251298
PT
163
164 /**
b489a029
AM
165 * Check an event if it indicates a function entry.
166 *
167 * @param event
168 * An event to check for function entry
169 * @return The function name of the function entry, or null if not a
170 * function entry.
171 */
172 protected abstract String functionEntry(ITmfEvent event);
173
174 /**
175 * Check an event if it indicates a function exit.
176 *
177 * @param event
178 * An event to check for function exit
179 * @return The function name, or UNDEFINED, for a function exit, or null if
180 * not a function exit.
e8251298 181 */
b489a029 182 protected abstract String functionExit(ITmfEvent event);
e8251298
PT
183
184 /**
b489a029
AM
185 * Return the thread name of a function entry or exit event.
186 *
187 * @param event
188 * The event
189 * @return The thread name (as will be shown in the view)
c4767854 190 * @since 3.0
e8251298 191 */
b489a029 192 protected abstract String getThreadName(ITmfEvent event);
ac31f2fb
PT
193
194 /**
195 * Return the thread id of a function entry event.
196 *
197 * @param event
198 * The event
199 * @return The thread id, or null if undefined
200 * @since 3.1
201 */
202 protected Long getThreadId(ITmfEvent event) {
203 return null;
204 }
e8251298 205}
This page took 0.072756 seconds and 5 git commands to generate.