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