1 /*******************************************************************************
2 * Copyright (c) 2012 Ericsson
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
10 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.internal
.lttng2
.kernel
.ui
.views
.controlflow
;
15 import java
.util
.ArrayList
;
16 import java
.util
.Arrays
;
17 import java
.util
.HashMap
;
18 import java
.util
.List
;
21 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
22 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
23 import org
.eclipse
.jface
.action
.Action
;
24 import org
.eclipse
.jface
.action
.IToolBarManager
;
25 import org
.eclipse
.jface
.action
.Separator
;
26 import org
.eclipse
.jface
.viewers
.ILabelProviderListener
;
27 import org
.eclipse
.jface
.viewers
.ITableLabelProvider
;
28 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
29 import org
.eclipse
.jface
.viewers
.Viewer
;
30 import org
.eclipse
.linuxtools
.internal
.lttng2
.kernel
.ui
.Messages
;
31 import org
.eclipse
.linuxtools
.lttng2
.kernel
.core
.trace
.Attributes
;
32 import org
.eclipse
.linuxtools
.lttng2
.kernel
.core
.trace
.CtfKernelTrace
;
33 import org
.eclipse
.linuxtools
.tmf
.core
.ctfadaptor
.CtfTmfTimestamp
;
34 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
35 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfTimeRange
;
36 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfTimestamp
;
37 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.AttributeNotFoundException
;
38 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.StateValueTypeException
;
39 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.TimeRangeException
;
40 import org
.eclipse
.linuxtools
.tmf
.core
.interval
.ITmfStateInterval
;
41 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfExperimentSelectedSignal
;
42 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfRangeSynchSignal
;
43 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignalHandler
;
44 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTimeSynchSignal
;
45 import org
.eclipse
.linuxtools
.tmf
.core
.statesystem
.IStateSystemQuerier
;
46 import org
.eclipse
.linuxtools
.tmf
.core
.statevalue
.ITmfStateValue
;
47 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
48 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfExperiment
;
49 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.TmfView
;
50 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.ITimeGraphRangeListener
;
51 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.ITimeGraphSelectionListener
;
52 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.ITimeGraphTimeListener
;
53 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.StateItem
;
54 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.TimeGraphCombo
;
55 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.TimeGraphPresentationProvider
;
56 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.TimeGraphRangeUpdateEvent
;
57 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.TimeGraphSelectionEvent
;
58 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.TimeGraphTimeEvent
;
59 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.model
.ITimeEvent
;
60 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.model
.ITimeGraphEntry
;
61 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.model
.TimeEvent
;
62 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
;
63 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.Resolution
;
64 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.TimeFormat
;
65 import org
.eclipse
.swt
.SWT
;
66 import org
.eclipse
.swt
.graphics
.Image
;
67 import org
.eclipse
.swt
.graphics
.RGB
;
68 import org
.eclipse
.swt
.widgets
.Composite
;
69 import org
.eclipse
.swt
.widgets
.Display
;
70 import org
.eclipse
.swt
.widgets
.TreeColumn
;
71 import org
.eclipse
.ui
.IActionBars
;
73 public class ControlFlowView
extends TmfView
{
75 // ------------------------------------------------------------------------
77 // ------------------------------------------------------------------------
82 public static final String ID
= "org.eclipse.linuxtools.lttng2.kernel.ui.views.controlflow"; //$NON-NLS-1$
87 private static final long INITIAL_WINDOW_OFFSET
= (1L * 100 * 1000 * 1000); // .1sec
89 private static final String PROCESS_COLUMN
= Messages
.ControlFlowView_processColumn
;
90 private static final String TID_COLUMN
= Messages
.ControlFlowView_tidColumn
;
91 private static final String PPID_COLUMN
= Messages
.ControlFlowView_ppidColumn
;
92 private static final String BIRTH_TIME_COLUMN
= Messages
.ControlFlowView_birthTimeColumn
;
93 private static final String TRACE_COLUMN
= Messages
.ControlFlowView_traceColumn
;
95 private final String
[] COLUMN_NAMES
= new String
[] {
103 // ------------------------------------------------------------------------
105 // ------------------------------------------------------------------------
107 // The timegraph combo
108 private TimeGraphCombo fTimeGraphCombo
;
110 // The selected experiment
111 private TmfExperiment
<ITmfEvent
> fSelectedExperiment
;
113 // The timegraph entry list
114 private ArrayList
<ControlFlowEntry
> fEntryList
;
117 private long fStartTime
;
120 private long fEndTime
;
123 private int fDisplayWidth
;
126 private ZoomThread fZoomThread
;
128 // The next resource action
129 private Action fNextResourceAction
;
131 // The previous resource action
132 private Action fPreviousResourceAction
;
134 // ------------------------------------------------------------------------
136 // ------------------------------------------------------------------------
138 private class TreeContentProvider
implements ITreeContentProvider
{
141 public void dispose() {
145 public void inputChanged(Viewer viewer
, Object oldInput
, Object newInput
) {
149 public Object
[] getElements(Object inputElement
) {
150 return (ITimeGraphEntry
[]) inputElement
;
154 public Object
[] getChildren(Object parentElement
) {
155 ITimeGraphEntry entry
= (ITimeGraphEntry
) parentElement
;
156 return entry
.getChildren();
160 public Object
getParent(Object element
) {
161 ITimeGraphEntry entry
= (ITimeGraphEntry
) element
;
162 return entry
.getParent();
166 public boolean hasChildren(Object element
) {
167 ITimeGraphEntry entry
= (ITimeGraphEntry
) element
;
168 return entry
.hasChildren();
173 private class TreeLabelProvider
implements ITableLabelProvider
{
176 public void addListener(ILabelProviderListener listener
) {
180 public void dispose() {
184 public boolean isLabelProperty(Object element
, String property
) {
189 public void removeListener(ILabelProviderListener listener
) {
193 public Image
getColumnImage(Object element
, int columnIndex
) {
198 public String
getColumnText(Object element
, int columnIndex
) {
199 ControlFlowEntry entry
= (ControlFlowEntry
) element
;
200 if (columnIndex
== 0) {
201 return entry
.getName();
202 } else if (columnIndex
== 1) {
203 return Integer
.toString(entry
.getThreadId());
204 } else if (columnIndex
== 2) {
205 if (entry
.getPPID() > 0) {
206 return Integer
.toString(entry
.getPPID());
208 } else if (columnIndex
== 3) {
209 return Utils
.formatTime(entry
.getBirthTime(), TimeFormat
.ABSOLUTE
, Resolution
.NANOSEC
);
210 } else if (columnIndex
== 4) {
211 return entry
.getTrace().getName();
213 return ""; //$NON-NLS-1$
218 private class ZoomThread
extends Thread
{
219 private long fZoomStartTime
;
220 private long fZoomEndTime
;
221 private long fResolution
;
222 private IProgressMonitor fMonitor
;
224 public ZoomThread(long startTime
, long endTime
) {
225 super("ControlFlowView zoom"); //$NON-NLS-1$
226 fZoomStartTime
= startTime
;
227 fZoomEndTime
= endTime
;
228 fResolution
= Math
.max(1, (fZoomEndTime
- fZoomStartTime
) / fDisplayWidth
);
229 fMonitor
= new NullProgressMonitor();
234 if (fEntryList
== null) {
237 for (ControlFlowEntry entry
: fEntryList
) {
238 if (fMonitor
.isCanceled()) {
241 zoom(entry
, fMonitor
);
246 private void zoom(ControlFlowEntry entry
, IProgressMonitor monitor
) {
247 List
<ITimeEvent
> zoomedEventList
= getEventList(entry
, fZoomStartTime
, fZoomEndTime
, fResolution
, monitor
);
248 if (fMonitor
.isCanceled()) {
251 entry
.setZoomedEventList(zoomedEventList
);
252 for (ControlFlowEntry child
: entry
.getChildren()) {
253 if (fMonitor
.isCanceled()) {
256 zoom(child
, monitor
);
260 public void cancel() {
261 fMonitor
.setCanceled(true);
265 // ------------------------------------------------------------------------
267 // ------------------------------------------------------------------------
269 public ControlFlowView() {
271 fDisplayWidth
= Display
.getDefault().getBounds().width
;
274 // ------------------------------------------------------------------------
276 // ------------------------------------------------------------------------
279 * @see org.eclipse.linuxtools.tmf.ui.views.TmfView#createPartControl(org.eclipse.swt.widgets.Composite)
282 public void createPartControl(Composite parent
) {
283 fTimeGraphCombo
= new TimeGraphCombo(parent
, SWT
.NONE
);
285 fTimeGraphCombo
.setTreeContentProvider(new TreeContentProvider());
287 fTimeGraphCombo
.setTreeLabelProvider(new TreeLabelProvider());
289 fTimeGraphCombo
.setTimeGraphProvider(new TimeGraphPresentationProvider() {
290 private static final String UNKNOWN
= "UNKNOWN"; //$NON-NLS-1$
291 private static final String WAIT
= "WAIT"; //$NON-NLS-1$
292 private static final String USERMODE
= "USERMODE"; //$NON-NLS-1$
293 private static final String SYSCALL
= "SYSCALL"; //$NON-NLS-1$
294 private static final String INTERRUPTED
= "INTERRUPTED"; //$NON-NLS-1$
297 public String
getStateTypeName() {
298 return Messages
.ControlFlowView_stateTypeName
;
302 public StateItem
[] getStateTable() {
303 return new StateItem
[] {
304 new StateItem(new RGB(100, 100, 100), UNKNOWN
),
305 new StateItem(new RGB(200, 200, 0), WAIT
),
306 new StateItem(new RGB(0, 200, 0), USERMODE
),
307 new StateItem(new RGB(0, 0, 200), SYSCALL
),
308 new StateItem(new RGB(200, 100, 100), INTERRUPTED
)
313 public int getStateTableIndex(ITimeEvent event
) {
314 if (event
instanceof ControlFlowEvent
) {
315 int status
= ((ControlFlowEvent
) event
).getStatus();
316 if (status
== Attributes
.STATUS_WAIT
) {
318 } else if (status
== Attributes
.STATUS_RUN_USERMODE
) {
320 } else if (status
== Attributes
.STATUS_RUN_SYSCALL
) {
322 } else if (status
== Attributes
.STATUS_INTERRUPTED
) {
330 public String
getEventName(ITimeEvent event
) {
331 if (event
instanceof ControlFlowEvent
) {
332 int status
= ((ControlFlowEvent
) event
).getStatus();
333 if (status
== Attributes
.STATUS_WAIT
) {
335 } else if (status
== Attributes
.STATUS_RUN_USERMODE
) {
337 } else if (status
== Attributes
.STATUS_RUN_SYSCALL
) {
339 } else if (status
== Attributes
.STATUS_INTERRUPTED
) {
347 public Map
<String
, String
> getEventHoverToolTipInfo(ITimeEvent event
) {
348 Map
<String
, String
> retMap
= new HashMap
<String
, String
>();
349 if (event
instanceof ControlFlowEvent
) {
350 int status
= ((ControlFlowEvent
) event
).getStatus();
351 if (status
== Attributes
.STATUS_RUN_SYSCALL
) {
352 ControlFlowEntry entry
= (ControlFlowEntry
) event
.getEntry();
353 IStateSystemQuerier ssq
= entry
.getTrace().getStateSystem();
355 int syscallQuark
= ssq
.getQuarkRelative(entry
.getThreadQuark(), Attributes
.SYSTEM_CALL
);
356 ITmfStateInterval value
= ssq
.querySingleState(event
.getTime(), syscallQuark
);
357 if (!value
.getStateValue().isNull()) {
358 ITmfStateValue state
= value
.getStateValue();
359 retMap
.put(Messages
.ControlFlowView_attributeSyscallName
, state
.toString());
362 } catch (AttributeNotFoundException e
) {
364 } catch (TimeRangeException e
) {
374 fTimeGraphCombo
.setTreeColumns(COLUMN_NAMES
);
376 fTimeGraphCombo
.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() {
378 public void timeRangeUpdated(TimeGraphRangeUpdateEvent event
) {
379 final long startTime
= event
.getStartTime();
380 final long endTime
= event
.getEndTime();
381 TmfTimeRange range
= new TmfTimeRange(new CtfTmfTimestamp(startTime
), new CtfTmfTimestamp(endTime
));
382 TmfTimestamp time
= new CtfTmfTimestamp(fTimeGraphCombo
.getTimeGraphViewer().getSelectedTime());
383 broadcast(new TmfRangeSynchSignal(ControlFlowView
.this, range
, time
));
384 if (fZoomThread
!= null) {
385 fZoomThread
.cancel();
387 startZoomThread(startTime
, endTime
);
391 fTimeGraphCombo
.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() {
393 public void timeSelected(TimeGraphTimeEvent event
) {
394 long time
= event
.getTime();
395 broadcast(new TmfTimeSynchSignal(ControlFlowView
.this, new CtfTmfTimestamp(time
)));
399 fTimeGraphCombo
.addSelectionListener(new ITimeGraphSelectionListener() {
401 public void selectionChanged(TimeGraphSelectionEvent event
) {
402 //ITimeGraphEntry selection = event.getSelection();
406 fTimeGraphCombo
.getTimeGraphViewer().setTimeCalendarFormat(true);
408 final Thread thread
= new Thread("ControlFlowView build") { //$NON-NLS-1$
411 if (TmfExperiment
.getCurrentExperiment() != null) {
412 selectExperiment(TmfExperiment
.getCurrentExperiment());
418 // View Action Handling
420 contributeToActionBars();
424 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
427 public void setFocus() {
428 fTimeGraphCombo
.setFocus();
431 // ------------------------------------------------------------------------
433 // ------------------------------------------------------------------------
436 public void experimentSelected(final TmfExperimentSelectedSignal
<?
extends ITmfEvent
> signal
) {
437 if (signal
.getExperiment().equals(fSelectedExperiment
)) {
441 final Thread thread
= new Thread("ControlFlowView build") { //$NON-NLS-1$
444 selectExperiment(signal
.getExperiment());
451 public void synchToTime(final TmfTimeSynchSignal signal
) {
452 if (signal
.getSource() == this) {
455 final long time
= signal
.getCurrentTime().normalize(0, -9).getValue();
458 for (ITmfTrace
<?
> trace
: fSelectedExperiment
.getTraces()) {
462 if (trace
instanceof CtfKernelTrace
) {
463 CtfKernelTrace ctfKernelTrace
= (CtfKernelTrace
) trace
;
464 IStateSystemQuerier ssq
= ctfKernelTrace
.getStateSystem();
465 if (time
>= ssq
.getStartTime() && time
<= ssq
.getCurrentEndTime()) {
466 List
<Integer
> currentThreadQuarks
= ssq
.getQuarks(Attributes
.CPUS
, "*", Attributes
.CURRENT_THREAD
); //$NON-NLS-1$
467 for (int currentThreadQuark
: currentThreadQuarks
) {
469 ITmfStateInterval currentThreadInterval
= ssq
.querySingleState(time
, currentThreadQuark
);
470 int currentThread
= currentThreadInterval
.getStateValue().unboxInt();
471 if (currentThread
> 0) {
472 int statusQuark
= ssq
.getQuarkAbsolute(Attributes
.THREADS
, Integer
.toString(currentThread
), Attributes
.STATUS
);
473 ITmfStateInterval statusInterval
= ssq
.querySingleState(time
, statusQuark
);
474 if (statusInterval
.getStartTime() == time
) {
475 thread
= currentThread
;
479 } catch (AttributeNotFoundException e
) {
481 } catch (TimeRangeException e
) {
483 } catch (StateValueTypeException e
) {
490 final int selectedThread
= thread
;
492 Display
.getDefault().asyncExec(new Runnable() {
495 if (fTimeGraphCombo
.isDisposed()) {
498 fTimeGraphCombo
.getTimeGraphViewer().setSelectedTime(time
, true);
499 startZoomThread(fTimeGraphCombo
.getTimeGraphViewer().getTime0(), fTimeGraphCombo
.getTimeGraphViewer().getTime1());
501 if (selectedThread
> 0) {
502 for (Object element
: fTimeGraphCombo
.getTimeGraphViewer().getExpandedElements()) {
503 if (element
instanceof ControlFlowEntry
) {
504 ControlFlowEntry entry
= (ControlFlowEntry
) element
;
505 if (entry
.getThreadId() == selectedThread
) {
506 fTimeGraphCombo
.setSelection(entry
);
516 public void synchToRange(final TmfRangeSynchSignal signal
) {
517 if (signal
.getSource() == this) {
520 final long startTime
= signal
.getCurrentRange().getStartTime().normalize(0, -9).getValue();
521 final long endTime
= signal
.getCurrentRange().getEndTime().normalize(0, -9).getValue();
522 final long time
= signal
.getCurrentTime().normalize(0, -9).getValue();
523 Display
.getDefault().asyncExec(new Runnable() {
526 if (fTimeGraphCombo
.isDisposed()) {
529 fTimeGraphCombo
.getTimeGraphViewer().setStartFinishTime(startTime
, endTime
);
530 fTimeGraphCombo
.getTimeGraphViewer().setSelectedTime(time
, false);
531 startZoomThread(startTime
, endTime
);
536 // ------------------------------------------------------------------------
538 // ------------------------------------------------------------------------
540 @SuppressWarnings("unchecked")
541 private void selectExperiment(TmfExperiment
<?
> experiment
) {
542 fStartTime
= Long
.MAX_VALUE
;
543 fEndTime
= Long
.MIN_VALUE
;
544 fSelectedExperiment
= (TmfExperiment
<ITmfEvent
>) experiment
;
545 fEntryList
= new ArrayList
<ControlFlowEntry
>();
546 for (ITmfTrace
<?
> trace
: experiment
.getTraces()) {
547 if (trace
instanceof CtfKernelTrace
) {
548 CtfKernelTrace ctfKernelTrace
= (CtfKernelTrace
) trace
;
549 IStateSystemQuerier ssq
= ctfKernelTrace
.getStateSystem();
550 long start
= ssq
.getStartTime();
551 long end
= ssq
.getCurrentEndTime();
552 fStartTime
= Math
.min(fStartTime
, start
);
553 fEndTime
= Math
.max(fEndTime
, end
);
554 List
<Integer
> threadQuarks
= ssq
.getQuarks(Attributes
.THREADS
, "*"); //$NON-NLS-1$
555 for (int threadQuark
: threadQuarks
) {
556 String threadName
= ssq
.getAttributeName(threadQuark
);
559 threadId
= Integer
.parseInt(threadName
);
560 } catch (NumberFormatException e1
) {
563 if (threadId
== 0) { // ignore the swapper thread
566 int execNameQuark
= -1;
569 execNameQuark
= ssq
.getQuarkRelative(threadQuark
, Attributes
.EXEC_NAME
);
570 } catch (AttributeNotFoundException e
) {
573 int ppidQuark
= ssq
.getQuarkRelative(threadQuark
, Attributes
.PPID
);
574 List
<ITmfStateInterval
> execNameIntervals
= ssq
.queryHistoryRange(execNameQuark
, start
, end
);
576 for (ITmfStateInterval execNameInterval
: execNameIntervals
) {
577 if (!execNameInterval
.getStateValue().isNull() && execNameInterval
.getStateValue().getType() == 1) {
578 String execName
= execNameInterval
.getStateValue().unboxStr();
579 long startTime
= execNameInterval
.getStartTime();
580 long endTime
= execNameInterval
.getEndTime() + 1;
581 if (birthTime
== -1) {
582 birthTime
= startTime
;
585 if (ppidQuark
!= -1) {
586 ITmfStateInterval ppidInterval
= ssq
.querySingleState(startTime
, ppidQuark
);
587 ppid
= ppidInterval
.getStateValue().unboxInt();
589 ControlFlowEntry entry
= new ControlFlowEntry(threadQuark
, ctfKernelTrace
, execName
, threadId
, ppid
, birthTime
, startTime
, endTime
);
590 fEntryList
.add(entry
);
591 entry
.addEvent(new TimeEvent(entry
, startTime
, endTime
- startTime
));
596 } catch (AttributeNotFoundException e
) {
598 } catch (TimeRangeException e
) {
600 } catch (StateValueTypeException e
) {
606 refresh(INITIAL_WINDOW_OFFSET
);
607 ControlFlowEntry
[] entries
= fEntryList
.toArray(new ControlFlowEntry
[0]);
608 Arrays
.sort(entries
);
609 for (ControlFlowEntry entry
: entries
) {
610 buildStatusEvents(entry
);
615 private void buildTree() {
616 ArrayList
<ControlFlowEntry
> rootList
= new ArrayList
<ControlFlowEntry
>();
617 for (ControlFlowEntry entry
: fEntryList
) {
619 if (entry
.getPPID() > 0) {
620 for (ControlFlowEntry parent
: fEntryList
) {
621 if (parent
.getThreadId() == entry
.getPPID() &&
622 entry
.getStartTime() >= parent
.getStartTime() &&
623 entry
.getStartTime() <= parent
.getEndTime()) {
624 parent
.addChild(entry
);
634 fEntryList
= rootList
;
637 private void buildStatusEvents(ControlFlowEntry entry
) {
638 IStateSystemQuerier ssq
= entry
.getTrace().getStateSystem();
639 long start
= ssq
.getStartTime();
640 long end
= ssq
.getCurrentEndTime();
641 long resolution
= Math
.max(1, (end
- start
) / fDisplayWidth
);
642 List
<ITimeEvent
> eventList
= getEventList(entry
, entry
.getStartTime(), entry
.getEndTime(), resolution
, new NullProgressMonitor());
643 entry
.setEventList(eventList
);
645 for (ITimeGraphEntry child
: entry
.getChildren()) {
646 buildStatusEvents((ControlFlowEntry
) child
);
650 private List
<ITimeEvent
> getEventList(ControlFlowEntry entry
, long startTime
, long endTime
, long resolution
, IProgressMonitor monitor
) {
651 startTime
= Math
.max(startTime
, entry
.getStartTime());
652 endTime
= Math
.min(endTime
, entry
.getEndTime());
653 if (endTime
<= startTime
) {
656 IStateSystemQuerier ssq
= entry
.getTrace().getStateSystem();
657 List
<ITimeEvent
> eventList
= null;
659 int statusQuark
= ssq
.getQuarkRelative(entry
.getThreadQuark(), Attributes
.STATUS
);
660 List
<ITmfStateInterval
> statusIntervals
= ssq
.queryHistoryRange(statusQuark
, startTime
, endTime
- 1, resolution
);
661 eventList
= new ArrayList
<ITimeEvent
>(statusIntervals
.size());
662 long lastEndTime
= -1;
663 for (ITmfStateInterval statusInterval
: statusIntervals
) {
664 if (monitor
.isCanceled()) {
667 long time
= statusInterval
.getStartTime();
668 long duration
= statusInterval
.getEndTime() - time
+ 1;
671 status
= statusInterval
.getStateValue().unboxInt();
672 } catch (StateValueTypeException e
) {
675 if (lastEndTime
!= time
&& lastEndTime
!= -1) {
676 eventList
.add(new ControlFlowEvent(entry
, lastEndTime
, time
- lastEndTime
, 0));
678 eventList
.add(new ControlFlowEvent(entry
, time
, duration
, status
));
679 lastEndTime
= time
+ duration
;
681 } catch (AttributeNotFoundException e
) {
683 } catch (TimeRangeException e
) {
689 private void refresh(final long windowRange
) {
690 Display
.getDefault().asyncExec(new Runnable() {
693 if (fTimeGraphCombo
.isDisposed()) {
696 ITimeGraphEntry
[] entries
= fEntryList
.toArray(new ITimeGraphEntry
[0]);
697 Arrays
.sort(entries
);
698 fTimeGraphCombo
.setInput(entries
);
699 fTimeGraphCombo
.getTimeGraphViewer().setTimeBounds(fStartTime
, fEndTime
);
701 long endTime
= fStartTime
+ windowRange
;
703 if (fEndTime
< endTime
) {
706 fTimeGraphCombo
.getTimeGraphViewer().setStartFinishTime(fStartTime
, endTime
);
707 for (TreeColumn column
: fTimeGraphCombo
.getTreeViewer().getTree().getColumns()) {
711 startZoomThread(fStartTime
, endTime
);
716 private void redraw() {
717 Display
.getDefault().asyncExec(new Runnable() {
720 if (fTimeGraphCombo
.isDisposed()) {
723 fTimeGraphCombo
.redraw();
724 fTimeGraphCombo
.update();
729 private void startZoomThread(long startTime
, long endTime
) {
730 if (fZoomThread
!= null) {
731 fZoomThread
.cancel();
733 fZoomThread
= new ZoomThread(startTime
, endTime
);
737 private void makeActions() {
738 fPreviousResourceAction
= fTimeGraphCombo
.getTimeGraphViewer().getPreviousItemAction();
739 fPreviousResourceAction
.setText(Messages
.ControlFlowView_previousProcessActionNameText
);
740 fPreviousResourceAction
.setToolTipText(Messages
.ControlFlowView_previousProcessActionToolTipText
);
741 fNextResourceAction
= fTimeGraphCombo
.getTimeGraphViewer().getNextItemAction();
742 fNextResourceAction
.setText(Messages
.ControlFlowView_nextProcessActionNameText
);
743 fNextResourceAction
.setToolTipText(Messages
.ControlFlowView_nextProcessActionToolTipText
);
746 private void contributeToActionBars() {
747 IActionBars bars
= getViewSite().getActionBars();
748 fillLocalToolBar(bars
.getToolBarManager());
751 private void fillLocalToolBar(IToolBarManager manager
) {
752 manager
.add(fTimeGraphCombo
.getTimeGraphViewer().getShowLegendAction());
753 manager
.add(new Separator());
754 manager
.add(fTimeGraphCombo
.getTimeGraphViewer().getResetScaleAction());
755 manager
.add(fTimeGraphCombo
.getTimeGraphViewer().getPreviousEventAction());
756 manager
.add(fTimeGraphCombo
.getTimeGraphViewer().getNextEventAction());
757 manager
.add(fPreviousResourceAction
);
758 manager
.add(fNextResourceAction
);
759 manager
.add(fTimeGraphCombo
.getTimeGraphViewer().getZoomInAction());
760 manager
.add(fTimeGraphCombo
.getTimeGraphViewer().getZoomOutAction());
761 manager
.add(new Separator());