/*******************************************************************************
- * Copyright (c) 2013 Ericsson
+ * Copyright (c) 2013, 2014 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.linuxtools.internal.tmf.ui.Activator;
import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants;
import org.eclipse.linuxtools.internal.tmf.ui.Messages;
+import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem;
+import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException;
+import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException;
+import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue;
+import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type;
import org.eclipse.linuxtools.tmf.core.callstack.CallStackStateProvider;
-import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
-import org.eclipse.linuxtools.tmf.core.exceptions.StateSystemDisposedException;
-import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
-import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
-import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;
import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal;
-import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
-import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
-import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue.Type;
import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp;
import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampDelta;
import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
-import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment;
+import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager;
import org.eclipse.linuxtools.tmf.ui.editors.ITmfTraceEditor;
import org.eclipse.linuxtools.tmf.ui.views.TmfView;
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphRangeListener;
private ITmfTrace fTrace;
// The selected thread map
- private final Map<ITmfTrace, String> fSelectedThreadMap = new HashMap<ITmfTrace, String>();
+ private final Map<ITmfTrace, String> fSelectedThreadMap = new HashMap<>();
// The time graph entry list
private List<ThreadEntry> fEntryList;
// The trace to entry list hash map
- private final Map<ITmfTrace, ArrayList<ThreadEntry>> fEntryListMap = new HashMap<ITmfTrace, ArrayList<ThreadEntry>>();
+ private final Map<ITmfTrace, ArrayList<ThreadEntry>> fEntryListMap = new HashMap<>();
// The trace to build thread hash map
- private final Map<ITmfTrace, BuildThread> fBuildThreadMap = new HashMap<ITmfTrace, BuildThread>();
+ private final Map<ITmfTrace, BuildThread> fBuildThreadMap = new HashMap<>();
/** The map to map function addresses to function names */
private Map<String, String> fNameMapping;
// ------------------------------------------------------------------------
private class ThreadEntry implements ITimeGraphEntry {
- // The Trace
- private final ITmfTrace fThreadTrace;
// The start time
private final long fTraceStartTime;
// The end time
private final String fName;
// The thread attribute quark
private final int fThreadQuark;
+ // The state system from which this entry comes
+ private final ITmfStateSystem fSS;
public ThreadEntry(ITmfTrace trace, String name, int threadQuark, long startTime, long endTime) {
- fThreadTrace = trace;
- fChildren = new ArrayList<CallStackEntry>();
+ fChildren = new ArrayList<>();
fName = name;
fTraceStartTime = startTime;
fTraceEndTime = endTime;
fThreadQuark = threadQuark;
+
+ fSS = getCallStackStateSystem(trace);
}
@Override
@Override
public boolean hasChildren() {
if (fChildren == null) {
- ITmfStateSystem ss = fThreadTrace.getStateSystems().get(CallStackStateProvider.ID);
+ ITmfStateSystem ss = getStateSystem();
+ if (ss == null) {
+ return false;
+ }
try {
int eventStackQuark = ss.getQuarkRelative(fThreadQuark, CallStackStateProvider.CALL_STACK);
ITmfStateInterval eventStackInterval = ss.querySingleState(ss.getStartTime(), eventStackQuark);
return fThreadQuark;
}
- public ITmfTrace getTrace() {
- return fThreadTrace;
+ @Nullable
+ public ITmfStateSystem getStateSystem() {
+ return fSS;
}
public void addChild(CallStackEntry entry) {
}
long resolution = Math.max(1, (fZoomEndTime - fZoomStartTime) / fDisplayWidth);
for (ThreadEntry threadEntry : fZoomEntryList) {
- ITmfStateSystem ss = threadEntry.fThreadTrace.getStateSystems().get(CallStackStateProvider.ID);
- if (ss == null || !ss.waitUntilBuilt()) {
+ ITmfStateSystem ss = threadEntry.getStateSystem();
+ if (ss == null) {
+ continue;
+ }
+ ss.waitUntilBuilt();
+ if (ss.isCancelled()) {
continue;
}
for (ITimeGraphEntry child : threadEntry.getChildren()) {
}
TimeGraphViewer viewer = fTimeGraphCombo.getTimeGraphViewer();
for (ThreadEntry threadEntry : fEntryList) {
- ITmfStateSystem ss = threadEntry.getTrace().getStateSystems().get(CallStackStateProvider.ID);
+ ITmfStateSystem ss = threadEntry.getStateSystem();
if (ss == null || beginTime < ss.getStartTime() || beginTime > ss.getCurrentEndTime()) {
continue;
}
private void buildThreadList(final ITmfTrace trace, IProgressMonitor monitor) {
fStartTime = Long.MAX_VALUE;
fEndTime = Long.MIN_VALUE;
- ITmfTrace[] traces;
- if (trace instanceof TmfExperiment) {
- TmfExperiment experiment = (TmfExperiment) trace;
- traces = experiment.getTraces();
- } else {
- traces = new ITmfTrace[] { trace };
- }
- ArrayList<ThreadEntry> entryList = new ArrayList<ThreadEntry>();
+ ITmfTrace[] traces = TmfTraceManager.getTraceSet(trace);
+ ArrayList<ThreadEntry> entryList = new ArrayList<>();
for (ITmfTrace aTrace : traces) {
if (monitor.isCanceled()) {
return;
}
- ITmfStateSystem ss = aTrace.getStateSystems().get(CallStackStateProvider.ID);
- if (ss == null || !ss.waitUntilBuilt()) {
- String threadName = Messages.CallStackView_StackInfoNotAvailable + ' ' + '(' + aTrace.getName() + ')';
- ThreadEntry threadEntry = new ThreadEntry(aTrace, threadName, -1, 0, 0);
- entryList.add(threadEntry);
+ ITmfStateSystem ss = getCallStackStateSystem(aTrace);
+ if (ss == null) {
+ addUnavailableEntry(aTrace, entryList);
+ continue;
+ }
+ ss.waitUntilBuilt();
+ if (ss.isCancelled()) {
+ addUnavailableEntry(aTrace, entryList);
continue;
}
long startTime = ss.getStartTime();
}
}
synchronized (fEntryListMap) {
- fEntryListMap.put(trace, new ArrayList<ThreadEntry>(entryList));
+ fEntryListMap.put(trace, new ArrayList<>(entryList));
}
if (trace == fTrace) {
refresh();
}
}
+ private void addUnavailableEntry(ITmfTrace trace, List<ThreadEntry> list) {
+ String threadName = Messages.CallStackView_StackInfoNotAvailable + ' ' + '(' + trace.getName() + ')';
+ ThreadEntry threadEntry = new ThreadEntry(trace, threadName, -1, 0, 0);
+ list.add(threadEntry);
+ }
+
private void buildStatusEvents(ITmfTrace trace, CallStackEntry entry, IProgressMonitor monitor) {
- ITmfStateSystem ss = entry.getTrace().getStateSystems().get(CallStackStateProvider.ID);
+ ITmfStateSystem ss = getCallStackStateSystem(entry.getTrace());
+ if (ss == null) {
+ return;
+ }
long start = ss.getStartTime();
long end = ss.getCurrentEndTime() + 1;
long resolution = Math.max(1, (end - start) / fDisplayWidth);
private static List<ITimeEvent> getEventList(CallStackEntry entry,
long startTime, long endTime, long resolution,
IProgressMonitor monitor) {
- ITmfStateSystem ss = entry.getTrace().getStateSystems().get(CallStackStateProvider.ID);
+ ITmfStateSystem ss = getCallStackStateSystem(entry.getTrace());
+ if (ss == null) {
+ return null;
+ }
long start = Math.max(startTime, ss.getStartTime());
long end = Math.min(endTime, ss.getCurrentEndTime() + 1);
if (end <= start) {
List<ITimeEvent> eventList = null;
try {
List<ITmfStateInterval> stackIntervals = ss.queryHistoryRange(entry.getQuark(), start, end - 1, resolution, monitor);
- eventList = new ArrayList<ITimeEvent>(stackIntervals.size());
+ eventList = new ArrayList<>(stackIntervals.size());
long lastEndTime = -1;
boolean lastIsNull = true;
for (ITmfStateInterval statusInterval : stackIntervals) {
return;
}
for (ThreadEntry threadEntry : fEntryList) {
- ITmfStateSystem ss = threadEntry.fThreadTrace.getStateSystems().get(CallStackStateProvider.ID);
- if (ss == null || !ss.waitUntilBuilt()) {
+ ITmfStateSystem ss = threadEntry.getStateSystem();
+ if (ss == null) {
+ continue;
+ }
+ ss.waitUntilBuilt();
+ if (ss.isCancelled()) {
continue;
}
long queryTime = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), time));
synchronized (fEntryListMap) {
fEntryList = fEntryListMap.get(fTrace);
if (fEntryList == null) {
- fEntryList = new ArrayList<ThreadEntry>();
+ fEntryList = new ArrayList<>();
}
entries = fEntryList.toArray(new ITimeGraphEntry[0]);
}
try {
CallStackEntry callStackEntry = (CallStackEntry) entry;
ITmfTrace trace = callStackEntry.getTrace();
- ITmfStateSystem ss = trace.getStateSystems().get(CallStackStateProvider.ID);
+ ITmfStateSystem ss = getCallStackStateSystem(trace);
+ if (ss == null) {
+ return;
+ }
long time = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), viewer.getSelectionBegin()));
ThreadEntry threadEntry = (ThreadEntry) callStackEntry.getParent();
int quark = ss.getQuarkRelative(threadEntry.getThreadQuark(), CallStackStateProvider.CALL_STACK);
fTimeGraphCombo.setSelection(selectedEntry);
viewer.getTimeGraphControl().fireSelectionChanged();
startZoomThread(viewer.getTime0(), viewer.getTime1());
+
} catch (AttributeNotFoundException e) {
Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
} catch (TimeRangeException e) {
try {
CallStackEntry callStackEntry = (CallStackEntry) entry;
ITmfTrace trace = callStackEntry.getTrace();
- ITmfStateSystem ss = trace.getStateSystems().get(CallStackStateProvider.ID);
+ ITmfStateSystem ss = getCallStackStateSystem(trace);
+ if (ss == null) {
+ return;
+ }
long time = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), viewer.getSelectionBegin()));
ThreadEntry threadEntry = (ThreadEntry) callStackEntry.getParent();
int quark = ss.getQuarkRelative(threadEntry.getThreadQuark(), CallStackStateProvider.CALL_STACK);
fTimeGraphCombo.setSelection(selectedEntry);
viewer.getTimeGraphControl().fireSelectionChanged();
startZoomThread(viewer.getTime0(), viewer.getTime1());
+
} catch (AttributeNotFoundException e) {
Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
} catch (TimeRangeException e) {
return fPrevEventAction;
}
+ @Nullable
+ static ITmfStateSystem getCallStackStateSystem(ITmfTrace trace) {
+ /*
+ * Since we cannot know the exact analysis ID (in separate plugins), we
+ * will search using the analysis type.
+ */
+ Iterable<AbstractCallStackAnalysis> modules =
+ trace.getAnalysisModulesOfClass(AbstractCallStackAnalysis.class);
+ Iterator<AbstractCallStackAnalysis> it = modules.iterator();
+ if (!it.hasNext()) {
+ /* This trace does not provide a call-stack analysis */
+ return null;
+ }
+
+ /*
+ * We only look at the first module we find.
+ *
+ * TODO Handle the advanced case where one trace provides more than one
+ * call-stack analysis.
+ */
+ AbstractCallStackAnalysis module = it.next();
+ /* This analysis is not automatic, we need to schedule it on-demand */
+ module.schedule();
+ module.waitForInitialization();
+ ITmfStateSystem ss = module.getStateSystem();
+ if (ss == null) {
+ /* If we've waited for initialization, 'ss' should not be null */
+ throw new IllegalStateException();
+ }
+ return ss;
+ }
+
// ------------------------------------------------------------------------
// Methods related to function name mapping
// ------------------------------------------------------------------------