tmf: Transition custom parsers to the new location
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / views / callstack / CallStackView.java
CommitLineData
e8251298
PT
1/*******************************************************************************
2 * Copyright (c) 2013 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Patrick Tasse - Initial API and implementation
fec1ac0b 11 * Bernd Hufmann - Updated signal handling
e8251298
PT
12 *******************************************************************************/
13
14package org.eclipse.linuxtools.tmf.ui.views.callstack;
15
5da83da5 16import java.io.File;
e8251298
PT
17import java.util.ArrayList;
18import java.util.HashMap;
19import java.util.Iterator;
20import java.util.List;
52974e38 21import java.util.Map;
e8251298
PT
22
23import org.eclipse.core.runtime.IProgressMonitor;
5da83da5 24import org.eclipse.core.runtime.IStatus;
e8251298 25import org.eclipse.core.runtime.NullProgressMonitor;
5da83da5
AM
26import org.eclipse.core.runtime.Status;
27import org.eclipse.core.runtime.jobs.Job;
e8251298
PT
28import org.eclipse.jface.action.Action;
29import org.eclipse.jface.action.IAction;
0fcf3b09 30import org.eclipse.jface.action.IStatusLineManager;
e8251298
PT
31import org.eclipse.jface.action.IToolBarManager;
32import org.eclipse.jface.action.Separator;
33import org.eclipse.jface.util.IPropertyChangeListener;
34import org.eclipse.jface.util.PropertyChangeEvent;
35import org.eclipse.jface.viewers.DoubleClickEvent;
36import org.eclipse.jface.viewers.IDoubleClickListener;
37import org.eclipse.jface.viewers.ILabelProviderListener;
38import org.eclipse.jface.viewers.ISelection;
39import org.eclipse.jface.viewers.IStructuredSelection;
40import org.eclipse.jface.viewers.ITableLabelProvider;
41import org.eclipse.jface.viewers.ITreeContentProvider;
42import org.eclipse.jface.viewers.Viewer;
43import org.eclipse.linuxtools.internal.tmf.ui.Activator;
44import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants;
45import org.eclipse.linuxtools.internal.tmf.ui.Messages;
46import org.eclipse.linuxtools.tmf.core.callstack.CallStackStateProvider;
e8251298
PT
47import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
48import org.eclipse.linuxtools.tmf.core.exceptions.StateSystemDisposedException;
49import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
50import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
51import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;
52import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;
53import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
54import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;
55import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal;
fec1ac0b 56import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
e8251298
PT
57import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal;
58import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
59import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
60import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue.Type;
61import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
f566d40a 62import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp;
e8251298
PT
63import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
64import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
65import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampDelta;
66import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
67import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment;
68import org.eclipse.linuxtools.tmf.ui.editors.ITmfTraceEditor;
69import org.eclipse.linuxtools.tmf.ui.views.TmfView;
70import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphRangeListener;
71import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphTimeListener;
72import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphCombo;
73import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent;
74import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTimeEvent;
75import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphViewer;
76import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent;
77import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
78import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.NullTimeEvent;
79import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeEvent;
80import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
81import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphSelection;
82import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
83import org.eclipse.swt.SWT;
84import org.eclipse.swt.events.ControlAdapter;
85import org.eclipse.swt.events.ControlEvent;
86import org.eclipse.swt.events.MouseAdapter;
87import org.eclipse.swt.events.MouseEvent;
88import org.eclipse.swt.graphics.Image;
89import org.eclipse.swt.widgets.Composite;
90import org.eclipse.swt.widgets.Display;
5da83da5 91import org.eclipse.swt.widgets.FileDialog;
e8251298
PT
92import org.eclipse.ui.IActionBars;
93import org.eclipse.ui.IEditorPart;
94
95/**
96 * Main implementation for the Call Stack view
97 *
98 * @author Patrick Tasse
99 * @since 2.0
100 */
101public class CallStackView extends TmfView {
102
103 // ------------------------------------------------------------------------
104 // Constants
105 // ------------------------------------------------------------------------
106
107 /** View ID. */
108 public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.callstack"; //$NON-NLS-1$
109
110 /**
111 * Redraw state enum
112 */
113 private enum State { IDLE, BUSY, PENDING }
114
52974e38 115 private static final String[] COLUMN_NAMES = new String[] {
e8251298
PT
116 Messages.CallStackView_FunctionColumn,
117 Messages.CallStackView_DepthColumn,
118 Messages.CallStackView_EntryTimeColumn,
119 Messages.CallStackView_ExitTimeColumn,
120 Messages.CallStackView_DurationColumn
121 };
122
52974e38
PT
123 private static final int[] COLUMN_WIDTHS = new int[] {
124 200,
125 50,
126 120,
127 120,
128 120
129 };
130
131 // Fraction of a function duration to be added as spacing
132 private static final double SPACING_RATIO = 0.01;
133
e8251298
PT
134 private static final Image THREAD_IMAGE = Activator.getDefault().getImageFromPath("icons/obj16/thread_obj.gif"); //$NON-NLS-1$
135 private static final Image STACKFRAME_IMAGE = Activator.getDefault().getImageFromPath("icons/obj16/stckframe_obj.gif"); //$NON-NLS-1$
136
5da83da5
AM
137 private static final String IMPORT_MAPPING_ICON_PATH = "icons/etool16/import.gif"; //$NON-NLS-1$
138
e8251298
PT
139 // ------------------------------------------------------------------------
140 // Fields
141 // ------------------------------------------------------------------------
142
143 // The time graph combo
52974e38 144 private TimeGraphCombo fTimeGraphCombo;
e8251298
PT
145
146 // The selected trace
147 private ITmfTrace fTrace;
148
149 // The selected thread map
507b1336 150 private final Map<ITmfTrace, String> fSelectedThreadMap = new HashMap<>();
e8251298
PT
151
152 // The time graph entry list
52974e38 153 private List<ThreadEntry> fEntryList;
e8251298
PT
154
155 // The trace to entry list hash map
507b1336 156 private final Map<ITmfTrace, ArrayList<ThreadEntry>> fEntryListMap = new HashMap<>();
e8251298
PT
157
158 // The trace to build thread hash map
507b1336 159 private final Map<ITmfTrace, BuildThread> fBuildThreadMap = new HashMap<>();
e8251298 160
5da83da5
AM
161 /** The map to map function addresses to function names */
162 private Map<String, String> fNameMapping;
163
e8251298
PT
164 // The start time
165 private long fStartTime;
166
167 // The end time
168 private long fEndTime;
169
170 // The display width
171 private int fDisplayWidth;
172
173 // The next event action
174 private Action fNextEventAction;
175
176 // The previous event action
177 private Action fPrevEventAction;
178
179 // The next item action
180 private Action fNextItemAction;
181
182 // The previous item action
183 private Action fPreviousItemAction;
184
5da83da5
AM
185 /** The action to import a function-name mapping file */
186 private Action fImportMappingAction;
187
e8251298
PT
188 // The zoom thread
189 private ZoomThread fZoomThread;
190
191 // The redraw state used to prevent unnecessary queuing of display runnables
192 private State fRedrawState = State.IDLE;
193
194 // The redraw synchronization object
52974e38 195 private final Object fSyncObj = new Object();
e8251298
PT
196
197 // The saved time sync. signal used when switching off the pinning of a view
198 private TmfTimeSynchSignal fSavedTimeSyncSignal;
199
200 // The saved time range sync. signal used when switching off the pinning of a view
201 private TmfRangeSynchSignal fSavedRangeSyncSignal;
202
203 // ------------------------------------------------------------------------
204 // Classes
205 // ------------------------------------------------------------------------
206
207 private class ThreadEntry implements ITimeGraphEntry {
208 // The Trace
209 private final ITmfTrace fThreadTrace;
210 // The start time
211 private final long fTraceStartTime;
212 // The end time
213 private final long fTraceEndTime;
214 // The children of the entry
215 private ArrayList<CallStackEntry> fChildren;
216 // The name of entry
217 private final String fName;
218 // The thread attribute quark
219 private final int fThreadQuark;
220
221 public ThreadEntry(ITmfTrace trace, String name, int threadQuark, long startTime, long endTime) {
222 fThreadTrace = trace;
507b1336 223 fChildren = new ArrayList<>();
e8251298
PT
224 fName = name;
225 fTraceStartTime = startTime;
226 fTraceEndTime = endTime;
227 fThreadQuark = threadQuark;
228 }
229
230 @Override
231 public ITimeGraphEntry getParent() {
232 return null;
233 }
234
235 @Override
236 public boolean hasChildren() {
237 if (fChildren == null) {
238 ITmfStateSystem ss = fThreadTrace.getStateSystems().get(CallStackStateProvider.ID);
239 try {
240 int eventStackQuark = ss.getQuarkRelative(fThreadQuark, CallStackStateProvider.CALL_STACK);
241 ITmfStateInterval eventStackInterval = ss.querySingleState(ss.getStartTime(), eventStackQuark);
242 return ! eventStackInterval.getStateValue().isNull() || eventStackInterval.getEndTime() != ss.getCurrentEndTime();
243 } catch (AttributeNotFoundException e) {
52974e38 244 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 245 } catch (TimeRangeException e) {
52974e38 246 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298
PT
247 } catch (StateSystemDisposedException e) {
248 /* Ignored */
249 }
250 }
251 return fChildren != null && fChildren.size() > 0;
252 }
253
254 @Override
255 public List<CallStackEntry> getChildren() {
256 return fChildren;
257 }
258
259 @Override
260 public String getName() {
261 return fName;
262 }
263
264 @Override
265 public long getStartTime() {
266 return fTraceStartTime;
267 }
268
269 @Override
270 public long getEndTime() {
271 return fTraceEndTime;
272 }
273
274 @Override
275 public boolean hasTimeEvents() {
276 return false;
277 }
278
279 @Override
280 public Iterator<ITimeEvent> getTimeEventsIterator() {
281 return null;
282 }
283
284 @Override
285 public <T extends ITimeEvent> Iterator<T> getTimeEventsIterator(long startTime, long stopTime, long visibleDuration) {
286 return null;
287 }
288
289 public int getThreadQuark() {
290 return fThreadQuark;
291 }
292
293 public ITmfTrace getTrace() {
294 return fThreadTrace;
295 }
296
297 public void addChild(CallStackEntry entry) {
298 entry.setParent(this);
299 fChildren.add(entry);
300 }
301 }
302
303 private class TreeContentProvider implements ITreeContentProvider {
304
305 @Override
306 public void dispose() {
307 }
308
309 @Override
310 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
311 }
312
313 @Override
314 public Object[] getElements(Object inputElement) {
315 return (ITimeGraphEntry[]) inputElement;
316 }
317
318 @Override
319 public Object[] getChildren(Object parentElement) {
320 ITimeGraphEntry entry = (ITimeGraphEntry) parentElement;
321 return entry.getChildren().toArray();
322 }
323
324 @Override
325 public Object getParent(Object element) {
326 ITimeGraphEntry entry = (ITimeGraphEntry) element;
327 return entry.getParent();
328 }
329
330 @Override
331 public boolean hasChildren(Object element) {
332 ITimeGraphEntry entry = (ITimeGraphEntry) element;
333 return entry.hasChildren();
334 }
335
336 }
337
338 private class TreeLabelProvider implements ITableLabelProvider {
339
340 @Override
341 public void addListener(ILabelProviderListener listener) {
342 }
343
344 @Override
345 public void dispose() {
346 }
347
348 @Override
349 public boolean isLabelProperty(Object element, String property) {
350 return false;
351 }
352
353 @Override
354 public void removeListener(ILabelProviderListener listener) {
355 }
356
357 @Override
358 public Image getColumnImage(Object element, int columnIndex) {
359 if (columnIndex == 0) {
360 if (element instanceof ThreadEntry) {
361 return THREAD_IMAGE;
362 } else if (element instanceof CallStackEntry) {
363 CallStackEntry entry = (CallStackEntry) element;
364 if (entry.getFunctionName().length() > 0) {
365 return STACKFRAME_IMAGE;
366 }
367 }
368 }
369 return null;
370 }
371
372 @Override
373 public String getColumnText(Object element, int columnIndex) {
374 if (element instanceof ThreadEntry) {
375 if (columnIndex == 0) {
376 return ((ThreadEntry) element).getName();
377 }
378 } else if (element instanceof CallStackEntry) {
379 CallStackEntry entry = (CallStackEntry) element;
380 if (columnIndex == 0) {
381 return entry.getFunctionName();
52974e38
PT
382 } else if (columnIndex == 1 && entry.getFunctionName().length() > 0) {
383 int depth = entry.getStackLevel();
384 return Integer.toString(depth);
385 } else if (columnIndex == 2 && entry.getFunctionName().length() > 0) {
386 ITmfTimestamp ts = new TmfTimestamp(entry.getStartTime(), ITmfTimestamp.NANOSECOND_SCALE);
387 return ts.toString();
388 } else if (columnIndex == 3 && entry.getFunctionName().length() > 0) {
389 ITmfTimestamp ts = new TmfTimestamp(entry.getEndTime(), ITmfTimestamp.NANOSECOND_SCALE);
390 return ts.toString();
391 } else if (columnIndex == 4 && entry.getFunctionName().length() > 0) {
392 ITmfTimestamp ts = new TmfTimestampDelta(entry.getEndTime() - entry.getStartTime(), ITmfTimestamp.NANOSECOND_SCALE);
393 return ts.toString();
e8251298
PT
394 }
395 }
396 return ""; //$NON-NLS-1$
397 }
398
399 }
400
401 private class BuildThread extends Thread {
402 private final ITmfTrace fBuildTrace;
403 private final IProgressMonitor fMonitor;
404
405 public BuildThread(ITmfTrace trace) {
406 super("CallStackView build"); //$NON-NLS-1$
407 fBuildTrace = trace;
408 fMonitor = new NullProgressMonitor();
409 }
410
411 @Override
412 public void run() {
413 buildThreadList(fBuildTrace, fMonitor);
414 synchronized (fBuildThreadMap) {
415 fBuildThreadMap.remove(this);
416 }
417 }
418
419 public void cancel() {
420 fMonitor.setCanceled(true);
421 }
422 }
423
424 private class ZoomThread extends Thread {
52974e38 425 private final List<ThreadEntry> fZoomEntryList;
e8251298
PT
426 private final long fZoomStartTime;
427 private final long fZoomEndTime;
428 private final IProgressMonitor fMonitor;
429
52974e38 430 public ZoomThread(List<ThreadEntry> entryList, long startTime, long endTime) {
e8251298
PT
431 super("ResourcesView zoom"); //$NON-NLS-1$
432 fZoomEntryList = entryList;
433 fZoomStartTime = startTime;
434 fZoomEndTime = endTime;
435 fMonitor = new NullProgressMonitor();
436 }
437
438 @Override
439 public void run() {
440 if (fZoomEntryList == null) {
441 return;
442 }
443 long resolution = Math.max(1, (fZoomEndTime - fZoomStartTime) / fDisplayWidth);
444 for (ThreadEntry threadEntry : fZoomEntryList) {
445 ITmfStateSystem ss = threadEntry.fThreadTrace.getStateSystems().get(CallStackStateProvider.ID);
2002c638
AM
446 if (ss == null) {
447 continue;
448 }
449 ss.waitUntilBuilt();
450 if (ss.isCancelled()) {
e8251298
PT
451 continue;
452 }
453 for (ITimeGraphEntry child : threadEntry.getChildren()) {
454 if (fMonitor.isCanceled()) {
455 break;
456 }
457 CallStackEntry entry = (CallStackEntry) child;
458 if (fZoomStartTime <= fStartTime && fZoomEndTime >= fEndTime) {
459 entry.setZoomedEventList(null);
460 } else {
461 List<ITimeEvent> zoomedEventList = getEventList(entry, fZoomStartTime, fZoomEndTime, resolution, fMonitor);
462 if (zoomedEventList != null) {
463 entry.setZoomedEventList(zoomedEventList);
464 }
465 }
466 redraw();
467 }
468 }
469 }
470
471 public void cancel() {
472 fMonitor.setCanceled(true);
473 }
474 }
475
476 // ------------------------------------------------------------------------
477 // Constructors
478 // ------------------------------------------------------------------------
479
480 /**
481 * Default constructor
482 */
483 public CallStackView() {
484 super(ID);
485 fDisplayWidth = Display.getDefault().getBounds().width;
486 }
487
488 // ------------------------------------------------------------------------
489 // ViewPart
490 // ------------------------------------------------------------------------
491
492 @Override
493 public void createPartControl(Composite parent) {
494 fTimeGraphCombo = new TimeGraphCombo(parent, SWT.NONE);
495
496 fTimeGraphCombo.setTreeContentProvider(new TreeContentProvider());
497
498 fTimeGraphCombo.setTreeLabelProvider(new TreeLabelProvider());
499
500 fTimeGraphCombo.setTreeColumns(COLUMN_NAMES);
501
52974e38
PT
502 fTimeGraphCombo.getTreeViewer().getTree().getColumn(0).setWidth(COLUMN_WIDTHS[0]);
503 fTimeGraphCombo.getTreeViewer().getTree().getColumn(1).setWidth(COLUMN_WIDTHS[1]);
504 fTimeGraphCombo.getTreeViewer().getTree().getColumn(2).setWidth(COLUMN_WIDTHS[2]);
505 fTimeGraphCombo.getTreeViewer().getTree().getColumn(3).setWidth(COLUMN_WIDTHS[3]);
506 fTimeGraphCombo.getTreeViewer().getTree().getColumn(4).setWidth(COLUMN_WIDTHS[4]);
e8251298 507
5da83da5 508 fTimeGraphCombo.setTimeGraphProvider(new CallStackPresentationProvider(this));
e8251298
PT
509 fTimeGraphCombo.getTimeGraphViewer().setTimeFormat(TimeFormat.CALENDAR);
510
511 fTimeGraphCombo.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() {
512 @Override
513 public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) {
514 long startTime = event.getStartTime();
515 long endTime = event.getEndTime();
f566d40a 516 TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime));
0fcf3b09 517 broadcast(new TmfRangeSynchSignal(CallStackView.this, range));
e8251298
PT
518 startZoomThread(startTime, endTime);
519 }
520 });
521
522 fTimeGraphCombo.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() {
523 @Override
524 public void timeSelected(TimeGraphTimeEvent event) {
0fcf3b09
PT
525 long beginTime = event.getBeginTime();
526 long endTime = event.getEndTime();
527 selectTime(beginTime);
f566d40a 528 broadcast(new TmfTimeSynchSignal(CallStackView.this, new TmfNanoTimestamp(beginTime), new TmfNanoTimestamp(endTime)));
e8251298
PT
529 }
530 });
531
532 fTimeGraphCombo.getTimeGraphViewer().getControl().addControlListener(new ControlAdapter() {
533 @Override
534 public void controlResized(ControlEvent e) {
535 fDisplayWidth = fTimeGraphCombo.getTimeGraphViewer().getControl().getSize().x;
536 if (fEntryList != null) {
537 startZoomThread(fTimeGraphCombo.getTimeGraphViewer().getTime0(), fTimeGraphCombo.getTimeGraphViewer().getTime1());
538 }
539 }
540 });
541
542 fTimeGraphCombo.getTreeViewer().addDoubleClickListener(new IDoubleClickListener() {
543 @Override
544 public void doubleClick(DoubleClickEvent event) {
545 Object selection = ((IStructuredSelection) event.getSelection()).getFirstElement();
546 if (selection instanceof CallStackEntry) {
547 CallStackEntry entry = (CallStackEntry) selection;
548 if (entry.getFunctionName().length() > 0) {
549 long startTime = entry.getStartTime();
550 long endTime = entry.getEndTime();
52974e38 551 long spacingTime = (long) ((endTime - startTime) * SPACING_RATIO);
e8251298
PT
552 startTime -= spacingTime;
553 endTime += spacingTime;
f566d40a 554 TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime));
0fcf3b09 555 broadcast(new TmfRangeSynchSignal(CallStackView.this, range));
e8251298
PT
556 fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
557 startZoomThread(startTime, endTime);
558 }
559 }
560 }
561 });
562
563 fTimeGraphCombo.getTimeGraphViewer().getTimeGraphControl().addMouseListener(new MouseAdapter() {
564 @Override
565 public void mouseDoubleClick(MouseEvent e) {
566 TimeGraphControl timeGraphControl = fTimeGraphCombo.getTimeGraphViewer().getTimeGraphControl();
567 ISelection selection = timeGraphControl.getSelection();
568 if (selection instanceof TimeGraphSelection) {
569 Object o = ((TimeGraphSelection) selection).getFirstElement();
570 if (o instanceof CallStackEvent) {
571 CallStackEvent event = (CallStackEvent) o;
572 long startTime = event.getTime();
573 long endTime = startTime + event.getDuration();
52974e38 574 long spacingTime = (long) ((endTime - startTime) * SPACING_RATIO);
e8251298
PT
575 startTime -= spacingTime;
576 endTime += spacingTime;
f566d40a 577 TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime));
0fcf3b09 578 broadcast(new TmfRangeSynchSignal(CallStackView.this, range));
e8251298
PT
579 fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
580 startZoomThread(startTime, endTime);
581 }
582 }
583 }
584 });
585
0fcf3b09
PT
586 IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager();
587 fTimeGraphCombo.getTimeGraphViewer().getTimeGraphControl().setStatusLineManager(statusLineManager);
588
e8251298
PT
589 // View Action Handling
590 makeActions();
591 contributeToActionBars();
592
593 IEditorPart editor = getSite().getPage().getActiveEditor();
594 if (editor instanceof ITmfTraceEditor) {
595 ITmfTrace trace = ((ITmfTraceEditor) editor).getTrace();
596 if (trace != null) {
597 traceSelected(new TmfTraceSelectedSignal(this, trace));
598 }
599 }
600 }
601
602 @Override
603 public void setFocus() {
604 fTimeGraphCombo.setFocus();
605 }
606
607 // ------------------------------------------------------------------------
608 // Signal handlers
609 // ------------------------------------------------------------------------
fec1ac0b
BH
610 /**
611 * Handler for the trace opened signal.
612 * @param signal
613 * The incoming signal
614 * @since 2.0
615 */
616 @TmfSignalHandler
617 public void traceOpened(TmfTraceOpenedSignal signal) {
618 fTrace = signal.getTrace();
619 loadTrace();
620 }
e8251298
PT
621
622 /**
623 * Handler for the trace selected signal
624 *
625 * @param signal
626 * The incoming signal
627 */
628 @TmfSignalHandler
629 public void traceSelected(final TmfTraceSelectedSignal signal) {
630 if (signal.getTrace() == fTrace) {
631 return;
632 }
633 fTrace = signal.getTrace();
fec1ac0b 634 loadTrace();
e8251298
PT
635 }
636
637 /**
638 * Trace is closed: clear the data structures and the view
639 *
640 * @param signal the signal received
641 */
642 @TmfSignalHandler
643 public void traceClosed(final TmfTraceClosedSignal signal) {
644 synchronized (fBuildThreadMap) {
645 BuildThread buildThread = fBuildThreadMap.remove(signal.getTrace());
646 if (buildThread != null) {
647 buildThread.cancel();
648 }
649 }
650 synchronized (fEntryListMap) {
651 fEntryListMap.remove(signal.getTrace());
652 }
653 fSelectedThreadMap.remove(signal.getTrace());
654 if (signal.getTrace() == fTrace) {
655 fTrace = null;
656 fStartTime = 0;
657 fEndTime = 0;
658 refresh();
659 }
660 }
661
662 /**
663 * Handler for the TimeSynch signal
664 *
665 * @param signal
666 * The incoming signal
667 */
668 @TmfSignalHandler
669 public void synchToTime(final TmfTimeSynchSignal signal) {
670
0fcf3b09 671 fSavedTimeSyncSignal = isPinned() ? new TmfTimeSynchSignal(signal.getSource(), signal.getBeginTime(), signal.getEndTime()) : null;
e8251298
PT
672
673 if (signal.getSource() == this || fTrace == null || isPinned()) {
674 return;
675 }
0fcf3b09
PT
676 final long beginTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
677 final long endTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
e8251298
PT
678 Display.getDefault().asyncExec(new Runnable() {
679 @Override
680 public void run() {
681 if (fTimeGraphCombo.isDisposed()) {
682 return;
683 }
0fcf3b09
PT
684 if (beginTime == endTime) {
685 fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(beginTime, true);
686 } else {
687 fTimeGraphCombo.getTimeGraphViewer().setSelectionRange(beginTime, endTime);
688 }
689 selectTime(beginTime);
e8251298
PT
690 startZoomThread(fTimeGraphCombo.getTimeGraphViewer().getTime0(), fTimeGraphCombo.getTimeGraphViewer().getTime1());
691 if (fEntryList == null) {
692 return;
693 }
694 TimeGraphViewer viewer = fTimeGraphCombo.getTimeGraphViewer();
695 for (ThreadEntry threadEntry : fEntryList) {
696 ITmfStateSystem ss = threadEntry.getTrace().getStateSystems().get(CallStackStateProvider.ID);
0fcf3b09 697 if (ss == null || beginTime < ss.getStartTime() || beginTime > ss.getCurrentEndTime()) {
e8251298
PT
698 continue;
699 }
700 try {
701 int quark = ss.getQuarkRelative(threadEntry.getThreadQuark(), CallStackStateProvider.CALL_STACK);
0fcf3b09
PT
702 ITmfStateInterval stackInterval = ss.querySingleState(beginTime, quark);
703 if (beginTime == stackInterval.getStartTime()) {
e8251298
PT
704 int stackLevel = stackInterval.getStateValue().unboxInt();
705 CallStackEntry selectedEntry = threadEntry.getChildren().get(Math.max(0, stackLevel - 1));
706 fTimeGraphCombo.setSelection(selectedEntry);
707 viewer.getTimeGraphControl().fireSelectionChanged();
708 break;
709 }
710 } catch (AttributeNotFoundException e) {
52974e38 711 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 712 } catch (TimeRangeException e) {
52974e38 713 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 714 } catch (StateSystemDisposedException e) {
52974e38 715 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 716 } catch (StateValueTypeException e) {
52974e38 717 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298
PT
718 }
719 }
720 }
721 });
722 }
723
724 /**
725 * Handler for the RangeSynch signal
726 *
727 * @param signal
728 * The incoming signal
729 */
730 @TmfSignalHandler
731 public void synchToRange(final TmfRangeSynchSignal signal) {
732
733 if (isPinned()) {
734 fSavedRangeSyncSignal =
0fcf3b09 735 new TmfRangeSynchSignal(signal.getSource(), new TmfTimeRange(signal.getCurrentRange().getStartTime(), signal.getCurrentRange().getEndTime()));
e8251298
PT
736
737 fSavedTimeSyncSignal = null;
738 }
739
740 if (signal.getSource() == this || fTrace == null || isPinned()) {
741 return;
742 }
743 if (signal.getCurrentRange().getIntersection(fTrace.getTimeRange()) == null) {
744 return;
745 }
746 final long startTime = signal.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
747 final long endTime = signal.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
e8251298
PT
748 Display.getDefault().asyncExec(new Runnable() {
749 @Override
750 public void run() {
751 if (fTimeGraphCombo.isDisposed()) {
752 return;
753 }
754 fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
e8251298
PT
755 startZoomThread(startTime, endTime);
756 }
757 });
758 }
759
760 // ------------------------------------------------------------------------
761 // Internal
762 // ------------------------------------------------------------------------
5da83da5 763
fec1ac0b
BH
764 private void loadTrace() {
765 synchronized (fEntryListMap) {
766 fEntryList = fEntryListMap.get(fTrace);
767 if (fEntryList == null) {
768 synchronized (fBuildThreadMap) {
769 BuildThread buildThread = new BuildThread(fTrace);
770 fBuildThreadMap.put(fTrace, buildThread);
771 buildThread.start();
772 }
773 } else {
774 fStartTime = fTrace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
775 fEndTime = fTrace.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
776 refresh();
777 }
778 }
779 }
e8251298
PT
780
781 private void buildThreadList(final ITmfTrace trace, IProgressMonitor monitor) {
782 fStartTime = Long.MAX_VALUE;
783 fEndTime = Long.MIN_VALUE;
784 ITmfTrace[] traces;
785 if (trace instanceof TmfExperiment) {
786 TmfExperiment experiment = (TmfExperiment) trace;
787 traces = experiment.getTraces();
788 } else {
789 traces = new ITmfTrace[] { trace };
790 }
507b1336 791 ArrayList<ThreadEntry> entryList = new ArrayList<>();
e8251298
PT
792 for (ITmfTrace aTrace : traces) {
793 if (monitor.isCanceled()) {
794 return;
795 }
796 ITmfStateSystem ss = aTrace.getStateSystems().get(CallStackStateProvider.ID);
2002c638
AM
797 if (ss == null) {
798 addUnavailableEntry(aTrace, entryList);
799 continue;
800 }
801 ss.waitUntilBuilt();
802 if (ss.isCancelled()) {
803 addUnavailableEntry(aTrace, entryList);
e8251298
PT
804 continue;
805 }
806 long startTime = ss.getStartTime();
807 long endTime = ss.getCurrentEndTime() + 1;
808 fStartTime = Math.min(fStartTime, startTime);
809 fEndTime = Math.max(fEndTime, endTime);
810 List<Integer> threadQuarks = ss.getQuarks(CallStackStateProvider.THREADS, "*"); //$NON-NLS-1$
811 for (int i = 0; i < threadQuarks.size(); i++) {
812 if (monitor.isCanceled()) {
813 return;
814 }
815 int threadQuark = threadQuarks.get(i);
816 String thread = ss.getAttributeName(threadQuark);
817 String threadEntryName = thread + ' ' + '(' + aTrace.getName() + ')';
818 ThreadEntry threadEntry = new ThreadEntry(aTrace, threadEntryName, threadQuark, startTime, endTime);
819 entryList.add(threadEntry);
820 int eventStackQuark;
821 try {
822 eventStackQuark = ss.getQuarkRelative(threadQuark, CallStackStateProvider.CALL_STACK);
823 int level = 1;
824 for (int stackLevelQuark : ss.getSubAttributes(eventStackQuark, false)) {
825 CallStackEntry callStackEntry = new CallStackEntry(stackLevelQuark, level++, aTrace);
826 threadEntry.addChild(callStackEntry);
827 }
828 } catch (AttributeNotFoundException e) {
52974e38 829 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298
PT
830 }
831 }
832 }
833 synchronized (fEntryListMap) {
507b1336 834 fEntryListMap.put(trace, new ArrayList<>(entryList));
e8251298
PT
835 }
836 if (trace == fTrace) {
837 refresh();
838 }
839 for (ThreadEntry threadEntry : entryList) {
840 for (CallStackEntry callStackEntry : threadEntry.getChildren()) {
841 if (monitor.isCanceled()) {
842 return;
843 }
844 buildStatusEvents(trace, callStackEntry, monitor);
845 }
846 }
847 }
848
2002c638
AM
849 private void addUnavailableEntry(ITmfTrace trace, List<ThreadEntry> list) {
850 String threadName = Messages.CallStackView_StackInfoNotAvailable + ' ' + '(' + trace.getName() + ')';
851 ThreadEntry threadEntry = new ThreadEntry(trace, threadName, -1, 0, 0);
852 list.add(threadEntry);
853 }
854
e8251298
PT
855 private void buildStatusEvents(ITmfTrace trace, CallStackEntry entry, IProgressMonitor monitor) {
856 ITmfStateSystem ss = entry.getTrace().getStateSystems().get(CallStackStateProvider.ID);
857 long start = ss.getStartTime();
858 long end = ss.getCurrentEndTime() + 1;
859 long resolution = Math.max(1, (end - start) / fDisplayWidth);
860 List<ITimeEvent> eventList = getEventList(entry, start, end, resolution, monitor);
861 if (monitor.isCanceled()) {
862 return;
863 }
864 entry.setEventList(eventList);
865 if (trace == fTrace) {
866 redraw();
867 }
868 }
869
870 private static List<ITimeEvent> getEventList(CallStackEntry entry,
871 long startTime, long endTime, long resolution,
872 IProgressMonitor monitor) {
873 ITmfStateSystem ss = entry.getTrace().getStateSystems().get(CallStackStateProvider.ID);
874 long start = Math.max(startTime, ss.getStartTime());
875 long end = Math.min(endTime, ss.getCurrentEndTime() + 1);
876 if (end <= start) {
877 return null;
878 }
879 List<ITimeEvent> eventList = null;
880 try {
881 List<ITmfStateInterval> stackIntervals = ss.queryHistoryRange(entry.getQuark(), start, end - 1, resolution, monitor);
507b1336 882 eventList = new ArrayList<>(stackIntervals.size());
e8251298
PT
883 long lastEndTime = -1;
884 boolean lastIsNull = true;
885 for (ITmfStateInterval statusInterval : stackIntervals) {
886 if (monitor.isCanceled()) {
887 return null;
888 }
889 long time = statusInterval.getStartTime();
890 long duration = statusInterval.getEndTime() - time + 1;
891 if (!statusInterval.getStateValue().isNull()) {
52974e38
PT
892 final int modulo = CallStackPresentationProvider.NUM_COLORS / 2;
893 int value = statusInterval.getStateValue().toString().hashCode() % modulo + modulo;
e8251298
PT
894 eventList.add(new CallStackEvent(entry, time, duration, value));
895 lastIsNull = false;
896 } else {
beb1b921
PT
897 if (lastEndTime == -1) {
898 // add null event if it intersects the start time
899 eventList.add(new NullTimeEvent(entry, time, duration));
900 } else {
901 if (lastEndTime != time && lastIsNull) {
902 // add unknown event if between two null states
903 eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime));
904 }
905 if (time + duration >= endTime) {
906 // add null event if it intersects the end time
907 eventList.add(new NullTimeEvent(entry, time, duration));
908 }
e8251298 909 }
e8251298
PT
910 lastIsNull = true;
911 }
912 lastEndTime = time + duration;
913 }
914 } catch (AttributeNotFoundException e) {
52974e38 915 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 916 } catch (TimeRangeException e) {
52974e38 917 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298
PT
918 } catch (StateSystemDisposedException e) {
919 /* Ignored */
920 }
921 return eventList;
922 }
923
924 private void selectTime(long time) {
925 if (fEntryList == null) {
926 return;
927 }
e8251298
PT
928 for (ThreadEntry threadEntry : fEntryList) {
929 ITmfStateSystem ss = threadEntry.fThreadTrace.getStateSystems().get(CallStackStateProvider.ID);
2002c638
AM
930 if (ss == null) {
931 continue;
932 }
933 ss.waitUntilBuilt();
934 if (ss.isCancelled()) {
e8251298
PT
935 continue;
936 }
937 long queryTime = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), time));
938 for (CallStackEntry callStackEntry : threadEntry.getChildren()) {
939 try {
940 ITmfStateInterval stackLevelInterval = ss.querySingleState(queryTime, callStackEntry.getQuark());
941 ITmfStateValue nameValue = stackLevelInterval.getStateValue();
942 String name = ""; //$NON-NLS-1$
943 try {
944 if (nameValue.getType() == Type.STRING) {
5da83da5
AM
945 String address = nameValue.unboxStr();
946 name = getFunctionName(address);
e8251298
PT
947 } else if (nameValue.getType() == Type.INTEGER) {
948 name = "0x" + Integer.toHexString(nameValue.unboxInt()); //$NON-NLS-1$
949 } else if (nameValue.getType() == Type.LONG) {
950 name = "0x" + Long.toHexString(nameValue.unboxLong()); //$NON-NLS-1$
951 }
952 } catch (StateValueTypeException e) {
953 }
954 callStackEntry.setFunctionName(name);
955 if (name.length() > 0) {
956 callStackEntry.setStartTime(stackLevelInterval.getStartTime());
957 callStackEntry.setEndTime(stackLevelInterval.getEndTime() + 1);
958 }
959 } catch (AttributeNotFoundException e) {
52974e38 960 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 961 } catch (TimeRangeException e) {
52974e38 962 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 963 } catch (StateSystemDisposedException e) {
52974e38 964 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298
PT
965 }
966 }
967 }
968 fTimeGraphCombo.refresh();
e8251298
PT
969 }
970
971 private void refresh() {
972 Display.getDefault().asyncExec(new Runnable() {
973 @Override
974 public void run() {
975 if (fTimeGraphCombo.isDisposed()) {
976 return;
977 }
978 ITimeGraphEntry[] entries = null;
979 synchronized (fEntryListMap) {
980 fEntryList = fEntryListMap.get(fTrace);
981 if (fEntryList == null) {
507b1336 982 fEntryList = new ArrayList<>();
e8251298
PT
983 }
984 entries = fEntryList.toArray(new ITimeGraphEntry[0]);
985 }
986 fTimeGraphCombo.setInput(entries);
987 fTimeGraphCombo.getTimeGraphViewer().setTimeBounds(fStartTime, fEndTime);
988
0fcf3b09
PT
989 long selectionBeginTime = fTrace == null ? 0 : fTraceManager.getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
990 long selectionEndTime = fTrace == null ? 0 : fTraceManager.getSelectionEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
248af329
AM
991 long startTime = fTrace == null ? 0 : fTraceManager.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
992 long endTime = fTrace == null ? 0 : fTraceManager.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
e8251298
PT
993 startTime = Math.max(startTime, fStartTime);
994 endTime = Math.min(endTime, fEndTime);
0fcf3b09
PT
995 fTimeGraphCombo.getTimeGraphViewer().setSelectionRange(selectionBeginTime, selectionEndTime);
996 selectTime(selectionBeginTime);
e8251298
PT
997 fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
998 startZoomThread(startTime, endTime);
999 }
1000 });
1001 }
1002
1003 private void redraw() {
1004 synchronized (fSyncObj) {
1005 if (fRedrawState == State.IDLE) {
1006 fRedrawState = State.BUSY;
1007 } else {
1008 fRedrawState = State.PENDING;
1009 return;
1010 }
1011 }
1012 Display.getDefault().asyncExec(new Runnable() {
1013 @Override
1014 public void run() {
1015 if (fTimeGraphCombo.isDisposed()) {
1016 return;
1017 }
1018 fTimeGraphCombo.redraw();
1019 fTimeGraphCombo.update();
1020 synchronized (fSyncObj) {
1021 if (fRedrawState == State.PENDING) {
1022 fRedrawState = State.IDLE;
1023 redraw();
1024 } else {
1025 fRedrawState = State.IDLE;
1026 }
1027 }
1028 }
1029 });
1030 }
1031
1032 private void startZoomThread(long startTime, long endTime) {
1033 if (fZoomThread != null) {
1034 fZoomThread.cancel();
1035 }
1036 fZoomThread = new ZoomThread(fEntryList, startTime, endTime);
1037 fZoomThread.start();
1038 }
1039
1040 private void makeActions() {
1041 fPreviousItemAction = fTimeGraphCombo.getTimeGraphViewer().getPreviousItemAction();
1042 fPreviousItemAction.setText(Messages.TmfTimeGraphViewer_PreviousItemActionNameText);
1043 fPreviousItemAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousItemActionToolTipText);
1044 fNextItemAction = fTimeGraphCombo.getTimeGraphViewer().getNextItemAction();
1045 fNextItemAction.setText(Messages.TmfTimeGraphViewer_NextItemActionNameText);
1046 fNextItemAction.setToolTipText(Messages.TmfTimeGraphViewer_NextItemActionToolTipText);
1047 }
1048
1049 private void contributeToActionBars() {
1050 IActionBars bars = getViewSite().getActionBars();
1051 fillLocalToolBar(bars.getToolBarManager());
1052
1053 // Create pin action
1054 contributePinActionToToolBar();
1055 fPinAction.addPropertyChangeListener(new IPropertyChangeListener(){
1056 @Override
1057 public void propertyChange(PropertyChangeEvent event) {
52974e38
PT
1058 if (IAction.CHECKED.equals(event.getProperty()) && !isPinned()) {
1059 if (fSavedRangeSyncSignal != null) {
1060 synchToRange(fSavedRangeSyncSignal);
1061 fSavedRangeSyncSignal = null;
1062 }
e8251298 1063
52974e38
PT
1064 if (fSavedTimeSyncSignal != null) {
1065 synchToTime(fSavedTimeSyncSignal);
1066 fSavedTimeSyncSignal = null;
e8251298
PT
1067 }
1068 }
1069 }
1070 });
1071 }
1072
1073 private void fillLocalToolBar(IToolBarManager manager) {
5da83da5 1074 manager.add(getImportMappingAction());
e8251298
PT
1075 manager.add(fTimeGraphCombo.getTimeGraphViewer().getResetScaleAction());
1076 manager.add(getPreviousEventAction());
1077 manager.add(getNextEventAction());
1078 manager.add(fPreviousItemAction);
1079 manager.add(fNextItemAction);
1080 manager.add(fTimeGraphCombo.getTimeGraphViewer().getZoomInAction());
1081 manager.add(fTimeGraphCombo.getTimeGraphViewer().getZoomOutAction());
1082 manager.add(new Separator());
1083 }
1084
1085 /**
1086 * Get the the next event action.
1087 *
1088 * @return The action object
1089 */
1090 private Action getNextEventAction() {
1091 if (fNextEventAction == null) {
1092 fNextEventAction = new Action() {
1093 @Override
1094 public void run() {
1095 TimeGraphViewer viewer = fTimeGraphCombo.getTimeGraphViewer();
1096 ITimeGraphEntry entry = viewer.getSelection();
1097 if (entry instanceof CallStackEntry) {
1098 try {
1099 CallStackEntry callStackEntry = (CallStackEntry) entry;
1100 ITmfTrace trace = callStackEntry.getTrace();
1101 ITmfStateSystem ss = trace.getStateSystems().get(CallStackStateProvider.ID);
0fcf3b09 1102 long time = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), viewer.getSelectionBegin()));
e8251298
PT
1103 ThreadEntry threadEntry = (ThreadEntry) callStackEntry.getParent();
1104 int quark = ss.getQuarkRelative(threadEntry.getThreadQuark(), CallStackStateProvider.CALL_STACK);
1105 ITmfStateInterval stackInterval = ss.querySingleState(time, quark);
1106 long newTime = stackInterval.getEndTime() + 1;
1107 viewer.setSelectedTimeNotify(newTime, true);
1108 stackInterval = ss.querySingleState(Math.min(ss.getCurrentEndTime(), newTime), quark);
1109 int stackLevel = stackInterval.getStateValue().unboxInt();
1110 CallStackEntry selectedEntry = threadEntry.getChildren().get(Math.max(0, stackLevel - 1));
1111 fTimeGraphCombo.setSelection(selectedEntry);
1112 viewer.getTimeGraphControl().fireSelectionChanged();
1113 startZoomThread(viewer.getTime0(), viewer.getTime1());
1114 } catch (AttributeNotFoundException e) {
52974e38 1115 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 1116 } catch (TimeRangeException e) {
52974e38 1117 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 1118 } catch (StateSystemDisposedException e) {
52974e38 1119 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 1120 } catch (StateValueTypeException e) {
52974e38 1121 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298
PT
1122 }
1123 }
1124 }
1125 };
1126
1127 fNextEventAction.setText(Messages.TmfTimeGraphViewer_NextEventActionNameText);
1128 fNextEventAction.setToolTipText(Messages.TmfTimeGraphViewer_NextEventActionToolTipText);
1129 fNextEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_EVENT));
1130 }
1131
1132 return fNextEventAction;
1133 }
1134
1135 /**
1136 * Get the previous event action.
1137 *
1138 * @return The Action object
1139 */
1140 private Action getPreviousEventAction() {
1141 if (fPrevEventAction == null) {
1142 fPrevEventAction = new Action() {
1143 @Override
1144 public void run() {
1145 TimeGraphViewer viewer = fTimeGraphCombo.getTimeGraphViewer();
1146 ITimeGraphEntry entry = viewer.getSelection();
1147 if (entry instanceof CallStackEntry) {
1148 try {
1149 CallStackEntry callStackEntry = (CallStackEntry) entry;
1150 ITmfTrace trace = callStackEntry.getTrace();
1151 ITmfStateSystem ss = trace.getStateSystems().get(CallStackStateProvider.ID);
0fcf3b09 1152 long time = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), viewer.getSelectionBegin()));
e8251298
PT
1153 ThreadEntry threadEntry = (ThreadEntry) callStackEntry.getParent();
1154 int quark = ss.getQuarkRelative(threadEntry.getThreadQuark(), CallStackStateProvider.CALL_STACK);
1155 ITmfStateInterval stackInterval = ss.querySingleState(time, quark);
1156 if (stackInterval.getStartTime() == time && time > ss.getStartTime()) {
1157 stackInterval = ss.querySingleState(time - 1, quark);
1158 }
1159 viewer.setSelectedTimeNotify(stackInterval.getStartTime(), true);
1160 int stackLevel = stackInterval.getStateValue().unboxInt();
1161 CallStackEntry selectedEntry = threadEntry.getChildren().get(Math.max(0, stackLevel - 1));
1162 fTimeGraphCombo.setSelection(selectedEntry);
1163 viewer.getTimeGraphControl().fireSelectionChanged();
1164 startZoomThread(viewer.getTime0(), viewer.getTime1());
1165 } catch (AttributeNotFoundException e) {
52974e38 1166 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 1167 } catch (TimeRangeException e) {
52974e38 1168 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 1169 } catch (StateSystemDisposedException e) {
52974e38 1170 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 1171 } catch (StateValueTypeException e) {
52974e38 1172 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298
PT
1173 }
1174 }
1175 }
1176 };
1177
1178 fPrevEventAction.setText(Messages.TmfTimeGraphViewer_PreviousEventActionNameText);
1179 fPrevEventAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousEventActionToolTipText);
1180 fPrevEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_EVENT));
1181 }
1182
1183 return fPrevEventAction;
1184 }
1185
5da83da5
AM
1186 // ------------------------------------------------------------------------
1187 // Methods related to function name mapping
1188 // ------------------------------------------------------------------------
1189
1190 /**
1191 * Toolbar icon to import the function address-to-name mapping file.
1192 */
1193 private Action getImportMappingAction() {
1194 if (fImportMappingAction != null) {
1195 return fImportMappingAction;
1196 }
1197 fImportMappingAction = new Action() {
1198 @Override
1199 public void run() {
1200 FileDialog dialog = new FileDialog(getViewSite().getShell());
1201 dialog.setText(Messages.CallStackView_ImportMappingDialogTitle);
1202 String filePath = dialog.open();
1203 if (filePath == null) {
1204 /* No file was selected, don't change anything */
1205 return;
1206 }
1207 /*
1208 * Start the mapping import in a separate thread (we do not want
1209 * to UI thread to do this).
1210 */
1211 Job job = new ImportMappingJob(new File(filePath));
1212 job.schedule();
1213 }
1214 };
1215
1216 fImportMappingAction.setText(Messages.CallStackView_ImportMappingButtonText);
1217 fImportMappingAction.setToolTipText(Messages.CallStackView_ImportMappingButtonTooltip);
1218 fImportMappingAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(IMPORT_MAPPING_ICON_PATH));
1219
1220 return fImportMappingAction;
1221 }
1222
1223 private class ImportMappingJob extends Job {
1224 private final File fMappingFile;
1225
1226 public ImportMappingJob(File mappingFile) {
1227 super(Messages.CallStackView_ImportMappingJobName);
1228 fMappingFile = mappingFile;
1229 }
1230
1231 @Override
1232 public IStatus run(IProgressMonitor monitor) {
1233 fNameMapping = FunctionNameMapper.mapFromNmTextFile(fMappingFile);
1234
1235 /* Refresh the time graph and the list of entries */
1236 buildThreadList(fTrace, new NullProgressMonitor());
1237 redraw();
1238
1239 return Status.OK_STATUS;
1240 }
1241 }
1242
1243 String getFunctionName(String address) {
1244 if (fNameMapping == null) {
1245 /* No mapping available, just print the addresses */
1246 return address;
1247 }
1248 String ret = fNameMapping.get(address);
1249 if (ret == null) {
1250 /* We didn't find this address in the mapping file, just use the address */
1251 return address;
1252 }
1253 return ret;
1254 }
1255
e8251298 1256}
This page took 0.096103 seconds and 5 git commands to generate.