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