Merge branch 'master' into lttng-luna
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / callstack / CallStackStateProvider.java
1 /*******************************************************************************
2 * Copyright (c) 2013 Ericsson
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
13 package org.eclipse.linuxtools.tmf.core.callstack;
14
15 import org.eclipse.linuxtools.internal.tmf.core.Activator;
16 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
17 import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
18 import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
19 import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
20 import org.eclipse.linuxtools.tmf.core.statesystem.AbstractTmfStateProvider;
21 import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
22 import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue;
23 import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
24 import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
25 import org.eclipse.osgi.util.NLS;
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>
56 * (Thread n) is an attribute whose name is the name of the thread
57 * <br>
58 * CallStack is a stack-attribute whose pushed values are either a string,
59 * int or long representing the function name or address in the call stack.
60 * The type of value used must be constant for a particular CallStack.
61 *
62 * @author Patrick Tasse
63 * @since 2.0
64 */
65 public abstract class CallStackStateProvider extends AbstractTmfStateProvider {
66
67 /** CallStack state system ID */
68 public static final String ID = "org.eclipse.linuxtools.tmf.callstack"; //$NON-NLS-1$
69 /** Thread attribute */
70 public static final String THREADS = "Threads"; //$NON-NLS-1$
71 /** CallStack stack-attribute */
72 public static final String CALL_STACK = "CallStack"; //$NON-NLS-1$
73 /** Undefined function exit name */
74 public static final String UNDEFINED = "UNDEFINED"; //$NON-NLS-1$
75
76 /** Dummy function name for when no function is expected */
77 private static final String NO_FUNCTION = "no function"; //$NON-NLS-1$
78
79 /**
80 * Version number of this state provider. Please bump this if you modify
81 * the contents of the generated state history in some way.
82 */
83 private static final int VERSION = 0;
84
85 /**
86 * Default constructor
87 *
88 * @param trace
89 * The trace for which we build this state system
90 */
91 public CallStackStateProvider(ITmfTrace trace) {
92 super(trace, ITmfEvent.class, ID);
93 }
94
95 @Override
96 public int getVersion() {
97 return VERSION;
98 }
99
100 @Override
101 protected void eventHandle(ITmfEvent event) {
102 if (!considerEvent(event)) {
103 return;
104 }
105 try {
106 /* Check if the event is a function entry */
107 String functionEntryName = functionEntry(event);
108 if (functionEntryName != null) {
109 long timestamp = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
110 String thread = getThreadName(event);
111 int quark = ss.getQuarkAbsoluteAndAdd(THREADS, thread, CALL_STACK);
112 ITmfStateValue value = TmfStateValue.newValueString(functionEntryName);
113 ss.pushAttribute(timestamp, value, quark);
114 return;
115 }
116
117 /* Check if the event is a function exit */
118 String functionExitName = functionExit(event);
119 if (functionExitName != null) {
120 long timestamp = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
121 String thread = getThreadName(event);
122 int quark = ss.getQuarkAbsoluteAndAdd(THREADS, thread, CALL_STACK);
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 }
137 }
138
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 /**
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.
158 */
159 protected abstract boolean considerEvent(ITmfEvent event);
160
161 /**
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.
178 */
179 protected abstract String functionExit(ITmfEvent event);
180
181 /**
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)
187 */
188 protected abstract String getThreadName(ITmfEvent event);
189 }
This page took 0.035918 seconds and 6 git commands to generate.