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