Fix for bug 382529: ConcurrentModificationException in Control Flow
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng2.kernel.ui / src / org / eclipse / linuxtools / internal / lttng2 / kernel / ui / views / controlflow / ControlFlowView.java
1 /*******************************************************************************
2 * Copyright (c) 2012 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.internal.lttng2.kernel.ui.views.controlflow;
14
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.Collections;
18 import java.util.Comparator;
19 import java.util.List;
20
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.core.Attributes;
31 import org.eclipse.linuxtools.internal.lttng2.kernel.ui.Messages;
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.TmfStateSystemBuildCompleted;
45 import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;
46 import org.eclipse.linuxtools.tmf.core.statesystem.IStateSystemQuerier;
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.TimeGraphCombo;
54 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent;
55 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphSelectionEvent;
56 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTimeEvent;
57 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent;
58 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
59 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeEvent;
60 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils;
61 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.Resolution;
62 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
63 import org.eclipse.swt.SWT;
64 import org.eclipse.swt.graphics.Image;
65 import org.eclipse.swt.widgets.Composite;
66 import org.eclipse.swt.widgets.Display;
67 import org.eclipse.swt.widgets.TreeColumn;
68 import org.eclipse.ui.IActionBars;
69
70 public class ControlFlowView extends TmfView {
71
72 // ------------------------------------------------------------------------
73 // Constants
74 // ------------------------------------------------------------------------
75
76 /**
77 * View ID.
78 */
79 public static final String ID = "org.eclipse.linuxtools.lttng2.kernel.ui.views.controlflow"; //$NON-NLS-1$
80
81 /**
82 * Initial time range
83 */
84 private static final long INITIAL_WINDOW_OFFSET = (1L * 100 * 1000 * 1000); // .1sec
85
86 private static final String PROCESS_COLUMN = Messages.ControlFlowView_processColumn;
87 private static final String TID_COLUMN = Messages.ControlFlowView_tidColumn;
88 private static final String PTID_COLUMN = Messages.ControlFlowView_ptidColumn;
89 private static final String BIRTH_TIME_COLUMN = Messages.ControlFlowView_birthTimeColumn;
90 private static final String TRACE_COLUMN = Messages.ControlFlowView_traceColumn;
91
92 private final String[] COLUMN_NAMES = new String[] {
93 PROCESS_COLUMN,
94 TID_COLUMN,
95 PTID_COLUMN,
96 BIRTH_TIME_COLUMN,
97 TRACE_COLUMN
98 };
99
100 // ------------------------------------------------------------------------
101 // Fields
102 // ------------------------------------------------------------------------
103
104 // The timegraph combo
105 private TimeGraphCombo fTimeGraphCombo;
106
107 // The selected experiment
108 private TmfExperiment<ITmfEvent> fSelectedExperiment;
109
110 // The timegraph entry list
111 private ArrayList<ControlFlowEntry> fEntryList;
112
113 // The time graph entry list synchronization object
114 final private Object fEntryListSyncObj = new Object();
115
116 // The start time
117 private long fStartTime;
118
119 // The end time
120 private long fEndTime;
121
122 // The display width
123 private int fDisplayWidth;
124
125 // The zoom thread
126 private ZoomThread fZoomThread;
127
128 // The next resource action
129 private Action fNextResourceAction;
130
131 // The previous resource action
132 private Action fPreviousResourceAction;
133
134 // A comparator class
135 private ControlFlowEntryComparator fControlFlowEntryComparator = new ControlFlowEntryComparator();
136
137 // ------------------------------------------------------------------------
138 // Classes
139 // ------------------------------------------------------------------------
140
141 private class TreeContentProvider implements ITreeContentProvider {
142
143 @Override
144 public void dispose() {
145 }
146
147 @Override
148 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
149 }
150
151 @Override
152 public Object[] getElements(Object inputElement) {
153 return (ITimeGraphEntry[]) inputElement;
154 }
155
156 @Override
157 public Object[] getChildren(Object parentElement) {
158 ITimeGraphEntry entry = (ITimeGraphEntry) parentElement;
159 return entry.getChildren();
160 }
161
162 @Override
163 public Object getParent(Object element) {
164 ITimeGraphEntry entry = (ITimeGraphEntry) element;
165 return entry.getParent();
166 }
167
168 @Override
169 public boolean hasChildren(Object element) {
170 ITimeGraphEntry entry = (ITimeGraphEntry) element;
171 return entry.hasChildren();
172 }
173
174 }
175
176 private class TreeLabelProvider implements ITableLabelProvider {
177
178 @Override
179 public void addListener(ILabelProviderListener listener) {
180 }
181
182 @Override
183 public void dispose() {
184 }
185
186 @Override
187 public boolean isLabelProperty(Object element, String property) {
188 return false;
189 }
190
191 @Override
192 public void removeListener(ILabelProviderListener listener) {
193 }
194
195 @Override
196 public Image getColumnImage(Object element, int columnIndex) {
197 return null;
198 }
199
200 @Override
201 public String getColumnText(Object element, int columnIndex) {
202 ControlFlowEntry entry = (ControlFlowEntry) element;
203 if (columnIndex == 0) {
204 return entry.getName();
205 } else if (columnIndex == 1) {
206 return Integer.toString(entry.getThreadId());
207 } else if (columnIndex == 2) {
208 if (entry.getParentThreadId() > 0) {
209 return Integer.toString(entry.getParentThreadId());
210 }
211 } else if (columnIndex == 3) {
212 return Utils.formatTime(entry.getBirthTime(), TimeFormat.ABSOLUTE, Resolution.NANOSEC);
213 } else if (columnIndex == 4) {
214 return entry.getTrace().getName();
215 }
216 return ""; //$NON-NLS-1$
217 }
218
219 }
220
221 private static class ControlFlowEntryComparator implements Comparator<ITimeGraphEntry> {
222
223 @Override
224 public int compare(ITimeGraphEntry o1, ITimeGraphEntry o2) {
225 int result = 0;
226
227 if ((o1 instanceof ControlFlowEntry) && (o2 instanceof ControlFlowEntry)) {
228 ControlFlowEntry entry1 = (ControlFlowEntry) o1;
229 ControlFlowEntry entry2 = (ControlFlowEntry) o2;
230 result = entry1.getTrace().getStartTime().compareTo(entry2.getTrace().getStartTime());
231 if (result == 0) {
232 result = entry1.getTrace().getName().compareTo(entry2.getTrace().getName());
233 }
234 if (result == 0) {
235 result = entry1.getThreadId() < entry2.getThreadId() ? -1 : entry1.getThreadId() > entry2.getThreadId() ? 1 : 0;
236 }
237 }
238
239 if (result == 0) {
240 result = o1.getStartTime() < o2.getStartTime() ? -1 : o1.getStartTime() > o2.getStartTime() ? 1 : 0;
241 }
242
243 return result;
244 }
245 }
246
247
248 private class ZoomThread extends Thread {
249 private long fZoomStartTime;
250 private long fZoomEndTime;
251 private long fResolution;
252 private IProgressMonitor fMonitor;
253
254 public ZoomThread(long startTime, long endTime) {
255 super("ControlFlowView zoom"); //$NON-NLS-1$
256 fZoomStartTime = startTime;
257 fZoomEndTime = endTime;
258 fResolution = Math.max(1, (fZoomEndTime - fZoomStartTime) / fDisplayWidth);
259 fMonitor = new NullProgressMonitor();
260 }
261
262 @Override
263 public void run() {
264 ArrayList<ControlFlowEntry> entryList = null;
265 synchronized (fEntryListSyncObj) {
266 entryList = fEntryList;
267 }
268 if (entryList == null) {
269 return;
270 }
271 for (ControlFlowEntry entry : entryList) {
272 if (fMonitor.isCanceled()) {
273 break;
274 }
275 zoom(entry, fMonitor);
276 }
277 redraw();
278 }
279
280 private void zoom(ControlFlowEntry entry, IProgressMonitor monitor) {
281 if (fZoomStartTime <= fStartTime && fZoomEndTime >= fEndTime) {
282 entry.setZoomedEventList(null);
283 } else {
284 List<ITimeEvent> zoomedEventList = getEventList(entry, fZoomStartTime, fZoomEndTime, fResolution, monitor);
285 if (zoomedEventList != null) {
286 entry.setZoomedEventList(zoomedEventList);
287 }
288 }
289 for (ControlFlowEntry child : entry.getChildren()) {
290 if (fMonitor.isCanceled()) {
291 return;
292 }
293 zoom(child, monitor);
294 }
295 }
296
297 public void cancel() {
298 fMonitor.setCanceled(true);
299 }
300 }
301
302 // ------------------------------------------------------------------------
303 // Constructors
304 // ------------------------------------------------------------------------
305
306 public ControlFlowView() {
307 super(ID);
308 fDisplayWidth = Display.getDefault().getBounds().width;
309 }
310
311 // ------------------------------------------------------------------------
312 // ViewPart
313 // ------------------------------------------------------------------------
314
315 /* (non-Javadoc)
316 * @see org.eclipse.linuxtools.tmf.ui.views.TmfView#createPartControl(org.eclipse.swt.widgets.Composite)
317 */
318 @Override
319 public void createPartControl(Composite parent) {
320 fTimeGraphCombo = new TimeGraphCombo(parent, SWT.NONE);
321
322 fTimeGraphCombo.setTreeContentProvider(new TreeContentProvider());
323
324 fTimeGraphCombo.setTreeLabelProvider(new TreeLabelProvider());
325
326 fTimeGraphCombo.setTimeGraphProvider(new ControlFlowPresentationProvider());
327
328 fTimeGraphCombo.setTreeColumns(COLUMN_NAMES);
329
330 fTimeGraphCombo.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() {
331 @Override
332 public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) {
333 final long startTime = event.getStartTime();
334 final long endTime = event.getEndTime();
335 TmfTimeRange range = new TmfTimeRange(new CtfTmfTimestamp(startTime), new CtfTmfTimestamp(endTime));
336 TmfTimestamp time = new CtfTmfTimestamp(fTimeGraphCombo.getTimeGraphViewer().getSelectedTime());
337 broadcast(new TmfRangeSynchSignal(ControlFlowView.this, range, time));
338 if (fZoomThread != null) {
339 fZoomThread.cancel();
340 }
341 startZoomThread(startTime, endTime);
342 }
343 });
344
345 fTimeGraphCombo.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() {
346 @Override
347 public void timeSelected(TimeGraphTimeEvent event) {
348 long time = event.getTime();
349 broadcast(new TmfTimeSynchSignal(ControlFlowView.this, new CtfTmfTimestamp(time)));
350 }
351 });
352
353 fTimeGraphCombo.addSelectionListener(new ITimeGraphSelectionListener() {
354 @Override
355 public void selectionChanged(TimeGraphSelectionEvent event) {
356 //ITimeGraphEntry selection = event.getSelection();
357 }
358 });
359
360 fTimeGraphCombo.getTimeGraphViewer().setTimeCalendarFormat(true);
361
362 final Thread thread = new Thread("ControlFlowView build") { //$NON-NLS-1$
363 @Override
364 public void run() {
365 if (TmfExperiment.getCurrentExperiment() != null) {
366 selectExperiment(TmfExperiment.getCurrentExperiment());
367 }
368 }
369 };
370 thread.start();
371
372 // View Action Handling
373 makeActions();
374 contributeToActionBars();
375 }
376
377 /* (non-Javadoc)
378 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
379 */
380 @Override
381 public void setFocus() {
382 fTimeGraphCombo.setFocus();
383 }
384
385 // ------------------------------------------------------------------------
386 // Signal handlers
387 // ------------------------------------------------------------------------
388
389 @TmfSignalHandler
390 public void experimentSelected(final TmfExperimentSelectedSignal<? extends ITmfEvent> signal) {
391 if (signal.getExperiment().equals(fSelectedExperiment)) {
392 return;
393 }
394
395 final Thread thread = new Thread("ControlFlowView build") { //$NON-NLS-1$
396 @Override
397 public void run() {
398 selectExperiment(signal.getExperiment());
399 }
400 };
401 thread.start();
402 }
403
404 @TmfSignalHandler
405 public void synchToTime(final TmfTimeSynchSignal signal) {
406 if (signal.getSource() == this || fSelectedExperiment == null) {
407 return;
408 }
409 final long time = signal.getCurrentTime().normalize(0, -9).getValue();
410
411 int thread = -1;
412 for (ITmfTrace<?> trace : fSelectedExperiment.getTraces()) {
413 if (thread > 0) {
414 break;
415 }
416 if (trace instanceof CtfKernelTrace) {
417 CtfKernelTrace ctfKernelTrace = (CtfKernelTrace) trace;
418 IStateSystemQuerier ssq = ctfKernelTrace.getStateSystem();
419 if (time >= ssq.getStartTime() && time <= ssq.getCurrentEndTime()) {
420 List<Integer> currentThreadQuarks = ssq.getQuarks(Attributes.CPUS, "*", Attributes.CURRENT_THREAD); //$NON-NLS-1$
421 for (int currentThreadQuark : currentThreadQuarks) {
422 try {
423 ITmfStateInterval currentThreadInterval = ssq.querySingleState(time, currentThreadQuark);
424 int currentThread = currentThreadInterval.getStateValue().unboxInt();
425 if (currentThread > 0) {
426 int statusQuark = ssq.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThread), Attributes.STATUS);
427 ITmfStateInterval statusInterval = ssq.querySingleState(time, statusQuark);
428 if (statusInterval.getStartTime() == time) {
429 thread = currentThread;
430 break;
431 }
432 }
433 } catch (AttributeNotFoundException e) {
434 e.printStackTrace();
435 } catch (TimeRangeException e) {
436 e.printStackTrace();
437 } catch (StateValueTypeException e) {
438 e.printStackTrace();
439 }
440 }
441 }
442 }
443 }
444 final int selectedThread = thread;
445
446 Display.getDefault().asyncExec(new Runnable() {
447 @Override
448 public void run() {
449 if (fTimeGraphCombo.isDisposed()) {
450 return;
451 }
452 fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, true);
453 startZoomThread(fTimeGraphCombo.getTimeGraphViewer().getTime0(), fTimeGraphCombo.getTimeGraphViewer().getTime1());
454
455 if (selectedThread > 0) {
456 for (Object element : fTimeGraphCombo.getTimeGraphViewer().getExpandedElements()) {
457 if (element instanceof ControlFlowEntry) {
458 ControlFlowEntry entry = (ControlFlowEntry) element;
459 if (entry.getThreadId() == selectedThread) {
460 fTimeGraphCombo.setSelection(entry);
461 break;
462 }
463 }
464 }
465 }
466 }
467 });
468 }
469
470 @TmfSignalHandler
471 public void synchToRange(final TmfRangeSynchSignal signal) {
472 if (signal.getSource() == this || fSelectedExperiment == null) {
473 return;
474 }
475 final long startTime = signal.getCurrentRange().getStartTime().normalize(0, -9).getValue();
476 final long endTime = signal.getCurrentRange().getEndTime().normalize(0, -9).getValue();
477 final long time = signal.getCurrentTime().normalize(0, -9).getValue();
478 Display.getDefault().asyncExec(new Runnable() {
479 @Override
480 public void run() {
481 if (fTimeGraphCombo.isDisposed()) {
482 return;
483 }
484 fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
485 fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, false);
486 startZoomThread(startTime, endTime);
487 }
488 });
489 }
490
491 @TmfSignalHandler
492 public void stateSystemBuildCompleted (final TmfStateSystemBuildCompleted signal) {
493 final TmfExperiment<?> selectedExperiment = fSelectedExperiment;
494 if (selectedExperiment == null) {
495 return;
496 }
497 for (ITmfTrace<?> trace : selectedExperiment.getTraces()) {
498 if (trace == signal.getTrace() && trace instanceof CtfKernelTrace) {
499 final Thread thread = new Thread("ControlFlowView build") { //$NON-NLS-1$
500 @Override
501 public void run() {
502 // rebuild the model
503 selectExperiment(selectedExperiment);
504 }
505 };
506 thread.start();
507 }
508 }
509 }
510
511 // ------------------------------------------------------------------------
512 // Internal
513 // ------------------------------------------------------------------------
514
515 @SuppressWarnings("unchecked")
516 private void selectExperiment(TmfExperiment<?> experiment) {
517 fStartTime = Long.MAX_VALUE;
518 fEndTime = Long.MIN_VALUE;
519 fSelectedExperiment = (TmfExperiment<ITmfEvent>) experiment;
520 ArrayList<ControlFlowEntry> rootList = new ArrayList<ControlFlowEntry>();
521 for (ITmfTrace<?> trace : experiment.getTraces()) {
522 if (trace instanceof CtfKernelTrace) {
523 ArrayList<ControlFlowEntry> entryList = new ArrayList<ControlFlowEntry>();
524 CtfKernelTrace ctfKernelTrace = (CtfKernelTrace) trace;
525 IStateSystemQuerier ssq = ctfKernelTrace.getStateSystem();
526 long start = ssq.getStartTime();
527 long end = ssq.getCurrentEndTime() + 1;
528 fStartTime = Math.min(fStartTime, start);
529 fEndTime = Math.max(fEndTime, end);
530 List<Integer> threadQuarks = ssq.getQuarks(Attributes.THREADS, "*"); //$NON-NLS-1$
531 for (int threadQuark : threadQuarks) {
532 String threadName = ssq.getAttributeName(threadQuark);
533 int threadId = -1;
534 try {
535 threadId = Integer.parseInt(threadName);
536 } catch (NumberFormatException e1) {
537 continue;
538 }
539 if (threadId == 0) { // ignore the swapper thread
540 continue;
541 }
542 int execNameQuark = -1;
543 try {
544 try {
545 execNameQuark = ssq.getQuarkRelative(threadQuark, Attributes.EXEC_NAME);
546 } catch (AttributeNotFoundException e) {
547 continue;
548 }
549 int ppidQuark = ssq.getQuarkRelative(threadQuark, Attributes.PPID);
550 List<ITmfStateInterval> execNameIntervals = ssq.queryHistoryRange(execNameQuark, start, end - 1);
551 long birthTime = -1;
552 for (ITmfStateInterval execNameInterval : execNameIntervals) {
553 if (!execNameInterval.getStateValue().isNull() && execNameInterval.getStateValue().getType() == 1) {
554 String execName = execNameInterval.getStateValue().unboxStr();
555 long startTime = execNameInterval.getStartTime();
556 long endTime = execNameInterval.getEndTime() + 1;
557 if (birthTime == -1) {
558 birthTime = startTime;
559 }
560 int ppid = -1;
561 if (ppidQuark != -1) {
562 ITmfStateInterval ppidInterval = ssq.querySingleState(startTime, ppidQuark);
563 ppid = ppidInterval.getStateValue().unboxInt();
564 }
565 ControlFlowEntry entry = new ControlFlowEntry(threadQuark, ctfKernelTrace, execName, threadId, ppid, birthTime, startTime, endTime);
566 entryList.add(entry);
567 entry.addEvent(new TimeEvent(entry, startTime, endTime - startTime));
568 } else {
569 birthTime = -1;
570 }
571 }
572 } catch (AttributeNotFoundException e) {
573 e.printStackTrace();
574 } catch (TimeRangeException e) {
575 e.printStackTrace();
576 } catch (StateValueTypeException e) {
577 e.printStackTrace();
578 }
579 }
580 buildTree(entryList, rootList);
581 }
582 Collections.sort(rootList, fControlFlowEntryComparator);
583 synchronized (fEntryListSyncObj) {
584 fEntryList = (ArrayList<ControlFlowEntry>) rootList.clone();
585 }
586 refresh(INITIAL_WINDOW_OFFSET);
587 }
588 for (ControlFlowEntry entry : rootList) {
589 buildStatusEvents(entry);
590 }
591 }
592
593 private void buildTree(ArrayList<ControlFlowEntry> entryList, ArrayList<ControlFlowEntry> rootList) {
594 for (ControlFlowEntry entry : entryList) {
595 boolean root = true;
596 if (entry.getParentThreadId() > 0) {
597 for (ControlFlowEntry parent : entryList) {
598 if (parent.getThreadId() == entry.getParentThreadId() &&
599 entry.getStartTime() >= parent.getStartTime() &&
600 entry.getStartTime() <= parent.getEndTime()) {
601 parent.addChild(entry);
602 root = false;
603 break;
604 }
605 }
606 }
607 if (root) {
608 rootList.add(entry);
609 }
610 }
611 }
612
613 private void buildStatusEvents(ControlFlowEntry entry) {
614 IStateSystemQuerier ssq = entry.getTrace().getStateSystem();
615 long start = ssq.getStartTime();
616 long end = ssq.getCurrentEndTime() + 1;
617 long resolution = Math.max(1, (end - start) / fDisplayWidth);
618 List<ITimeEvent> eventList = getEventList(entry, entry.getStartTime(), entry.getEndTime(), resolution, new NullProgressMonitor());
619 entry.setEventList(eventList);
620 redraw();
621 for (ITimeGraphEntry child : entry.getChildren()) {
622 buildStatusEvents((ControlFlowEntry) child);
623 }
624 }
625
626 private List<ITimeEvent> getEventList(ControlFlowEntry entry, long startTime, long endTime, long resolution, IProgressMonitor monitor) {
627 startTime = Math.max(startTime, entry.getStartTime());
628 endTime = Math.min(endTime, entry.getEndTime());
629 if (endTime <= startTime) {
630 return null;
631 }
632 IStateSystemQuerier ssq = entry.getTrace().getStateSystem();
633 List<ITimeEvent> eventList = null;
634 try {
635 int statusQuark = ssq.getQuarkRelative(entry.getThreadQuark(), Attributes.STATUS);
636 List<ITmfStateInterval> statusIntervals = ssq.queryHistoryRange(statusQuark, startTime, endTime - 1, resolution);
637 eventList = new ArrayList<ITimeEvent>(statusIntervals.size());
638 long lastEndTime = -1;
639 for (ITmfStateInterval statusInterval : statusIntervals) {
640 if (monitor.isCanceled()) {
641 return null;
642 }
643 long time = statusInterval.getStartTime();
644 long duration = statusInterval.getEndTime() - time + 1;
645 int status = -1;
646 try {
647 status = statusInterval.getStateValue().unboxInt();
648 } catch (StateValueTypeException e) {
649 e.printStackTrace();
650 }
651 if (lastEndTime != time && lastEndTime != -1) {
652 eventList.add(new ControlFlowEvent(entry, lastEndTime, time - lastEndTime, 0));
653 }
654 eventList.add(new ControlFlowEvent(entry, time, duration, status));
655 lastEndTime = time + duration;
656 }
657 } catch (AttributeNotFoundException e) {
658 e.printStackTrace();
659 } catch (TimeRangeException e) {
660 e.printStackTrace();
661 }
662 return eventList;
663 }
664
665 private void refresh(final long windowRange) {
666 Display.getDefault().asyncExec(new Runnable() {
667 @Override
668 public void run() {
669 if (fTimeGraphCombo.isDisposed()) {
670 return;
671 }
672 ITimeGraphEntry[] entries = null;
673 synchronized (fEntryListSyncObj) {
674 entries = fEntryList.toArray(new ITimeGraphEntry[0]);
675 }
676 Arrays.sort(entries, fControlFlowEntryComparator);
677 fTimeGraphCombo.setInput(entries);
678 fTimeGraphCombo.getTimeGraphViewer().setTimeBounds(fStartTime, fEndTime);
679
680 long endTime = fStartTime + windowRange;
681
682 if (fEndTime < endTime) {
683 endTime = fEndTime;
684 }
685 fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(fStartTime, endTime);
686 for (TreeColumn column : fTimeGraphCombo.getTreeViewer().getTree().getColumns()) {
687 column.pack();
688 }
689
690 startZoomThread(fStartTime, endTime);
691 }
692 });
693 }
694
695 private void redraw() {
696 Display.getDefault().asyncExec(new Runnable() {
697 @Override
698 public void run() {
699 if (fTimeGraphCombo.isDisposed()) {
700 return;
701 }
702 fTimeGraphCombo.redraw();
703 fTimeGraphCombo.update();
704 }
705 });
706 }
707
708 private void startZoomThread(long startTime, long endTime) {
709 if (fZoomThread != null) {
710 fZoomThread.cancel();
711 }
712 fZoomThread = new ZoomThread(startTime, endTime);
713 fZoomThread.start();
714 }
715
716 private void makeActions() {
717 fPreviousResourceAction = fTimeGraphCombo.getTimeGraphViewer().getPreviousItemAction();
718 fPreviousResourceAction.setText(Messages.ControlFlowView_previousProcessActionNameText);
719 fPreviousResourceAction.setToolTipText(Messages.ControlFlowView_previousProcessActionToolTipText);
720 fNextResourceAction = fTimeGraphCombo.getTimeGraphViewer().getNextItemAction();
721 fNextResourceAction.setText(Messages.ControlFlowView_nextProcessActionNameText);
722 fNextResourceAction.setToolTipText(Messages.ControlFlowView_nextProcessActionToolTipText);
723 }
724
725 private void contributeToActionBars() {
726 IActionBars bars = getViewSite().getActionBars();
727 fillLocalToolBar(bars.getToolBarManager());
728 }
729
730 private void fillLocalToolBar(IToolBarManager manager) {
731 manager.add(fTimeGraphCombo.getTimeGraphViewer().getShowLegendAction());
732 manager.add(new Separator());
733 manager.add(fTimeGraphCombo.getTimeGraphViewer().getResetScaleAction());
734 manager.add(fTimeGraphCombo.getTimeGraphViewer().getPreviousEventAction());
735 manager.add(fTimeGraphCombo.getTimeGraphViewer().getNextEventAction());
736 manager.add(fPreviousResourceAction);
737 manager.add(fNextResourceAction);
738 manager.add(fTimeGraphCombo.getTimeGraphViewer().getZoomInAction());
739 manager.add(fTimeGraphCombo.getTimeGraphViewer().getZoomOutAction());
740 manager.add(new Separator());
741 }
742 }
This page took 0.049082 seconds and 6 git commands to generate.