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