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