*/
protected abstract @NonNull CtfTestTrace getTestTrace();
+ /**
+ * @return The ID of the process the desired thread belongs to
+ */
+ protected abstract int getProcessId();
+
/**
* @return The name of the executable process in that particular trace
*/
- protected abstract String getProcName();
+ protected abstract String getThreadName();
/**
* Get the list of timestamps to query in that trace.
@Test
public void testCallStackBegin() {
long start = fSS.getStartTime();
- String[] cs = getCallStack(fSS, getProcName(), start);
+ String[] cs = getCallStack(fSS, getProcessId(), getThreadName(), start);
assertEquals(1, cs.length);
assertEquals("40472b", cs[0]);
*/
@Test
public void testCallStack1() {
- String[] cs = getCallStack(fSS, getProcName(), getTestTimestamp(0));
+ String[] cs = getCallStack(fSS, getProcessId(), getThreadName(), getTestTimestamp(0));
assertEquals(2, cs.length);
assertEquals("40472b", cs[0]);
*/
@Test
public void testCallStack2() {
- String[] cs = getCallStack(fSS, getProcName(), getTestTimestamp(1));
+ String[] cs = getCallStack(fSS, getProcessId(), getThreadName(), getTestTimestamp(1));
assertEquals(3, cs.length);
assertEquals("40472b", cs[0]);
*/
@Test
public void testCallStack3() {
- String[] cs = getCallStack(fSS, getProcName(), getTestTimestamp(2));
+ String[] cs = getCallStack(fSS, getProcessId(), getThreadName(), getTestTimestamp(2));
assertEquals(4, cs.length);
assertEquals("40472b", cs[0]);
@Test
public void testCallStackEnd() {
long end = fSS.getCurrentEndTime();
- String[] cs = getCallStack(fSS, getProcName(), end);
+ String[] cs = getCallStack(fSS, getProcessId(), getThreadName(), end);
assertEquals(3, cs.length);
assertEquals("40472b", cs[0]);
}
/** Get the callstack for the given timestamp, for this particular trace */
- private static String[] getCallStack(ITmfStateSystem ss, String processName, long timestamp) {
+ private static String[] getCallStack(ITmfStateSystem ss, int pid, String threadName, long timestamp) {
try {
- int stackAttribute = ss.getQuarkAbsolute("Threads", processName, "CallStack");
+ int stackAttribute = ss.getQuarkAbsolute("Processes", Integer.toString(pid), threadName, "CallStack");
List<ITmfStateInterval> state = ss.queryFullState(timestamp);
int depth = state.get(stackAttribute).getStateValue().unboxInt();
}
@Override
- protected String getProcName() {
+ protected int getProcessId() {
+ /* This particular trace does not have PID contexts. */
+ return -1;
+ }
+
+ @Override
+ protected String getThreadName() {
return "glxgears-29822";
}
}
@Override
- protected String getProcName() {
+ protected int getProcessId() {
+ /* This particular trace does not have PID contexts. */
+ return -1;
+ }
+
+ @Override
+ protected String getThreadName() {
return "glxgears-16073";
}
import java.util.Set;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.internal.lttng2.ust.core.trace.layout.LttngUst20EventLayout;
import org.eclipse.tracecompass.lttng2.ust.core.trace.LttngUstTrace;
import org.eclipse.tracecompass.lttng2.ust.core.trace.layout.ILttngUstEventLayout;
*
* @author Alexandre Montplaisir
*/
+@NonNullByDefault
public class LttngUstCallStackProvider extends CallStackStateProvider {
/**
* Version number of this state provider. Please bump this if you modify
* the contents of the generated state history in some way.
*/
- private static final int VERSION = 2;
+ private static final int VERSION = 3;
/** Event names indicating function entry */
- private final @NonNull Set<String> funcEntryEvents;
+ private final Set<String> funcEntryEvents;
/** Event names indicating function exit */
- private final @NonNull Set<String> funcExitEvents;
+ private final Set<String> funcExitEvents;
- private final @NonNull ILttngUstEventLayout fLayout;
+ private final ILttngUstEventLayout fLayout;
// ------------------------------------------------------------------------
// Constructor
* @param trace
* The UST trace
*/
- public LttngUstCallStackProvider(@NonNull ITmfTrace trace) {
+ public LttngUstCallStackProvider(ITmfTrace trace) {
super(trace);
if (trace instanceof LttngUstTrace) {
* Check that this event contains the required information we need to be
* used in the call stack view. We need at least the "procname" and "vtid"
* contexts.
+ *
+ * The "vpid" is useful too, but optional.
*/
@Override
protected boolean considerEvent(ITmfEvent event) {
}
@Override
- public String functionEntry(ITmfEvent event) {
+ public @Nullable String functionEntry(ITmfEvent event) {
String eventName = event.getName();
if (!funcEntryEvents.contains(eventName)) {
return null;
}
@Override
- public String functionExit(ITmfEvent event) {
+ public @Nullable String functionExit(ITmfEvent event) {
String eventName = event.getName();
if (!funcExitEvents.contains(eventName)) {
return null;
}
@Override
- public String getThreadName(ITmfEvent event) {
- /* Class type and content was already checked if we get called here */
- ITmfEventField content = ((CtfTmfEvent) event).getContent();
- String procName = (String) content.getField(fLayout.contextProcname()).getValue();
- Long vtid = (Long) content.getField(fLayout.contextVtid()).getValue();
-
- if (procName == null || vtid == null) {
- throw new IllegalStateException();
+ protected int getProcessId(@NonNull ITmfEvent event) {
+ /* The "vpid" context may not be present! We need to check */
+ ITmfEventField content = event.getContent();
+ ITmfEventField vpidContextField = content.getField(fLayout.contextVpid());
+ if (vpidContextField == null) {
+ return UNDEFINED_PID;
}
+ return ((Long) vpidContextField.getValue()).intValue();
+ }
- return procName + '-' + vtid.toString();
+ @Override
+ protected long getThreadId(ITmfEvent event) {
+ /* We checked earlier that the "vtid" context is present */
+ ITmfEventField content = event.getContent();
+ return ((Long) content.getField(fLayout.contextVtid()).getValue()).longValue();
}
@Override
- protected Long getThreadId(ITmfEvent event) {
- ITmfEventField content = ((CtfTmfEvent) event).getContent();
- return (Long) content.getField(fLayout.contextVtid()).getValue();
+ public String getThreadName(ITmfEvent event) {
+ /* We checked earlier that the "procname" context is present */
+ ITmfEventField content = event.getContent();
+ String procName = (String) content.getField(fLayout.contextProcname()).getValue();
+ long vtid = getThreadId(event);
+ return (procName + '-' + Long.toString(vtid));
}
}
import java.io.File;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import java.util.stream.Collectors;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Logger;
@Test
public void testOpenCallstack() {
String node = "glxgears-cyg-profile";
+ String pid = "-1";
String childName = "glxgears-16073";
List<String> expected = ImmutableList.of("40472b", "", "", "", "");
viewBot.setFocus();
final SWTBotView viewBot1 = viewBot;
SWTBotTree tree = viewBot1.bot().tree();
- SWTBotTreeItem treeItem = tree.getTreeItem(node);
+ SWTBotTreeItem treeItem = tree.getTreeItem(node).getNode(pid);
assertEquals(childName, treeItem.getNodes().get(0));
List<String> names = treeItem.getNode(childName).getNodes();
assertEquals(expected, names);
private static List<String> getVisibleStackFrames(final SWTBotView viewBot) {
SWTBotTree tree = viewBot.bot().tree();
- List<String> names = new ArrayList<>();
- for (SWTBotTreeItem swtBotTreeItem : tree.getAllItems()) {
- for (SWTBotTreeItem items : swtBotTreeItem.getItems()) {
- for (SWTBotTreeItem item : items.getItems()) {
- names.add(item.cell(0));
- }
- }
- }
- return names;
+ return Arrays.stream(tree.getAllItems())
+ // Process entries
+ .flatMap(item -> Arrays.stream(item.getItems()))
+ // Thread entries
+ .flatMap(item -> Arrays.stream(item.getItems()))
+ // Callstack entries
+ .flatMap(item -> Arrays.stream(item.getItems()))
+ .map(item -> item.cell(0))
+ .collect(Collectors.toList());
}
private static void goToTime(long timestamp) {
import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
-import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.osgi.util.NLS;
import org.eclipse.tracecompass.internal.tmf.core.Activator;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider;
+import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
/**
* The state provider for traces that support the Call Stack view.
*
* The attribute tree should have the following structure:
- *<pre>
+ *
+ * <pre>
* (root)
- * \-- Threads
- * |-- (Thread 1)
- * | \-- CallStack (stack-attribute)
- * | |-- 1
- * | |-- 2
- * | ...
- * | \-- n
- * |-- (Thread 2)
- * | \-- CallStack (stack-attribute)
- * | |-- 1
- * | |-- 2
- * | ...
- * | \-- n
- * ...
- * \-- (Thread n)
- * \-- CallStack (stack-attribute)
- * |-- 1
- * |-- 2
- * ...
- * \-- n
- *</pre>
+ * +-- Processes
+ * +-- (PID 1000)
+ * | +-- (TID 1000)
+ * | | +-- CallStack (stack-attribute)
+ * | | +-- 1
+ * | | +-- 2
+ * | | ...
+ * | | +-- n
+ * | +-- (TID 1001)
+ * | +-- CallStack (stack-attribute)
+ * | +-- 1
+ * | +-- 2
+ * | ...
+ * | +-- n
+ * |
+ * +-- (PID 2000)
+ * +-- (TID 2000)
+ * +-- CallStack (stack-attribute)
+ * +-- 1
+ * +-- 2
+ * ...
+ * +-- n
+ * </pre>
+ *
* where:
- * <br>
- * (Thread n) is an attribute whose name is the display name of the thread.
+ * <ul>
+ * <li>(PID n) is an attribute name representing a unique process identifier.
+ * </li>
+ * <li>(TID n) is an attribute whose name is the display name of the thread.
* Optionally, its value is a long representing the thread id, used for sorting.
- * <br>
- * CallStack is a stack-attribute whose pushed values are either a string,
- * int or long representing the function name or address in the call stack.
- * The type of value used must be constant for a particular CallStack.
+ * </li>
+ * <li>"CallStack" is a stack-attribute whose pushed values are either a string,
+ * int or long representing the function name or address in the call stack. The
+ * type of value used must be constant for a particular CallStack.</li>
+ * </ul>
*
* @author Patrick Tasse
*/
+@NonNullByDefault
public abstract class CallStackStateProvider extends AbstractTmfStateProvider {
- /** Thread attribute */
- public static final String THREADS = "Threads"; //$NON-NLS-1$
+ /** Thread attribute
+ * @since 2.0 */
+ public static final String PROCESSES = "Processes"; //$NON-NLS-1$
+
/** CallStack stack-attribute */
public static final String CALL_STACK = "CallStack"; //$NON-NLS-1$
+
+ /** Undefined process ID
+ * @since 2.0 */
+ protected static final int UNDEFINED_PID = -1;
+
/** Undefined function exit name */
- public static final String UNDEFINED = "UNDEFINED"; //$NON-NLS-1$
+ protected static final String UNDEFINED = "UNDEFINED"; //$NON-NLS-1$
/** CallStack state system ID */
- private static final @NonNull String ID = "org.eclipse.linuxtools.tmf.callstack"; //$NON-NLS-1$
+ private static final String ID = "org.eclipse.linuxtools.tmf.callstack"; //$NON-NLS-1$
+
/** Dummy function name for when no function is expected */
private static final String NO_FUNCTION = "no function"; //$NON-NLS-1$
* @param trace
* The trace for which we build this state system
*/
- public CallStackStateProvider(@NonNull ITmfTrace trace) {
+ public CallStackStateProvider(ITmfTrace trace) {
super(trace, ID);
}
String functionEntryName = functionEntry(event);
if (functionEntryName != null) {
long timestamp = event.getTimestamp().toNanos();
- String thread = getThreadName(event);
- int threadQuark = ss.getQuarkAbsoluteAndAdd(THREADS, thread);
- Long threadId = getThreadId(event);
- if (threadId != null) {
- ss.updateOngoingState(TmfStateValue.newValueLong(threadId), threadQuark);
- }
+ int pid = getProcessId(event);
+ String threadName = getThreadName(event);
+ int threadQuark = ss.getQuarkAbsoluteAndAdd(PROCESSES, Integer.toString(pid), threadName);
+
+ long threadId = getThreadId(event);
+ ss.updateOngoingState(TmfStateValue.newValueLong(threadId), threadQuark);
+
int callStackQuark = ss.getQuarkRelativeAndAdd(threadQuark, CALL_STACK);
ITmfStateValue value = TmfStateValue.newValueString(functionEntryName);
ss.pushAttribute(timestamp, value, callStackQuark);
String functionExitName = functionExit(event);
if (functionExitName != null) {
long timestamp = event.getTimestamp().toNanos();
+ int pid = getProcessId(event);
String thread = getThreadName(event);
- int quark = ss.getQuarkAbsoluteAndAdd(THREADS, thread, CALL_STACK);
+ int quark = ss.getQuarkAbsoluteAndAdd(PROCESSES, Integer.toString(pid), thread, CALL_STACK);
ITmfStateValue poppedValue = ss.popAttribute(timestamp, quark);
String poppedName = (poppedValue == null ? NO_FUNCTION : poppedValue.unboxStr());
}
}
- } catch (TimeRangeException e) {
- e.printStackTrace();
} catch (AttributeNotFoundException e) {
e.printStackTrace();
- } catch (StateValueTypeException e) {
- e.printStackTrace();
}
}
+ /**
+ * Restrict the return type for {@link ITmfStateProvider#getNewInstance}.
+ *
+ * @since 2.0
+ */
+ @Override
+ public abstract CallStackStateProvider getNewInstance();
+
/**
* Check if this event should be considered at all for function entry/exit
* analysis. This check is only run once per event, before
* @return The function name of the function entry, or null if not a
* function entry.
*/
- protected abstract String functionEntry(ITmfEvent event);
+ protected abstract @Nullable String functionEntry(ITmfEvent event);
/**
* Check an event if it indicates a function exit.
* @return The function name, or UNDEFINED, for a function exit, or null if
* not a function exit.
*/
- protected abstract String functionExit(ITmfEvent event);
+ protected abstract @Nullable String functionExit(ITmfEvent event);
/**
- * Return the thread name of a function entry or exit event.
+ * Return the process ID of a function entry event.
+ *
+ * Use {@link #UNDEFINED_PID} if it is not known.
*
* @param event
* The event
- * @return The thread name (as will be shown in the view)
+ * @return The process ID
+ * @since 2.0
*/
- protected abstract String getThreadName(ITmfEvent event);
+ protected abstract int getProcessId(ITmfEvent event);
/**
* Return the thread id of a function entry event.
*
* @param event
* The event
- * @return The thread id, or null if undefined
+ * @return The thread id
+ * @since 2.0
*/
- protected Long getThreadId(ITmfEvent event) {
- return null;
- }
+ protected abstract long getThreadId(ITmfEvent event);
+
+ /**
+ * Return the thread name of a function entry or exit event.
+ *
+ * @param event
+ * The event
+ * @return The thread name (as will be shown in the view)
+ */
+ protected abstract String getThreadName(ITmfEvent event);
}
package org.eclipse.tracecompass.tmf.ui.views.callstack;
+import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.tracecompass.tmf.core.callstack.CallStackStateProvider;
import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
import org.eclipse.tracecompass.tmf.ui.analysis.TmfAnalysisViewOutput;
*
* @author Alexandre Montplaisir
*/
+@NonNullByDefault
public abstract class AbstractCallStackAnalysis extends TmfStateSystemAnalysisModule {
- private static final String[] DEFAULT_THREADS_PATTERN =
- new String[] { CallStackStateProvider.THREADS, "*" }; //$NON-NLS-1$;
+ private static final String[] DEFAULT_PROCESSES_PATTERN =
+ new String[] { CallStackStateProvider.PROCESSES, "*" }; //$NON-NLS-1$
+
+ private static final String DEFAULT_THREADS_PATTERN = ".*"; //$NON-NLS-1$
private static final String[] DEFAULT_CALL_STACK_PATH =
new String[] { CallStackStateProvider.CALL_STACK };
* Abstract constructor (should only be called via the sub-classes'
* constructors.
*/
- public AbstractCallStackAnalysis() {
+ protected AbstractCallStackAnalysis() {
super();
registerOutput(new TmfAnalysisViewOutput(CallStackView.ID));
}
/**
- * Get the pattern of thread attributes. Override this method if the state
- * system attributes do not match the default pattern defined by
- * {@link CallStackStateProvider}.
+ * The quark pattern to get the list of attributes representing the
+ * different processes.
+ *
+ * It is passed as-is to
+ * {@link org.eclipse.tracecompass.statesystem.core.ITmfStateSystem#getQuarks}
+ * .
+ * @return The quark pattern to find the processes attribute
+ * @since 2.0
+ */
+ public String[] getProcessesPattern() {
+ return DEFAULT_PROCESSES_PATTERN;
+ }
+
+ /**
+ * The regex to match sub-attributes of each Process attributes representing
+ * the threads of this process.
*
- * @return the absolute pattern of the thread attributes
+ * This will be passed as-is to
+ * {@link org.eclipse.tracecompass.statesystem.core.ITmfStateSystem#getSubAttributes(int, boolean, String)}
+ *
+ * @return The regex to pass
+ * @since 2.0
*/
- public String[] getThreadsPattern() {
+ public String getThreadsForProcessPattern() {
return DEFAULT_THREADS_PATTERN;
}
/**
* Get the call stack attribute path relative to a thread attribute found by
- * {@link #getThreadsPattern()}. Override this method if the state system
- * attributes do not match the default pattern defined by
+ * {@link #getThreadsForProcessPattern()}. Override this method if the state
+ * system attributes do not match the default pattern defined by
* {@link CallStackStateProvider}.
*
* @return the relative path of the call stack attribute
+ * @since 2.0
*/
- public String[] getCallStackPath() {
+ public String[] getCallStackPathForThread() {
return DEFAULT_CALL_STACK_PATH;
}
}
}
}
+ private static class ProcessEntry extends TimeGraphEntry {
+
+ public ProcessEntry(String name, long startTime, long endTime) {
+ super(name, startTime, endTime);
+ }
+
+ @Override
+ public boolean hasTimeEvents() {
+ return false;
+ }
+ }
+
private static class ThreadEntry extends TimeGraphEntry {
// The call stack quark
private final int fCallStackQuark;
}
synchingToTime(beginTime);
startZoomThread(getTimeGraphViewer().getTime0(), getTimeGraphViewer().getTime1());
- List<TimeGraphEntry> entryList = getEntryList(getTrace());
- if (entryList == null) {
+ List<TimeGraphEntry> traceEntries = getEntryList(getTrace());
+ if (traceEntries == null) {
return;
}
TimeGraphViewer viewer = getTimeGraphViewer();
- for (TimeGraphEntry traceEntry : entryList) {
- for (ITimeGraphEntry child : traceEntry.getChildren()) {
- ThreadEntry threadEntry = (ThreadEntry) child;
- ITmfStateSystem ss = threadEntry.getStateSystem();
- if (ss == null || beginTime < ss.getStartTime() || beginTime > ss.getCurrentEndTime()) {
- continue;
- }
- try {
- int quark = threadEntry.getCallStackQuark();
- ITmfStateInterval stackInterval = ss.querySingleState(beginTime, quark);
- if (beginTime == stackInterval.getStartTime()) {
- int stackLevel = stackInterval.getStateValue().unboxInt();
- ITimeGraphEntry selectedEntry = threadEntry.getChildren().get(Math.max(0, stackLevel - 1));
- getTimeGraphCombo().setSelection(selectedEntry);
- viewer.getTimeGraphControl().fireSelectionChanged();
- break;
+ for (TimeGraphEntry traceEntry : traceEntries) {
+ for (ITimeGraphEntry processEntry : traceEntry.getChildren()) {
+ for (ITimeGraphEntry aThreadEntry : processEntry.getChildren()) {
+ ThreadEntry threadEntry = (ThreadEntry) aThreadEntry;
+ ITmfStateSystem ss = threadEntry.getStateSystem();
+ if (ss == null || beginTime < ss.getStartTime() || beginTime > ss.getCurrentEndTime()) {
+ continue;
+ }
+ try {
+ int quark = threadEntry.getCallStackQuark();
+ ITmfStateInterval stackInterval = ss.querySingleState(beginTime, quark);
+ if (beginTime == stackInterval.getStartTime()) {
+ int stackLevel = stackInterval.getStateValue().unboxInt();
+ ITimeGraphEntry selectedEntry = threadEntry.getChildren().get(Math.max(0, stackLevel - 1));
+ getTimeGraphCombo().setSelection(selectedEntry);
+ viewer.getTimeGraphControl().fireSelectionChanged();
+ break;
+ }
+ } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException | StateValueTypeException e) {
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
}
- } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException | StateValueTypeException e) {
- Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
}
}
}
}
});
+
}
/**
}
Map<ITmfTrace, TraceEntry> traceEntryMap = new HashMap<>();
+ Map<Integer, ProcessEntry> processEntryMap = new HashMap<>();
Map<Integer, ThreadEntry> threadEntryMap = new HashMap<>();
- String[] threadPaths = module.getThreadsPattern();
long start = ss.getStartTime();
getConfigureSymbolsAction().setEnabled(true);
- List<Integer> threadQuarks = ss.getQuarks(threadPaths);
+
TraceEntry traceEntry = traceEntryMap.get(trace);
if (traceEntry == null) {
traceEntry = new TraceEntry(trace.getName(), start, end + 1);
traceEntry.updateEndTime(end);
}
- try {
- /* Only query startStates if necessary (threadEntry == null)*/
- List<ITmfStateInterval> startStates = null;
- List<ITmfStateInterval> endStates = ss.queryFullState(ss.getCurrentEndTime());
- for (int i = 0; i < threadQuarks.size(); i++) {
- if (monitor.isCanceled()) {
- return;
- }
- int threadQuark = threadQuarks.get(i);
- String[] callStackPath = module.getCallStackPath();
- int callStackQuark = ss.getQuarkRelative(threadQuark, callStackPath);
- String threadName = ss.getAttributeName(threadQuark);
- long threadEnd = end + 1;
- ITmfStateInterval endInterval = endStates.get(callStackQuark);
- if (endInterval.getStateValue().isNull() && endInterval.getStartTime() != ss.getStartTime()) {
- threadEnd = endInterval.getStartTime();
- }
- ThreadEntry threadEntry = threadEntryMap.get(threadQuark);
- if (threadEntry == null) {
- if (startStates == null) {
- startStates = ss.queryFullState(ss.getStartTime());
+ List<Integer> processQuarks = ss.getQuarks(module.getProcessesPattern());
+ for (Integer processQuark : processQuarks) {
+
+ /* Create the entry for the process */
+ ProcessEntry processEntry = processEntryMap.get(processQuark);
+ if (processEntry == null) {
+ String name = ss.getAttributeName(processQuark.intValue());
+ processEntry = new ProcessEntry(name, start, end);
+ processEntryMap.put(processQuark, processEntry);
+ traceEntry.addChild(processEntry);
+ } else {
+ processEntry.updateEndTime(end);
+ }
+
+ /* Create the threads under the process */
+ try {
+ List<Integer> threadQuarks = ss.getSubAttributes(processQuark, false, module.getThreadsForProcessPattern());
+
+ /*
+ * Only query startStates if necessary (threadEntry == null)
+ */
+ List<ITmfStateInterval> startStates = null;
+ List<ITmfStateInterval> endStates = ss.queryFullState(ss.getCurrentEndTime());
+ for (int i = 0; i < threadQuarks.size(); i++) {
+ if (monitor.isCanceled()) {
+ return;
}
- long threadId = endInterval.getStateValue().unboxLong();
- long threadStart = start;
- ITmfStateInterval startInterval = startStates.get(callStackQuark);
- if (startInterval.getStateValue().isNull()) {
- threadStart = Math.min(startInterval.getEndTime() + 1, end + 1);
+ int threadQuark = threadQuarks.get(i);
+
+ String[] callStackPath = module.getCallStackPathForThread();
+ int callStackQuark = ss.getQuarkRelative(threadQuark, callStackPath);
+ String threadName = ss.getAttributeName(threadQuark);
+ long threadEnd = end + 1;
+ ITmfStateInterval endInterval = endStates.get(callStackQuark);
+ if (endInterval.getStateValue().isNull() && endInterval.getStartTime() != ss.getStartTime()) {
+ threadEnd = endInterval.getStartTime();
}
- threadEntry = new ThreadEntry(ss, threadName, threadId, callStackQuark, threadStart, threadEnd);
- threadEntryMap.put(threadQuark, threadEntry);
- traceEntry.addChild(threadEntry);
- } else {
- threadEntry.updateEndTime(threadEnd);
- }
- int level = 1;
- for (int stackLevelQuark : ss.getSubAttributes(callStackQuark, false)) {
- if (level > threadEntry.getChildren().size()) {
- CallStackEntry callStackEntry = new CallStackEntry(threadName, stackLevelQuark, level, trace, ss);
- threadEntry.addChild(callStackEntry);
+ ThreadEntry threadEntry = threadEntryMap.get(threadQuark);
+ if (threadEntry == null) {
+ if (startStates == null) {
+ startStates = ss.queryFullState(ss.getStartTime());
+ }
+ long threadId = endInterval.getStateValue().unboxLong();
+ long threadStart = start;
+ ITmfStateInterval startInterval = startStates.get(callStackQuark);
+ if (startInterval.getStateValue().isNull()) {
+ threadStart = Math.min(startInterval.getEndTime() + 1, end + 1);
+ }
+ threadEntry = new ThreadEntry(ss, threadName, threadId, callStackQuark, threadStart, threadEnd);
+ threadEntryMap.put(threadQuark, threadEntry);
+ processEntry.addChild(threadEntry);
+ } else {
+ threadEntry.updateEndTime(threadEnd);
+ }
+ int level = 1;
+ for (int stackLevelQuark : ss.getSubAttributes(callStackQuark, false)) {
+ if (level > threadEntry.getChildren().size()) {
+ CallStackEntry callStackEntry = new CallStackEntry(threadName, stackLevelQuark, level, trace, ss);
+ threadEntry.addChild(callStackEntry);
+ }
+ level++;
}
- level++;
}
+ } catch (AttributeNotFoundException e) {
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
+ } catch (StateSystemDisposedException e) {
+ /* Ignored */
}
- } catch (AttributeNotFoundException e) {
- Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
- } catch (StateSystemDisposedException e) {
- /* Ignored */
}
+
if (parentTrace == getTrace()) {
synchronized (this) {
setStartTime(getStartTime() == SWT.DEFAULT ? start : Math.min(getStartTime(), start));
synchingToTime(getTimeGraphViewer().getSelectionBegin());
refresh();
}
- for (ITimeGraphEntry threadEntry : traceEntry.getChildren()) {
- for (ITimeGraphEntry callStackEntry : threadEntry.getChildren()) {
- if (monitor.isCanceled()) {
- return;
+
+ for (ITimeGraphEntry processEntry : traceEntry.getChildren()) {
+ for (ITimeGraphEntry threadEntry : processEntry.getChildren()) {
+ for (ITimeGraphEntry callStackEntry : threadEntry.getChildren()) {
+ if (monitor.isCanceled()) {
+ return;
+ }
+ buildStatusEvents(parentTrace, (CallStackEntry) callStackEntry, monitor, ss.getStartTime(), end);
}
- buildStatusEvents(parentTrace, (CallStackEntry) callStackEntry, monitor, ss.getStartTime(), end);
}
}
start = end;
return;
}
for (TimeGraphEntry traceEntry : entryList) {
- for (ITimeGraphEntry threadEntry : traceEntry.getChildren()) {
- ITmfStateSystem ss = ((ThreadEntry) threadEntry).getStateSystem();
- if (ss == null) {
- continue;
- }
- if (ss.isCancelled()) {
- continue;
- }
- if (time < ss.getStartTime() || time > ss.getCurrentEndTime()) {
- continue;
- }
- for (ITimeGraphEntry child : threadEntry.getChildren()) {
- CallStackEntry callStackEntry = (CallStackEntry) child;
- ITmfTrace trace = callStackEntry.getTrace();
- try {
- ITmfStateInterval stackLevelInterval = ss.querySingleState(time, callStackEntry.getQuark());
- ITmfStateValue nameValue = stackLevelInterval.getStateValue();
- String name = getFunctionName(trace, nameValue);
- callStackEntry.setFunctionName(name);
- if (name.length() > 0) {
- callStackEntry.setFunctionEntryTime(stackLevelInterval.getStartTime());
- callStackEntry.setFunctionExitTime(stackLevelInterval.getEndTime() + 1);
+ for (ITimeGraphEntry processEntry : traceEntry.getChildren()) {
+ for (ITimeGraphEntry threadEntry : processEntry.getChildren()) {
+ ITmfStateSystem ss = ((ThreadEntry) threadEntry).getStateSystem();
+ if (ss == null) {
+ continue;
+ }
+ if (ss.isCancelled()) {
+ continue;
+ }
+ if (time < ss.getStartTime() || time > ss.getCurrentEndTime()) {
+ continue;
+ }
+ for (ITimeGraphEntry child : threadEntry.getChildren()) {
+ CallStackEntry callStackEntry = (CallStackEntry) child;
+ ITmfTrace trace = callStackEntry.getTrace();
+ try {
+ ITmfStateInterval stackLevelInterval = ss.querySingleState(time, callStackEntry.getQuark());
+ ITmfStateValue nameValue = stackLevelInterval.getStateValue();
+ String name = getFunctionName(trace, nameValue);
+ callStackEntry.setFunctionName(name);
+ if (name.length() > 0) {
+ callStackEntry.setFunctionEntryTime(stackLevelInterval.getStartTime());
+ callStackEntry.setFunctionExitTime(stackLevelInterval.getEndTime() + 1);
+ }
+ } catch (AttributeNotFoundException e) {
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
+ } catch (StateSystemDisposedException e) {
+ /* Ignored */
}
- } catch (AttributeNotFoundException e) {
- Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
- } catch (StateSystemDisposedException e) {
- /* Ignored */
}
}
}