/*******************************************************************************\r
* Copyright (c) 2012 Ericsson\r
- * \r
+ *\r
* All rights reserved. This program and the accompanying materials are\r
* made available under the terms of the Eclipse Public License v1.0 which\r
* accompanies this distribution, and is available at\r
* http://www.eclipse.org/legal/epl-v10.html\r
- * \r
+ *\r
* Contributors:\r
* Patrick Tasse - Initial API and implementation\r
*******************************************************************************/\r
\r
import java.util.ArrayList;\r
import java.util.Arrays;\r
-import java.util.HashMap;\r
+import java.util.Collections;\r
+import java.util.Comparator;\r
import java.util.List;\r
-import java.util.Map;\r
\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.NullProgressMonitor;\r
import org.eclipse.jface.action.Action;\r
import org.eclipse.jface.action.IToolBarManager;\r
import org.eclipse.jface.action.Separator;\r
import org.eclipse.jface.viewers.ITableLabelProvider;\r
import org.eclipse.jface.viewers.ITreeContentProvider;\r
import org.eclipse.jface.viewers.Viewer;\r
+import org.eclipse.linuxtools.internal.lttng2.kernel.core.Attributes;\r
import org.eclipse.linuxtools.internal.lttng2.kernel.ui.Messages;\r
-import org.eclipse.linuxtools.lttng2.kernel.core.trace.Attributes;\r
import org.eclipse.linuxtools.lttng2.kernel.core.trace.CtfKernelTrace;\r
import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTimestamp;\r
import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;\r
import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentSelectedSignal;\r
import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;\r
import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;\r
+import org.eclipse.linuxtools.tmf.core.signal.TmfStateSystemBuildCompleted;\r
import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;\r
import org.eclipse.linuxtools.tmf.core.statesystem.IStateSystemQuerier;\r
import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;\r
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphRangeListener;\r
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphSelectionListener;\r
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphTimeListener;\r
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.StateItem;\r
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphCombo;\r
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider;\r
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent;\r
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphSelectionEvent;\r
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTimeEvent;\r
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;\r
import org.eclipse.swt.SWT;\r
import org.eclipse.swt.graphics.Image;\r
-import org.eclipse.swt.graphics.RGB;\r
import org.eclipse.swt.widgets.Composite;\r
import org.eclipse.swt.widgets.Display;\r
import org.eclipse.swt.widgets.TreeColumn;\r
import org.eclipse.ui.IActionBars;\r
\r
+/**\r
+ * The Control Flow view main object\r
+ *\r
+ */\r
public class ControlFlowView extends TmfView {\r
\r
// ------------------------------------------------------------------------\r
*/\r
public static final String ID = "org.eclipse.linuxtools.lttng2.kernel.ui.views.controlflow"; //$NON-NLS-1$\r
\r
+ /**\r
+ * Initial time range\r
+ */\r
+ private static final long INITIAL_WINDOW_OFFSET = (1L * 100 * 1000 * 1000); // .1sec\r
+\r
private static final String PROCESS_COLUMN = Messages.ControlFlowView_processColumn;\r
private static final String TID_COLUMN = Messages.ControlFlowView_tidColumn;\r
- private static final String PPID_COLUMN = Messages.ControlFlowView_ppidColumn;\r
+ private static final String PTID_COLUMN = Messages.ControlFlowView_ptidColumn;\r
private static final String BIRTH_TIME_COLUMN = Messages.ControlFlowView_birthTimeColumn;\r
private static final String TRACE_COLUMN = Messages.ControlFlowView_traceColumn;\r
\r
private final String[] COLUMN_NAMES = new String[] {\r
PROCESS_COLUMN,\r
TID_COLUMN,\r
- PPID_COLUMN,\r
+ PTID_COLUMN,\r
BIRTH_TIME_COLUMN,\r
TRACE_COLUMN\r
};\r
// The timegraph entry list\r
private ArrayList<ControlFlowEntry> fEntryList;\r
\r
+ // The time graph entry list synchronization object\r
+ final private Object fEntryListSyncObj = new Object();\r
+\r
// The start time\r
private long fStartTime;\r
\r
private long fEndTime;\r
\r
// The display width\r
- private int fDisplayWidth;\r
+ private final int fDisplayWidth;\r
\r
// The zoom thread\r
private ZoomThread fZoomThread;\r
- \r
+\r
// The next resource action\r
private Action fNextResourceAction;\r
- \r
+\r
// The previous resource action\r
private Action fPreviousResourceAction;\r
\r
+ // A comparator class\r
+ private final ControlFlowEntryComparator fControlFlowEntryComparator = new ControlFlowEntryComparator();\r
+\r
// ------------------------------------------------------------------------\r
// Classes\r
// ------------------------------------------------------------------------\r
ITimeGraphEntry entry = (ITimeGraphEntry) element;\r
return entry.hasChildren();\r
}\r
- \r
+\r
}\r
\r
private class TreeLabelProvider implements ITableLabelProvider {\r
} else if (columnIndex == 1) {\r
return Integer.toString(entry.getThreadId());\r
} else if (columnIndex == 2) {\r
- if (entry.getPPID() > 0) {\r
- return Integer.toString(entry.getPPID());\r
+ if (entry.getParentThreadId() > 0) {\r
+ return Integer.toString(entry.getParentThreadId());\r
}\r
} else if (columnIndex == 3) {\r
return Utils.formatTime(entry.getBirthTime(), TimeFormat.ABSOLUTE, Resolution.NANOSEC);\r
}\r
return ""; //$NON-NLS-1$\r
}\r
- \r
+\r
}\r
\r
+ private static class ControlFlowEntryComparator implements Comparator<ITimeGraphEntry> {\r
+\r
+ @Override\r
+ public int compare(ITimeGraphEntry o1, ITimeGraphEntry o2) {\r
+ int result = 0;\r
+\r
+ if ((o1 instanceof ControlFlowEntry) && (o2 instanceof ControlFlowEntry)) {\r
+ ControlFlowEntry entry1 = (ControlFlowEntry) o1;\r
+ ControlFlowEntry entry2 = (ControlFlowEntry) o2;\r
+ result = entry1.getTrace().getStartTime().compareTo(entry2.getTrace().getStartTime());\r
+ if (result == 0) {\r
+ result = entry1.getTrace().getName().compareTo(entry2.getTrace().getName());\r
+ }\r
+ if (result == 0) {\r
+ result = entry1.getThreadId() < entry2.getThreadId() ? -1 : entry1.getThreadId() > entry2.getThreadId() ? 1 : 0;\r
+ }\r
+ }\r
+\r
+ if (result == 0) {\r
+ result = o1.getStartTime() < o2.getStartTime() ? -1 : o1.getStartTime() > o2.getStartTime() ? 1 : 0;\r
+ }\r
+\r
+ return result;\r
+ }\r
+ }\r
+\r
+\r
private class ZoomThread extends Thread {\r
- private long fStartTime;\r
- private long fEndTime;\r
- private long fResolution;\r
- private boolean fCancelled = false;\r
+ private final long fZoomStartTime;\r
+ private final long fZoomEndTime;\r
+ private final long fResolution;\r
+ private final IProgressMonitor fMonitor;\r
\r
public ZoomThread(long startTime, long endTime) {\r
super("ControlFlowView zoom"); //$NON-NLS-1$\r
- fStartTime = startTime;\r
- fEndTime = endTime;\r
- fResolution = Math.max(1, (fEndTime - fStartTime) / fDisplayWidth);\r
+ fZoomStartTime = startTime;\r
+ fZoomEndTime = endTime;\r
+ fResolution = Math.max(1, (fZoomEndTime - fZoomStartTime) / fDisplayWidth);\r
+ fMonitor = new NullProgressMonitor();\r
}\r
\r
@Override\r
public void run() {\r
- if (fEntryList == null) {\r
+ ArrayList<ControlFlowEntry> entryList = null;\r
+ synchronized (fEntryListSyncObj) {\r
+ entryList = fEntryList;\r
+ }\r
+ if (entryList == null) {\r
return;\r
}\r
- for (ControlFlowEntry entry : fEntryList) {\r
- if (fCancelled) {\r
- return;\r
+ for (ControlFlowEntry entry : entryList) {\r
+ if (fMonitor.isCanceled()) {\r
+ break;\r
}\r
- zoom(entry);\r
+ zoom(entry, fMonitor);\r
}\r
redraw();\r
}\r
\r
- private void zoom(ControlFlowEntry entry) {\r
- List<ITimeEvent> zoomedEventList = getEventList(entry, fStartTime, fEndTime, fResolution);\r
- entry.setZoomedEventList(zoomedEventList);\r
+ private void zoom(ControlFlowEntry entry, IProgressMonitor monitor) {\r
+ if (fZoomStartTime <= fStartTime && fZoomEndTime >= fEndTime) {\r
+ entry.setZoomedEventList(null);\r
+ } else {\r
+ List<ITimeEvent> zoomedEventList = getEventList(entry, fZoomStartTime, fZoomEndTime, fResolution, monitor);\r
+ if (zoomedEventList != null) {\r
+ entry.setZoomedEventList(zoomedEventList);\r
+ }\r
+ }\r
for (ControlFlowEntry child : entry.getChildren()) {\r
- if (fCancelled) {\r
+ if (fMonitor.isCanceled()) {\r
return;\r
}\r
- zoom(child);\r
+ zoom(child, monitor);\r
}\r
}\r
\r
public void cancel() {\r
- fCancelled = true;\r
+ fMonitor.setCanceled(true);\r
}\r
}\r
\r
// Constructors\r
// ------------------------------------------------------------------------\r
\r
+ /**\r
+ * Constructor\r
+ */\r
public ControlFlowView() {\r
super(ID);\r
fDisplayWidth = Display.getDefault().getBounds().width;\r
\r
fTimeGraphCombo.setTreeLabelProvider(new TreeLabelProvider());\r
\r
- fTimeGraphCombo.setTimeGraphProvider(new TimeGraphPresentationProvider() {\r
- private static final String UNKNOWN = "UNKNOWN"; //$NON-NLS-1$\r
- private static final String WAIT = "WAIT"; //$NON-NLS-1$\r
- private static final String USERMODE = "USERMODE"; //$NON-NLS-1$\r
- private static final String SYSCALL = "SYSCALL"; //$NON-NLS-1$\r
- private static final String INTERRUPTED = "INTERRUPTED"; //$NON-NLS-1$\r
-\r
- @Override \r
- public String getStateTypeName() {\r
- return Messages.ControlFlowView_stateTypeName;\r
- }\r
- \r
- @Override\r
- public StateItem[] getStateTable() {\r
- return new StateItem[] {\r
- new StateItem(new RGB(100, 100, 100), UNKNOWN),\r
- new StateItem(new RGB(150, 150, 0), WAIT),\r
- new StateItem(new RGB(0, 200, 0), USERMODE),\r
- new StateItem(new RGB(0, 0, 200), SYSCALL),\r
- new StateItem(new RGB(200, 100, 100), INTERRUPTED)\r
- };\r
- }\r
-\r
- @Override\r
- public int getEventTableIndex(ITimeEvent event) {\r
- if (event instanceof ControlFlowEvent) {\r
- int status = ((ControlFlowEvent) event).getStatus();\r
- if (status == Attributes.STATUS_WAIT) {\r
- return 1;\r
- } else if (status == Attributes.STATUS_RUN_USERMODE) {\r
- return 2;\r
- } else if (status == Attributes.STATUS_RUN_SYSCALL) {\r
- return 3;\r
- } else if (status == Attributes.STATUS_INTERRUPTED) {\r
- return 4;\r
- }\r
- }\r
- return 0;\r
- }\r
-\r
- @Override\r
- public String getEventName(ITimeEvent event) {\r
- if (event instanceof ControlFlowEvent) {\r
- int status = ((ControlFlowEvent) event).getStatus();\r
- if (status == Attributes.STATUS_WAIT) {\r
- return WAIT;\r
- } else if (status == Attributes.STATUS_RUN_USERMODE) {\r
- return USERMODE;\r
- } else if (status == Attributes.STATUS_RUN_SYSCALL) {\r
- return SYSCALL;\r
- } else if (status == Attributes.STATUS_INTERRUPTED) {\r
- return INTERRUPTED;\r
- }\r
- }\r
- return UNKNOWN;\r
- }\r
- \r
- @Override\r
- public Map<String, String> getEventHoverToolTipInfo(ITimeEvent event) {\r
- return new HashMap<String, String>();\r
- }\r
- });\r
+ fTimeGraphCombo.setTimeGraphProvider(new ControlFlowPresentationProvider());\r
\r
fTimeGraphCombo.setTreeColumns(COLUMN_NAMES);\r
\r
if (fZoomThread != null) {\r
fZoomThread.cancel();\r
}\r
- fZoomThread = new ZoomThread(startTime, endTime);\r
- fZoomThread.start();\r
+ startZoomThread(startTime, endTime);\r
}\r
});\r
\r
}\r
};\r
thread.start();\r
- \r
+\r
// View Action Handling\r
makeActions();\r
contributeToActionBars();\r
// Signal handlers\r
// ------------------------------------------------------------------------\r
\r
+ /**\r
+ * Handler for the experiment selected signal\r
+ *\r
+ * @param signal\r
+ * The signal that's received\r
+ */\r
@TmfSignalHandler\r
public void experimentSelected(final TmfExperimentSelectedSignal<? extends ITmfEvent> signal) {\r
if (signal.getExperiment().equals(fSelectedExperiment)) {\r
@Override\r
public void run() {\r
selectExperiment(signal.getExperiment());\r
- }};\r
+ }\r
+ };\r
thread.start();\r
}\r
\r
+ /**\r
+ * Handler for the synch signal\r
+ *\r
+ * @param signal\r
+ * The signal that's received\r
+ */\r
@TmfSignalHandler\r
public void synchToTime(final TmfTimeSynchSignal signal) {\r
- if (signal.getSource() == this) {\r
+ if (signal.getSource() == this || fSelectedExperiment == null) {\r
return;\r
}\r
final long time = signal.getCurrentTime().normalize(0, -9).getValue();\r
+\r
+ int thread = -1;\r
+ for (ITmfTrace<?> trace : fSelectedExperiment.getTraces()) {\r
+ if (thread > 0) {\r
+ break;\r
+ }\r
+ if (trace instanceof CtfKernelTrace) {\r
+ CtfKernelTrace ctfKernelTrace = (CtfKernelTrace) trace;\r
+ IStateSystemQuerier ssq = ctfKernelTrace.getStateSystem();\r
+ if (time >= ssq.getStartTime() && time <= ssq.getCurrentEndTime()) {\r
+ List<Integer> currentThreadQuarks = ssq.getQuarks(Attributes.CPUS, "*", Attributes.CURRENT_THREAD); //$NON-NLS-1$\r
+ for (int currentThreadQuark : currentThreadQuarks) {\r
+ try {\r
+ ITmfStateInterval currentThreadInterval = ssq.querySingleState(time, currentThreadQuark);\r
+ int currentThread = currentThreadInterval.getStateValue().unboxInt();\r
+ if (currentThread > 0) {\r
+ int statusQuark = ssq.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThread), Attributes.STATUS);\r
+ ITmfStateInterval statusInterval = ssq.querySingleState(time, statusQuark);\r
+ if (statusInterval.getStartTime() == time) {\r
+ thread = currentThread;\r
+ break;\r
+ }\r
+ }\r
+ } catch (AttributeNotFoundException e) {\r
+ e.printStackTrace();\r
+ } catch (TimeRangeException e) {\r
+ e.printStackTrace();\r
+ } catch (StateValueTypeException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ final int selectedThread = thread;\r
+\r
Display.getDefault().asyncExec(new Runnable() {\r
@Override\r
public void run() {\r
if (fTimeGraphCombo.isDisposed()) {\r
return;\r
}\r
- fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, true, signal.getSource());\r
+ fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, true);\r
+ startZoomThread(fTimeGraphCombo.getTimeGraphViewer().getTime0(), fTimeGraphCombo.getTimeGraphViewer().getTime1());\r
+\r
+ if (selectedThread > 0) {\r
+ for (Object element : fTimeGraphCombo.getTimeGraphViewer().getExpandedElements()) {\r
+ if (element instanceof ControlFlowEntry) {\r
+ ControlFlowEntry entry = (ControlFlowEntry) element;\r
+ if (entry.getThreadId() == selectedThread) {\r
+ fTimeGraphCombo.setSelection(entry);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
}\r
});\r
}\r
\r
+ /**\r
+ * Handler for the range sync signal\r
+ *\r
+ * @param signal\r
+ * The signal that's received\r
+ */\r
@TmfSignalHandler\r
public void synchToRange(final TmfRangeSynchSignal signal) {\r
- if (signal.getSource() == this) {\r
+ if (signal.getSource() == this || fSelectedExperiment == null) {\r
return;\r
}\r
final long startTime = signal.getCurrentRange().getStartTime().normalize(0, -9).getValue();\r
return;\r
}\r
fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);\r
- fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, false, signal.getSource());\r
+ fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, false);\r
+ startZoomThread(startTime, endTime);\r
}\r
});\r
}\r
\r
+ /**\r
+ * Handler for the state system build completed signal\r
+ *\r
+ * @param signal\r
+ * The signal that's received\r
+ */\r
+ @TmfSignalHandler\r
+ public void stateSystemBuildCompleted (final TmfStateSystemBuildCompleted signal) {\r
+ final TmfExperiment<?> selectedExperiment = fSelectedExperiment;\r
+ if (selectedExperiment == null) {\r
+ return;\r
+ }\r
+ for (ITmfTrace<?> trace : selectedExperiment.getTraces()) {\r
+ if (trace == signal.getTrace() && trace instanceof CtfKernelTrace) {\r
+ final Thread thread = new Thread("ControlFlowView build") { //$NON-NLS-1$\r
+ @Override\r
+ public void run() {\r
+ // rebuild the model\r
+ selectExperiment(selectedExperiment);\r
+ }\r
+ };\r
+ thread.start();\r
+ }\r
+ }\r
+ }\r
+\r
// ------------------------------------------------------------------------\r
// Internal\r
// ------------------------------------------------------------------------\r
fStartTime = Long.MAX_VALUE;\r
fEndTime = Long.MIN_VALUE;\r
fSelectedExperiment = (TmfExperiment<ITmfEvent>) experiment;\r
- fEntryList = new ArrayList<ControlFlowEntry>();\r
+ ArrayList<ControlFlowEntry> rootList = new ArrayList<ControlFlowEntry>();\r
for (ITmfTrace<?> trace : experiment.getTraces()) {\r
if (trace instanceof CtfKernelTrace) {\r
+ ArrayList<ControlFlowEntry> entryList = new ArrayList<ControlFlowEntry>();\r
CtfKernelTrace ctfKernelTrace = (CtfKernelTrace) trace;\r
IStateSystemQuerier ssq = ctfKernelTrace.getStateSystem();\r
long start = ssq.getStartTime();\r
- long end = ssq.getCurrentEndTime();\r
+ long end = ssq.getCurrentEndTime() + 1;\r
fStartTime = Math.min(fStartTime, start);\r
fEndTime = Math.max(fEndTime, end);\r
List<Integer> threadQuarks = ssq.getQuarks(Attributes.THREADS, "*"); //$NON-NLS-1$\r
continue;\r
}\r
int ppidQuark = ssq.getQuarkRelative(threadQuark, Attributes.PPID);\r
- List<ITmfStateInterval> execNameIntervals = ssq.queryHistoryRange(execNameQuark, start, end);\r
+ List<ITmfStateInterval> execNameIntervals = ssq.queryHistoryRange(execNameQuark, start, end - 1);\r
long birthTime = -1;\r
for (ITmfStateInterval execNameInterval : execNameIntervals) {\r
if (!execNameInterval.getStateValue().isNull() && execNameInterval.getStateValue().getType() == 1) {\r
ppid = ppidInterval.getStateValue().unboxInt();\r
}\r
ControlFlowEntry entry = new ControlFlowEntry(threadQuark, ctfKernelTrace, execName, threadId, ppid, birthTime, startTime, endTime);\r
- fEntryList.add(entry);\r
+ entryList.add(entry);\r
entry.addEvent(new TimeEvent(entry, startTime, endTime - startTime));\r
} else {\r
birthTime = -1;\r
e.printStackTrace();\r
}\r
}\r
+ buildTree(entryList, rootList);\r
}\r
- buildTree();\r
- refresh();\r
- ControlFlowEntry[] entries = fEntryList.toArray(new ControlFlowEntry[0]);\r
- Arrays.sort(entries);\r
- for (ControlFlowEntry entry : entries) {\r
- buildStatusEvents(entry);\r
+ Collections.sort(rootList, fControlFlowEntryComparator);\r
+ synchronized (fEntryListSyncObj) {\r
+ fEntryList = (ArrayList<ControlFlowEntry>) rootList.clone();\r
}\r
+ refresh(INITIAL_WINDOW_OFFSET);\r
+ }\r
+ for (ControlFlowEntry entry : rootList) {\r
+ buildStatusEvents(entry);\r
}\r
}\r
\r
- private void buildTree() {\r
- ArrayList<ControlFlowEntry> rootList = new ArrayList<ControlFlowEntry>();\r
- for (ControlFlowEntry entry : fEntryList) {\r
+ private void buildTree(ArrayList<ControlFlowEntry> entryList, ArrayList<ControlFlowEntry> rootList) {\r
+ for (ControlFlowEntry entry : entryList) {\r
boolean root = true;\r
- if (entry.getPPID() > 0) {\r
- for (ControlFlowEntry parent : fEntryList) {\r
- if (parent.getThreadId() == entry.getPPID() &&\r
+ if (entry.getParentThreadId() > 0) {\r
+ for (ControlFlowEntry parent : entryList) {\r
+ if (parent.getThreadId() == entry.getParentThreadId() &&\r
entry.getStartTime() >= parent.getStartTime() &&\r
entry.getStartTime() <= parent.getEndTime()) {\r
parent.addChild(entry);\r
rootList.add(entry);\r
}\r
}\r
- fEntryList = rootList;\r
}\r
\r
private void buildStatusEvents(ControlFlowEntry entry) {\r
IStateSystemQuerier ssq = entry.getTrace().getStateSystem();\r
long start = ssq.getStartTime();\r
- long end = ssq.getCurrentEndTime();\r
+ long end = ssq.getCurrentEndTime() + 1;\r
long resolution = Math.max(1, (end - start) / fDisplayWidth);\r
- List<ITimeEvent> eventList = getEventList(entry, entry.getStartTime(), entry.getEndTime(), resolution);\r
+ List<ITimeEvent> eventList = getEventList(entry, entry.getStartTime(), entry.getEndTime(), resolution, new NullProgressMonitor());\r
entry.setEventList(eventList);\r
redraw();\r
for (ITimeGraphEntry child : entry.getChildren()) {\r
}\r
}\r
\r
- private List<ITimeEvent> getEventList(ControlFlowEntry entry, long startTime, long endTime, long resolution) {\r
+ private List<ITimeEvent> getEventList(ControlFlowEntry entry, long startTime, long endTime, long resolution, IProgressMonitor monitor) {\r
startTime = Math.max(startTime, entry.getStartTime());\r
endTime = Math.min(endTime, entry.getEndTime());\r
if (endTime <= startTime) {\r
eventList = new ArrayList<ITimeEvent>(statusIntervals.size());\r
long lastEndTime = -1;\r
for (ITmfStateInterval statusInterval : statusIntervals) {\r
+ if (monitor.isCanceled()) {\r
+ return null;\r
+ }\r
long time = statusInterval.getStartTime();\r
long duration = statusInterval.getEndTime() - time + 1;\r
int status = -1;\r
return eventList;\r
}\r
\r
- private void refresh() {\r
+ private void refresh(final long windowRange) {\r
Display.getDefault().asyncExec(new Runnable() {\r
@Override\r
public void run() {\r
if (fTimeGraphCombo.isDisposed()) {\r
return;\r
}\r
- ITimeGraphEntry[] entries = fEntryList.toArray(new ITimeGraphEntry[0]);\r
- Arrays.sort(entries);\r
+ ITimeGraphEntry[] entries = null;\r
+ synchronized (fEntryListSyncObj) {\r
+ entries = fEntryList.toArray(new ITimeGraphEntry[0]);\r
+ }\r
+ Arrays.sort(entries, fControlFlowEntryComparator);\r
fTimeGraphCombo.setInput(entries);\r
fTimeGraphCombo.getTimeGraphViewer().setTimeBounds(fStartTime, fEndTime);\r
- fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(fStartTime, fEndTime);\r
+\r
+ long endTime = fStartTime + windowRange;\r
+\r
+ if (fEndTime < endTime) {\r
+ endTime = fEndTime;\r
+ }\r
+ fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(fStartTime, endTime);\r
for (TreeColumn column : fTimeGraphCombo.getTreeViewer().getTree().getColumns()) {\r
column.pack();\r
}\r
+\r
+ startZoomThread(fStartTime, endTime);\r
}\r
});\r
}\r
});\r
}\r
\r
+ private void startZoomThread(long startTime, long endTime) {\r
+ if (fZoomThread != null) {\r
+ fZoomThread.cancel();\r
+ }\r
+ fZoomThread = new ZoomThread(startTime, endTime);\r
+ fZoomThread.start();\r
+ }\r
+\r
private void makeActions() {\r
fPreviousResourceAction = fTimeGraphCombo.getTimeGraphViewer().getPreviousItemAction();\r
fPreviousResourceAction.setText(Messages.ControlFlowView_previousProcessActionNameText);\r
fNextResourceAction.setText(Messages.ControlFlowView_nextProcessActionNameText);\r
fNextResourceAction.setToolTipText(Messages.ControlFlowView_nextProcessActionToolTipText);\r
}\r
- \r
+\r
private void contributeToActionBars() {\r
IActionBars bars = getViewSite().getActionBars();\r
fillLocalToolBar(bars.getToolBarManager());\r