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