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
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
21import org.eclipse.core.runtime.IProgressMonitor;\r
22import org.eclipse.core.runtime.NullProgressMonitor;\r
23import org.eclipse.jface.action.Action;\r
24import org.eclipse.jface.action.IToolBarManager;\r
25import org.eclipse.jface.action.Separator;\r
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
33import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTimestamp;\r
34import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;\r
35import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;\r
36import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;\r
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
40import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;\r
41import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentSelectedSignal;\r
42import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;\r
43import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;\r
44import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;\r
45import org.eclipse.linuxtools.tmf.core.statesystem.IStateSystemQuerier;\r
46import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;\r
47import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;\r
48import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment;\r
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
53import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.StateItem;\r
54import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphCombo;\r
55import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider;\r
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
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
65import org.eclipse.swt.SWT;\r
66import org.eclipse.swt.graphics.Image;\r
67import org.eclipse.swt.graphics.RGB;\r
68import org.eclipse.swt.widgets.Composite;\r
69import org.eclipse.swt.widgets.Display;\r
70import org.eclipse.swt.widgets.TreeColumn;\r
71import org.eclipse.ui.IActionBars;\r
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
84 /**\r
85 * Initial time range\r
86 */\r
87 private static final long INITIAL_WINDOW_OFFSET = (1L * 100 * 1000 * 1000); // .1sec\r
88\r
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
94\r
95 private final String[] COLUMN_NAMES = new String[] {\r
96 PROCESS_COLUMN,\r
97 TID_COLUMN,\r
98 PPID_COLUMN,\r
99 BIRTH_TIME_COLUMN,\r
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
114 private ArrayList<ControlFlowEntry> fEntryList;\r
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
122 // The display width\r
123 private int fDisplayWidth;\r
124\r
125 // The zoom thread\r
126 private ZoomThread fZoomThread;\r
127\r
128 // The next resource action\r
129 private Action fNextResourceAction;\r
130\r
131 // The previous resource action\r
132 private Action fPreviousResourceAction;\r
133\r
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
170\r
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
204 } else if (columnIndex == 2) {\r
205 if (entry.getPPID() > 0) {\r
206 return Integer.toString(entry.getPPID());\r
207 }\r
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
212 }\r
213 return ""; //$NON-NLS-1$\r
214 }\r
215\r
216 }\r
217\r
218 private class ZoomThread extends Thread {\r
219 private long fZoomStartTime;\r
220 private long fZoomEndTime;\r
221 private long fResolution;\r
222 private IProgressMonitor fMonitor;\r
223\r
224 public ZoomThread(long startTime, long endTime) {\r
225 super("ControlFlowView zoom"); //$NON-NLS-1$\r
226 fZoomStartTime = startTime;\r
227 fZoomEndTime = endTime;\r
228 fResolution = Math.max(1, (fZoomEndTime - fZoomStartTime) / fDisplayWidth);\r
229 fMonitor = new NullProgressMonitor();\r
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
238 if (fMonitor.isCanceled()) {\r
239 return;\r
240 }\r
241 zoom(entry, fMonitor);\r
242 }\r
243 redraw();\r
244 }\r
245\r
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
251 entry.setZoomedEventList(zoomedEventList);\r
252 for (ControlFlowEntry child : entry.getChildren()) {\r
253 if (fMonitor.isCanceled()) {\r
254 return;\r
255 }\r
256 zoom(child, monitor);\r
257 }\r
258 }\r
259\r
260 public void cancel() {\r
261 fMonitor.setCanceled(true);\r
262 }\r
263 }\r
264\r
265 // ------------------------------------------------------------------------\r
266 // Constructors\r
267 // ------------------------------------------------------------------------\r
268\r
269 public ControlFlowView() {\r
270 super(ID);\r
271 fDisplayWidth = Display.getDefault().getBounds().width;\r
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
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
299 }\r
300\r
301 @Override\r
302 public StateItem[] getStateTable() {\r
303 return new StateItem[] {\r
304 new StateItem(new RGB(100, 100, 100), UNKNOWN),\r
305 new StateItem(new RGB(200, 200, 0), WAIT),\r
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
310 }\r
311\r
312 @Override\r
313 public int getStateTableIndex(ITimeEvent event) {\r
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
327 }\r
328\r
329 @Override\r
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
344 }\r
345\r
346 @Override\r
347 public Map<String, String> getEventHoverToolTipInfo(ITimeEvent event) {\r
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
361\r
362 } catch (AttributeNotFoundException e) {\r
363 e.printStackTrace();\r
364 } catch (TimeRangeException e) {\r
365 e.printStackTrace();\r
366 }\r
367 } \r
368 }\r
369\r
370 return retMap;\r
371 }\r
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
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
387 startZoomThread(startTime, endTime);\r
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
395 broadcast(new TmfTimeSynchSignal(ControlFlowView.this, new CtfTmfTimestamp(time)));\r
396 }\r
397 });\r
398\r
399 fTimeGraphCombo.addSelectionListener(new ITimeGraphSelectionListener() {\r
400 @Override\r
401 public void selectionChanged(TimeGraphSelectionEvent event) {\r
402 //ITimeGraphEntry selection = event.getSelection();\r
403 }\r
404 });\r
405\r
406 fTimeGraphCombo.getTimeGraphViewer().setTimeCalendarFormat(true);\r
407\r
408 final Thread thread = new Thread("ControlFlowView build") { //$NON-NLS-1$\r
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
417\r
418 // View Action Handling\r
419 makeActions();\r
420 contributeToActionBars();\r
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
441 final Thread thread = new Thread("ControlFlowView build") { //$NON-NLS-1$\r
442 @Override\r
443 public void run() {\r
444 selectExperiment(signal.getExperiment());\r
445 }\r
446 };\r
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
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
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
498 fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, true);\r
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
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
530 fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, false);\r
531 startZoomThread(startTime, endTime);\r
532 }\r
533 });\r
534 }\r
535\r
536 // ------------------------------------------------------------------------\r
537 // Internal\r
538 // ------------------------------------------------------------------------\r
539\r
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
545 fEntryList = new ArrayList<ControlFlowEntry>();\r
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
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
563 if (threadId == 0) { // ignore the swapper thread\r
564 continue;\r
565 }\r
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
575 long birthTime = -1;\r
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
580 long endTime = execNameInterval.getEndTime() + 1;\r
581 if (birthTime == -1) {\r
582 birthTime = startTime;\r
583 }\r
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
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
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
605 buildTree();\r
606 refresh(INITIAL_WINDOW_OFFSET);\r
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
633 }\r
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
642 List<ITimeEvent> eventList = getEventList(entry, entry.getStartTime(), entry.getEndTime(), resolution, new NullProgressMonitor());\r
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
650 private List<ITimeEvent> getEventList(ControlFlowEntry entry, long startTime, long endTime, long resolution, IProgressMonitor monitor) {\r
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
664 if (monitor.isCanceled()) {\r
665 return null;\r
666 }\r
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
687 }\r
688\r
689 private void refresh(final long windowRange) {\r
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
700\r
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
707 for (TreeColumn column : fTimeGraphCombo.getTreeViewer().getTree().getColumns()) {\r
708 column.pack();\r
709 }\r
710\r
711 startZoomThread(fStartTime, endTime);\r
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
725 }\r
726 });\r
727 }\r
728\r
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
736\r
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
745\r
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
763}\r
This page took 0.027039 seconds and 5 git commands to generate.