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