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