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