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