Bug 378402: Implementation of ControlFlow view and Resources view for
[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.HashMap;
18 import java.util.List;
19 import java.util.Map;
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.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;
72
73 public class ControlFlowView extends TmfView {
74
75 // ------------------------------------------------------------------------
76 // Constants
77 // ------------------------------------------------------------------------
78
79 /**
80 * View ID.
81 */
82 public static final String ID = "org.eclipse.linuxtools.lttng2.kernel.ui.views.controlflow"; //$NON-NLS-1$
83
84 /**
85 * Initial time range
86 */
87 private static final long INITIAL_WINDOW_OFFSET = (1L * 100 * 1000 * 1000); // .1sec
88
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;
94
95 private final String[] COLUMN_NAMES = new String[] {
96 PROCESS_COLUMN,
97 TID_COLUMN,
98 PPID_COLUMN,
99 BIRTH_TIME_COLUMN,
100 TRACE_COLUMN
101 };
102
103 // ------------------------------------------------------------------------
104 // Fields
105 // ------------------------------------------------------------------------
106
107 // The timegraph combo
108 private TimeGraphCombo fTimeGraphCombo;
109
110 // The selected experiment
111 private TmfExperiment<ITmfEvent> fSelectedExperiment;
112
113 // The timegraph entry list
114 private ArrayList<ControlFlowEntry> fEntryList;
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 // ------------------------------------------------------------------------
135 // Classes
136 // ------------------------------------------------------------------------
137
138 private class TreeContentProvider implements ITreeContentProvider {
139
140 @Override
141 public void dispose() {
142 }
143
144 @Override
145 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
146 }
147
148 @Override
149 public Object[] getElements(Object inputElement) {
150 return (ITimeGraphEntry[]) inputElement;
151 }
152
153 @Override
154 public Object[] getChildren(Object parentElement) {
155 ITimeGraphEntry entry = (ITimeGraphEntry) parentElement;
156 return entry.getChildren();
157 }
158
159 @Override
160 public Object getParent(Object element) {
161 ITimeGraphEntry entry = (ITimeGraphEntry) element;
162 return entry.getParent();
163 }
164
165 @Override
166 public boolean hasChildren(Object element) {
167 ITimeGraphEntry entry = (ITimeGraphEntry) element;
168 return entry.hasChildren();
169 }
170
171 }
172
173 private class TreeLabelProvider implements ITableLabelProvider {
174
175 @Override
176 public void addListener(ILabelProviderListener listener) {
177 }
178
179 @Override
180 public void dispose() {
181 }
182
183 @Override
184 public boolean isLabelProperty(Object element, String property) {
185 return false;
186 }
187
188 @Override
189 public void removeListener(ILabelProviderListener listener) {
190 }
191
192 @Override
193 public Image getColumnImage(Object element, int columnIndex) {
194 return null;
195 }
196
197 @Override
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());
207 }
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();
212 }
213 return ""; //$NON-NLS-1$
214 }
215
216 }
217
218 private class ZoomThread extends Thread {
219 private long fZoomStartTime;
220 private long fZoomEndTime;
221 private long fResolution;
222 private IProgressMonitor fMonitor;
223
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();
230 }
231
232 @Override
233 public void run() {
234 if (fEntryList == null) {
235 return;
236 }
237 for (ControlFlowEntry entry : fEntryList) {
238 if (fMonitor.isCanceled()) {
239 return;
240 }
241 zoom(entry, fMonitor);
242 }
243 redraw();
244 }
245
246 private void zoom(ControlFlowEntry entry, IProgressMonitor monitor) {
247 List<ITimeEvent> zoomedEventList = getEventList(entry, fZoomStartTime, fZoomEndTime, fResolution, monitor);
248 if (fMonitor.isCanceled()) {
249 return;
250 }
251 entry.setZoomedEventList(zoomedEventList);
252 for (ControlFlowEntry child : entry.getChildren()) {
253 if (fMonitor.isCanceled()) {
254 return;
255 }
256 zoom(child, monitor);
257 }
258 }
259
260 public void cancel() {
261 fMonitor.setCanceled(true);
262 }
263 }
264
265 // ------------------------------------------------------------------------
266 // Constructors
267 // ------------------------------------------------------------------------
268
269 public ControlFlowView() {
270 super(ID);
271 fDisplayWidth = Display.getDefault().getBounds().width;
272 }
273
274 // ------------------------------------------------------------------------
275 // ViewPart
276 // ------------------------------------------------------------------------
277
278 /* (non-Javadoc)
279 * @see org.eclipse.linuxtools.tmf.ui.views.TmfView#createPartControl(org.eclipse.swt.widgets.Composite)
280 */
281 @Override
282 public void createPartControl(Composite parent) {
283 fTimeGraphCombo = new TimeGraphCombo(parent, SWT.NONE);
284
285 fTimeGraphCombo.setTreeContentProvider(new TreeContentProvider());
286
287 fTimeGraphCombo.setTreeLabelProvider(new TreeLabelProvider());
288
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$
295
296 @Override
297 public String getStateTypeName() {
298 return Messages.ControlFlowView_stateTypeName;
299 }
300
301 @Override
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)
309 };
310 }
311
312 @Override
313 public int getStateTableIndex(ITimeEvent event) {
314 if (event instanceof ControlFlowEvent) {
315 int status = ((ControlFlowEvent) event).getStatus();
316 if (status == Attributes.STATUS_WAIT) {
317 return 1;
318 } else if (status == Attributes.STATUS_RUN_USERMODE) {
319 return 2;
320 } else if (status == Attributes.STATUS_RUN_SYSCALL) {
321 return 3;
322 } else if (status == Attributes.STATUS_INTERRUPTED) {
323 return 4;
324 }
325 }
326 return 0;
327 }
328
329 @Override
330 public String getEventName(ITimeEvent event) {
331 if (event instanceof ControlFlowEvent) {
332 int status = ((ControlFlowEvent) event).getStatus();
333 if (status == Attributes.STATUS_WAIT) {
334 return WAIT;
335 } else if (status == Attributes.STATUS_RUN_USERMODE) {
336 return USERMODE;
337 } else if (status == Attributes.STATUS_RUN_SYSCALL) {
338 return SYSCALL;
339 } else if (status == Attributes.STATUS_INTERRUPTED) {
340 return INTERRUPTED;
341 }
342 }
343 return UNKNOWN;
344 }
345
346 @Override
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();
354 try {
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());
360 }
361
362 } catch (AttributeNotFoundException e) {
363 e.printStackTrace();
364 } catch (TimeRangeException e) {
365 e.printStackTrace();
366 }
367 }
368 }
369
370 return retMap;
371 }
372 });
373
374 fTimeGraphCombo.setTreeColumns(COLUMN_NAMES);
375
376 fTimeGraphCombo.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() {
377 @Override
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();
386 }
387 startZoomThread(startTime, endTime);
388 }
389 });
390
391 fTimeGraphCombo.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() {
392 @Override
393 public void timeSelected(TimeGraphTimeEvent event) {
394 long time = event.getTime();
395 broadcast(new TmfTimeSynchSignal(ControlFlowView.this, new CtfTmfTimestamp(time)));
396 }
397 });
398
399 fTimeGraphCombo.addSelectionListener(new ITimeGraphSelectionListener() {
400 @Override
401 public void selectionChanged(TimeGraphSelectionEvent event) {
402 //ITimeGraphEntry selection = event.getSelection();
403 }
404 });
405
406 fTimeGraphCombo.getTimeGraphViewer().setTimeCalendarFormat(true);
407
408 final Thread thread = new Thread("ControlFlowView build") { //$NON-NLS-1$
409 @Override
410 public void run() {
411 if (TmfExperiment.getCurrentExperiment() != null) {
412 selectExperiment(TmfExperiment.getCurrentExperiment());
413 }
414 }
415 };
416 thread.start();
417
418 // View Action Handling
419 makeActions();
420 contributeToActionBars();
421 }
422
423 /* (non-Javadoc)
424 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
425 */
426 @Override
427 public void setFocus() {
428 fTimeGraphCombo.setFocus();
429 }
430
431 // ------------------------------------------------------------------------
432 // Signal handlers
433 // ------------------------------------------------------------------------
434
435 @TmfSignalHandler
436 public void experimentSelected(final TmfExperimentSelectedSignal<? extends ITmfEvent> signal) {
437 if (signal.getExperiment().equals(fSelectedExperiment)) {
438 return;
439 }
440
441 final Thread thread = new Thread("ControlFlowView build") { //$NON-NLS-1$
442 @Override
443 public void run() {
444 selectExperiment(signal.getExperiment());
445 }
446 };
447 thread.start();
448 }
449
450 @TmfSignalHandler
451 public void synchToTime(final TmfTimeSynchSignal signal) {
452 if (signal.getSource() == this) {
453 return;
454 }
455 final long time = signal.getCurrentTime().normalize(0, -9).getValue();
456
457 int thread = -1;
458 for (ITmfTrace<?> trace : fSelectedExperiment.getTraces()) {
459 if (thread > 0) {
460 break;
461 }
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) {
468 try {
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;
476 break;
477 }
478 }
479 } catch (AttributeNotFoundException e) {
480 e.printStackTrace();
481 } catch (TimeRangeException e) {
482 e.printStackTrace();
483 } catch (StateValueTypeException e) {
484 e.printStackTrace();
485 }
486 }
487 }
488 }
489 }
490 final int selectedThread = thread;
491
492 Display.getDefault().asyncExec(new Runnable() {
493 @Override
494 public void run() {
495 if (fTimeGraphCombo.isDisposed()) {
496 return;
497 }
498 fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, true);
499 startZoomThread(fTimeGraphCombo.getTimeGraphViewer().getTime0(), fTimeGraphCombo.getTimeGraphViewer().getTime1());
500
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);
507 }
508 }
509 }
510 }
511 }
512 });
513 }
514
515 @TmfSignalHandler
516 public void synchToRange(final TmfRangeSynchSignal signal) {
517 if (signal.getSource() == this) {
518 return;
519 }
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() {
524 @Override
525 public void run() {
526 if (fTimeGraphCombo.isDisposed()) {
527 return;
528 }
529 fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
530 fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, false);
531 startZoomThread(startTime, endTime);
532 }
533 });
534 }
535
536 // ------------------------------------------------------------------------
537 // Internal
538 // ------------------------------------------------------------------------
539
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);
557 int threadId = -1;
558 try {
559 threadId = Integer.parseInt(threadName);
560 } catch (NumberFormatException e1) {
561 continue;
562 }
563 if (threadId == 0) { // ignore the swapper thread
564 continue;
565 }
566 int execNameQuark = -1;
567 try {
568 try {
569 execNameQuark = ssq.getQuarkRelative(threadQuark, Attributes.EXEC_NAME);
570 } catch (AttributeNotFoundException e) {
571 continue;
572 }
573 int ppidQuark = ssq.getQuarkRelative(threadQuark, Attributes.PPID);
574 List<ITmfStateInterval> execNameIntervals = ssq.queryHistoryRange(execNameQuark, start, end);
575 long birthTime = -1;
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;
583 }
584 int ppid = -1;
585 if (ppidQuark != -1) {
586 ITmfStateInterval ppidInterval = ssq.querySingleState(startTime, ppidQuark);
587 ppid = ppidInterval.getStateValue().unboxInt();
588 }
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));
592 } else {
593 birthTime = -1;
594 }
595 }
596 } catch (AttributeNotFoundException e) {
597 e.printStackTrace();
598 } catch (TimeRangeException e) {
599 e.printStackTrace();
600 } catch (StateValueTypeException e) {
601 e.printStackTrace();
602 }
603 }
604 }
605 buildTree();
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);
611 }
612 }
613 }
614
615 private void buildTree() {
616 ArrayList<ControlFlowEntry> rootList = new ArrayList<ControlFlowEntry>();
617 for (ControlFlowEntry entry : fEntryList) {
618 boolean root = true;
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);
625 root = false;
626 break;
627 }
628 }
629 }
630 if (root) {
631 rootList.add(entry);
632 }
633 }
634 fEntryList = rootList;
635 }
636
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);
644 redraw();
645 for (ITimeGraphEntry child : entry.getChildren()) {
646 buildStatusEvents((ControlFlowEntry) child);
647 }
648 }
649
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) {
654 return null;
655 }
656 IStateSystemQuerier ssq = entry.getTrace().getStateSystem();
657 List<ITimeEvent> eventList = null;
658 try {
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()) {
665 return null;
666 }
667 long time = statusInterval.getStartTime();
668 long duration = statusInterval.getEndTime() - time + 1;
669 int status = -1;
670 try {
671 status = statusInterval.getStateValue().unboxInt();
672 } catch (StateValueTypeException e) {
673 e.printStackTrace();
674 }
675 if (lastEndTime != time && lastEndTime != -1) {
676 eventList.add(new ControlFlowEvent(entry, lastEndTime, time - lastEndTime, 0));
677 }
678 eventList.add(new ControlFlowEvent(entry, time, duration, status));
679 lastEndTime = time + duration;
680 }
681 } catch (AttributeNotFoundException e) {
682 e.printStackTrace();
683 } catch (TimeRangeException e) {
684 e.printStackTrace();
685 }
686 return eventList;
687 }
688
689 private void refresh(final long windowRange) {
690 Display.getDefault().asyncExec(new Runnable() {
691 @Override
692 public void run() {
693 if (fTimeGraphCombo.isDisposed()) {
694 return;
695 }
696 ITimeGraphEntry[] entries = fEntryList.toArray(new ITimeGraphEntry[0]);
697 Arrays.sort(entries);
698 fTimeGraphCombo.setInput(entries);
699 fTimeGraphCombo.getTimeGraphViewer().setTimeBounds(fStartTime, fEndTime);
700
701 long endTime = fStartTime + windowRange;
702
703 if (fEndTime < endTime) {
704 endTime = fEndTime;
705 }
706 fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(fStartTime, endTime);
707 for (TreeColumn column : fTimeGraphCombo.getTreeViewer().getTree().getColumns()) {
708 column.pack();
709 }
710
711 startZoomThread(fStartTime, endTime);
712 }
713 });
714 }
715
716 private void redraw() {
717 Display.getDefault().asyncExec(new Runnable() {
718 @Override
719 public void run() {
720 if (fTimeGraphCombo.isDisposed()) {
721 return;
722 }
723 fTimeGraphCombo.redraw();
724 fTimeGraphCombo.update();
725 }
726 });
727 }
728
729 private void startZoomThread(long startTime, long endTime) {
730 if (fZoomThread != null) {
731 fZoomThread.cancel();
732 }
733 fZoomThread = new ZoomThread(startTime, endTime);
734 fZoomThread.start();
735 }
736
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);
744 }
745
746 private void contributeToActionBars() {
747 IActionBars bars = getViewSite().getActionBars();
748 fillLocalToolBar(bars.getToolBarManager());
749 }
750
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());
762 }
763 }
This page took 0.048083 seconds and 6 git commands to generate.