tmf: Make sure the request scheduler threads end gracefully
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng2.kernel.ui / src / org / eclipse / linuxtools / internal / lttng2 / kernel / ui / views / controlflow / ControlFlowView.java
index fe9cb3f4c6736fdb9254eea479c5da549d8a7f20..fb6eb79bba16c17dc7b9cd56b8e1e22278b672ef 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2012 Ericsson\r
- *\r
- * All rights reserved. This program and the accompanying materials are\r
- * made available under the terms of the Eclipse Public License v1.0 which\r
- * accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *   Patrick Tasse - Initial API and implementation\r
- *******************************************************************************/\r
-\r
-package org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.controlflow;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.Collections;\r
-import java.util.Comparator;\r
-import java.util.List;\r
-\r
-import org.eclipse.core.runtime.IProgressMonitor;\r
-import org.eclipse.core.runtime.NullProgressMonitor;\r
-import org.eclipse.jface.action.Action;\r
-import org.eclipse.jface.action.IToolBarManager;\r
-import org.eclipse.jface.action.Separator;\r
-import org.eclipse.jface.viewers.ILabelProviderListener;\r
-import org.eclipse.jface.viewers.ITableLabelProvider;\r
-import org.eclipse.jface.viewers.ITreeContentProvider;\r
-import org.eclipse.jface.viewers.Viewer;\r
-import org.eclipse.linuxtools.internal.lttng2.kernel.core.Attributes;\r
-import org.eclipse.linuxtools.internal.lttng2.kernel.ui.Messages;\r
-import org.eclipse.linuxtools.lttng2.kernel.core.trace.CtfKernelTrace;\r
-import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTimestamp;\r
-import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;\r
-import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;\r
-import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;\r
-import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;\r
-import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;\r
-import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;\r
-import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;\r
-import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentSelectedSignal;\r
-import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;\r
-import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;\r
-import org.eclipse.linuxtools.tmf.core.signal.TmfStateSystemBuildCompleted;\r
-import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;\r
-import org.eclipse.linuxtools.tmf.core.statesystem.IStateSystemQuerier;\r
-import org.eclipse.linuxtools.tmf.core.statesystem.IStateSystemQuerier2;\r
-import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;\r
-import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment;\r
-import org.eclipse.linuxtools.tmf.ui.views.TmfView;\r
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphRangeListener;\r
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphSelectionListener;\r
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphTimeListener;\r
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphCombo;\r
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent;\r
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphSelectionEvent;\r
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTimeEvent;\r
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent;\r
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;\r
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeEvent;\r
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils;\r
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.Resolution;\r
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.graphics.Image;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.swt.widgets.Display;\r
-import org.eclipse.swt.widgets.TreeColumn;\r
-import org.eclipse.ui.IActionBars;\r
-\r
-/**\r
- * The Control Flow view main object\r
- *\r
- */\r
-public class ControlFlowView extends TmfView {\r
-\r
-    // ------------------------------------------------------------------------\r
-    // Constants\r
-    // ------------------------------------------------------------------------\r
-\r
-    /**\r
-     * View ID.\r
-     */\r
-    public static final String ID = "org.eclipse.linuxtools.lttng2.kernel.ui.views.controlflow"; //$NON-NLS-1$\r
-\r
-    /**\r
-     * Initial time range\r
-     */\r
-    private static final long INITIAL_WINDOW_OFFSET = (1L * 100  * 1000 * 1000); // .1sec\r
-\r
-    private static final String PROCESS_COLUMN    = Messages.ControlFlowView_processColumn;\r
-    private static final String TID_COLUMN        = Messages.ControlFlowView_tidColumn;\r
-    private static final String PTID_COLUMN       = Messages.ControlFlowView_ptidColumn;\r
-    private static final String BIRTH_TIME_COLUMN = Messages.ControlFlowView_birthTimeColumn;\r
-    private static final String TRACE_COLUMN      = Messages.ControlFlowView_traceColumn;\r
-\r
-    private final String[] COLUMN_NAMES = new String[] {\r
-            PROCESS_COLUMN,\r
-            TID_COLUMN,\r
-            PTID_COLUMN,\r
-            BIRTH_TIME_COLUMN,\r
-            TRACE_COLUMN\r
-    };\r
-\r
-    /**\r
-     * Redraw state enum\r
-     */\r
-    private enum State { IDLE, BUSY, PENDING };\r
-\r
-    // ------------------------------------------------------------------------\r
-    // Fields\r
-    // ------------------------------------------------------------------------\r
-\r
-    // The timegraph combo\r
-    private TimeGraphCombo fTimeGraphCombo;\r
-\r
-    // The selected experiment\r
-    private TmfExperiment<ITmfEvent> fSelectedExperiment;\r
-\r
-    // The timegraph entry list\r
-    private ArrayList<ControlFlowEntry> fEntryList;\r
-\r
-    // The time graph entry list synchronization object\r
-    final private Object fEntryListSyncObj = new Object();\r
-\r
-    // The start time\r
-    private long fStartTime;\r
-\r
-    // The end time\r
-    private long fEndTime;\r
-\r
-    // The display width\r
-    private final int fDisplayWidth;\r
-\r
-    // The zoom thread\r
-    private ZoomThread fZoomThread;\r
-\r
-    // The next resource action\r
-    private Action fNextResourceAction;\r
-\r
-    // The previous resource action\r
-    private Action fPreviousResourceAction;\r
-\r
-    // A comparator class\r
-    private final ControlFlowEntryComparator fControlFlowEntryComparator = new ControlFlowEntryComparator();\r
-\r
-    // The redraw state used to prevent unnecessary queuing of display runnables\r
-    private State fRedrawState = State.IDLE;\r
-\r
-    // The redraw synchronization object\r
-    final private Object fSyncObj = new Object();\r
-\r
-    // ------------------------------------------------------------------------\r
-    // Classes\r
-    // ------------------------------------------------------------------------\r
-\r
-    private class TreeContentProvider implements ITreeContentProvider {\r
-\r
-        @Override\r
-        public void dispose() {\r
-        }\r
-\r
-        @Override\r
-        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {\r
-        }\r
-\r
-        @Override\r
-        public Object[] getElements(Object inputElement) {\r
-            return (ITimeGraphEntry[]) inputElement;\r
-        }\r
-\r
-        @Override\r
-        public Object[] getChildren(Object parentElement) {\r
-            ITimeGraphEntry entry = (ITimeGraphEntry) parentElement;\r
-            return entry.getChildren();\r
-        }\r
-\r
-        @Override\r
-        public Object getParent(Object element) {\r
-            ITimeGraphEntry entry = (ITimeGraphEntry) element;\r
-            return entry.getParent();\r
-        }\r
-\r
-        @Override\r
-        public boolean hasChildren(Object element) {\r
-            ITimeGraphEntry entry = (ITimeGraphEntry) element;\r
-            return entry.hasChildren();\r
-        }\r
-\r
-    }\r
-\r
-    private class TreeLabelProvider implements ITableLabelProvider {\r
-\r
-        @Override\r
-        public void addListener(ILabelProviderListener listener) {\r
-        }\r
-\r
-        @Override\r
-        public void dispose() {\r
-        }\r
-\r
-        @Override\r
-        public boolean isLabelProperty(Object element, String property) {\r
-            return false;\r
-        }\r
-\r
-        @Override\r
-        public void removeListener(ILabelProviderListener listener) {\r
-        }\r
-\r
-        @Override\r
-        public Image getColumnImage(Object element, int columnIndex) {\r
-            return null;\r
-        }\r
-\r
-        @Override\r
-        public String getColumnText(Object element, int columnIndex) {\r
-            ControlFlowEntry entry = (ControlFlowEntry) element;\r
-            if (columnIndex == 0) {\r
-                return entry.getName();\r
-            } else if (columnIndex == 1) {\r
-                return Integer.toString(entry.getThreadId());\r
-            } else if (columnIndex == 2) {\r
-                if (entry.getParentThreadId() > 0) {\r
-                    return Integer.toString(entry.getParentThreadId());\r
-                }\r
-            } else if (columnIndex == 3) {\r
-                return Utils.formatTime(entry.getBirthTime(), TimeFormat.ABSOLUTE, Resolution.NANOSEC);\r
-            } else if (columnIndex == 4) {\r
-                return entry.getTrace().getName();\r
-            }\r
-            return ""; //$NON-NLS-1$\r
-        }\r
-\r
-    }\r
-\r
-    private static class ControlFlowEntryComparator implements Comparator<ITimeGraphEntry> {\r
-\r
-        @Override\r
-        public int compare(ITimeGraphEntry o1, ITimeGraphEntry o2) {\r
-            int result = 0;\r
-\r
-            if ((o1 instanceof ControlFlowEntry) && (o2 instanceof ControlFlowEntry)) {\r
-                ControlFlowEntry entry1 = (ControlFlowEntry) o1;\r
-                ControlFlowEntry entry2 = (ControlFlowEntry) o2;\r
-                result = entry1.getTrace().getStartTime().compareTo(entry2.getTrace().getStartTime());\r
-                if (result == 0) {\r
-                    result = entry1.getTrace().getName().compareTo(entry2.getTrace().getName());\r
-                }\r
-                if (result == 0) {\r
-                    result = entry1.getThreadId() < entry2.getThreadId() ? -1 : entry1.getThreadId() > entry2.getThreadId() ? 1 : 0;\r
-                }\r
-            }\r
-\r
-            if (result == 0) {\r
-                result = o1.getStartTime() < o2.getStartTime() ? -1 : o1.getStartTime() > o2.getStartTime() ? 1 : 0;\r
-            }\r
-\r
-            return result;\r
-        }\r
-    }\r
-\r
-\r
-    private class ZoomThread extends Thread {\r
-        private final long fZoomStartTime;\r
-        private final long fZoomEndTime;\r
-        private final long fResolution;\r
-        private final IProgressMonitor fMonitor;\r
-\r
-        public ZoomThread(long startTime, long endTime) {\r
-            super("ControlFlowView zoom"); //$NON-NLS-1$\r
-            fZoomStartTime = startTime;\r
-            fZoomEndTime = endTime;\r
-            fResolution = Math.max(1, (fZoomEndTime - fZoomStartTime) / fDisplayWidth);\r
-            fMonitor = new NullProgressMonitor();\r
-        }\r
-\r
-        @Override\r
-        public void run() {\r
-            ArrayList<ControlFlowEntry> entryList = null;\r
-            synchronized (fEntryListSyncObj) {\r
-                entryList = fEntryList;\r
-            }\r
-            if (entryList == null) {\r
-                return;\r
-            }\r
-            for (ControlFlowEntry entry : entryList) {\r
-                if (fMonitor.isCanceled()) {\r
-                    break;\r
-                }\r
-                zoom(entry, fMonitor);\r
-            }\r
-        }\r
-\r
-        private void zoom(ControlFlowEntry entry, IProgressMonitor monitor) {\r
-            if (fZoomStartTime <= fStartTime && fZoomEndTime >= fEndTime) {\r
-                entry.setZoomedEventList(null);\r
-            } else {\r
-                List<ITimeEvent> zoomedEventList = getEventList(entry, fZoomStartTime, fZoomEndTime, fResolution, monitor);\r
-                if (zoomedEventList != null) {\r
-                    entry.setZoomedEventList(zoomedEventList);\r
-                }\r
-            }\r
-            redraw();\r
-            for (ControlFlowEntry child : entry.getChildren()) {\r
-                if (fMonitor.isCanceled()) {\r
-                    return;\r
-                }\r
-                zoom(child, monitor);\r
-            }\r
-        }\r
-\r
-        public void cancel() {\r
-            fMonitor.setCanceled(true);\r
-        }\r
-    }\r
-\r
-    // ------------------------------------------------------------------------\r
-    // Constructors\r
-    // ------------------------------------------------------------------------\r
-\r
-    /**\r
-     * Constructor\r
-     */\r
-    public ControlFlowView() {\r
-        super(ID);\r
-        fDisplayWidth = Display.getDefault().getBounds().width;\r
-    }\r
-\r
-    // ------------------------------------------------------------------------\r
-    // ViewPart\r
-    // ------------------------------------------------------------------------\r
-\r
-    /* (non-Javadoc)\r
-     * @see org.eclipse.linuxtools.tmf.ui.views.TmfView#createPartControl(org.eclipse.swt.widgets.Composite)\r
-     */\r
-    @Override\r
-    public void createPartControl(Composite parent) {\r
-        fTimeGraphCombo = new TimeGraphCombo(parent, SWT.NONE);\r
-\r
-        fTimeGraphCombo.setTreeContentProvider(new TreeContentProvider());\r
-\r
-        fTimeGraphCombo.setTreeLabelProvider(new TreeLabelProvider());\r
-\r
-        fTimeGraphCombo.setTimeGraphProvider(new ControlFlowPresentationProvider());\r
-\r
-        fTimeGraphCombo.setTreeColumns(COLUMN_NAMES);\r
-\r
-        fTimeGraphCombo.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() {\r
-            @Override\r
-            public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) {\r
-                final long startTime = event.getStartTime();\r
-                final long endTime = event.getEndTime();\r
-                TmfTimeRange range = new TmfTimeRange(new CtfTmfTimestamp(startTime), new CtfTmfTimestamp(endTime));\r
-                TmfTimestamp time = new CtfTmfTimestamp(fTimeGraphCombo.getTimeGraphViewer().getSelectedTime());\r
-                broadcast(new TmfRangeSynchSignal(ControlFlowView.this, range, time));\r
-                if (fZoomThread != null) {\r
-                    fZoomThread.cancel();\r
-                }\r
-                startZoomThread(startTime, endTime);\r
-            }\r
-        });\r
-\r
-        fTimeGraphCombo.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() {\r
-            @Override\r
-            public void timeSelected(TimeGraphTimeEvent event) {\r
-                long time = event.getTime();\r
-                broadcast(new TmfTimeSynchSignal(ControlFlowView.this, new CtfTmfTimestamp(time)));\r
-            }\r
-        });\r
-\r
-        fTimeGraphCombo.addSelectionListener(new ITimeGraphSelectionListener() {\r
-            @Override\r
-            public void selectionChanged(TimeGraphSelectionEvent event) {\r
-                //ITimeGraphEntry selection = event.getSelection();\r
-            }\r
-        });\r
-\r
-        fTimeGraphCombo.getTimeGraphViewer().setTimeCalendarFormat(true);\r
-\r
-        final Thread thread = new Thread("ControlFlowView build") { //$NON-NLS-1$\r
-            @Override\r
-            public void run() {\r
-                if (TmfExperiment.getCurrentExperiment() != null) {\r
-                    selectExperiment(TmfExperiment.getCurrentExperiment());\r
-                }\r
-            }\r
-        };\r
-        thread.start();\r
-\r
-        // View Action Handling\r
-        makeActions();\r
-        contributeToActionBars();\r
-    }\r
-\r
-    /* (non-Javadoc)\r
-     * @see org.eclipse.ui.part.WorkbenchPart#setFocus()\r
-     */\r
-    @Override\r
-    public void setFocus() {\r
-        fTimeGraphCombo.setFocus();\r
-    }\r
-\r
-    // ------------------------------------------------------------------------\r
-    // Signal handlers\r
-    // ------------------------------------------------------------------------\r
-\r
-    /**\r
-     * Handler for the experiment selected signal\r
-     *\r
-     * @param signal\r
-     *            The signal that's received\r
-     */\r
-    @TmfSignalHandler\r
-    public void experimentSelected(final TmfExperimentSelectedSignal<? extends ITmfEvent> signal) {\r
-        if (signal.getExperiment().equals(fSelectedExperiment)) {\r
-            return;\r
-        }\r
-\r
-        final Thread thread = new Thread("ControlFlowView build") { //$NON-NLS-1$\r
-            @Override\r
-            public void run() {\r
-                selectExperiment(signal.getExperiment());\r
-            }\r
-        };\r
-        thread.start();\r
-    }\r
-\r
-    /**\r
-     * Handler for the synch signal\r
-     *\r
-     * @param signal\r
-     *            The signal that's received\r
-     */\r
-    @TmfSignalHandler\r
-    public void synchToTime(final TmfTimeSynchSignal signal) {\r
-        if (signal.getSource() == this || fSelectedExperiment == null || fSelectedExperiment.getTraces() == null) {\r
-            return;\r
-        }\r
-        final long time = signal.getCurrentTime().normalize(0, -9).getValue();\r
-\r
-        int thread = -1;\r
-        for (ITmfTrace<?> trace : fSelectedExperiment.getTraces()) {\r
-            if (thread > 0) {\r
-                break;\r
-            }\r
-            if (trace instanceof CtfKernelTrace) {\r
-                CtfKernelTrace ctfKernelTrace = (CtfKernelTrace) trace;\r
-                IStateSystemQuerier ssq = ctfKernelTrace.getStateSystem();\r
-                if (time >= ssq.getStartTime() && time <= ssq.getCurrentEndTime()) {\r
-                    List<Integer> currentThreadQuarks = ssq.getQuarks(Attributes.CPUS, "*", Attributes.CURRENT_THREAD);  //$NON-NLS-1$\r
-                    for (int currentThreadQuark : currentThreadQuarks) {\r
-                        try {\r
-                            ITmfStateInterval currentThreadInterval = ssq.querySingleState(time, currentThreadQuark);\r
-                            int currentThread = currentThreadInterval.getStateValue().unboxInt();\r
-                            if (currentThread > 0) {\r
-                                int statusQuark = ssq.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThread), Attributes.STATUS);\r
-                                ITmfStateInterval statusInterval = ssq.querySingleState(time, statusQuark);\r
-                                if (statusInterval.getStartTime() == time) {\r
-                                    thread = currentThread;\r
-                                    break;\r
-                                }\r
-                            }\r
-                        } catch (AttributeNotFoundException e) {\r
-                            e.printStackTrace();\r
-                        } catch (TimeRangeException e) {\r
-                            e.printStackTrace();\r
-                        } catch (StateValueTypeException e) {\r
-                            e.printStackTrace();\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        final int selectedThread = thread;\r
-\r
-        Display.getDefault().asyncExec(new Runnable() {\r
-            @Override\r
-            public void run() {\r
-                if (fTimeGraphCombo.isDisposed()) {\r
-                    return;\r
-                }\r
-                fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, true);\r
-                startZoomThread(fTimeGraphCombo.getTimeGraphViewer().getTime0(), fTimeGraphCombo.getTimeGraphViewer().getTime1());\r
-\r
-                if (selectedThread > 0) {\r
-                    for (Object element : fTimeGraphCombo.getTimeGraphViewer().getExpandedElements()) {\r
-                        if (element instanceof ControlFlowEntry) {\r
-                            ControlFlowEntry entry = (ControlFlowEntry) element;\r
-                            if (entry.getThreadId() == selectedThread) {\r
-                                fTimeGraphCombo.setSelection(entry);\r
-                                break;\r
-                            }\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        });\r
-    }\r
-\r
-    /**\r
-     * Handler for the range sync signal\r
-     *\r
-     * @param signal\r
-     *            The signal that's received\r
-     */\r
-    @TmfSignalHandler\r
-    public void synchToRange(final TmfRangeSynchSignal signal) {\r
-        if (signal.getSource() == this || fSelectedExperiment == null) {\r
-            return;\r
-        }\r
-        final long startTime = signal.getCurrentRange().getStartTime().normalize(0, -9).getValue();\r
-        final long endTime = signal.getCurrentRange().getEndTime().normalize(0, -9).getValue();\r
-        final long time = signal.getCurrentTime().normalize(0, -9).getValue();\r
-        Display.getDefault().asyncExec(new Runnable() {\r
-            @Override\r
-            public void run() {\r
-                if (fTimeGraphCombo.isDisposed()) {\r
-                    return;\r
-                }\r
-                fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);\r
-                fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, false);\r
-                startZoomThread(startTime, endTime);\r
-            }\r
-        });\r
-    }\r
-\r
-    /**\r
-     * Handler for the state system build completed signal\r
-     *\r
-     * @param signal\r
-     *            The signal that's received\r
-     */\r
-    @TmfSignalHandler\r
-    public void stateSystemBuildCompleted (final TmfStateSystemBuildCompleted signal) {\r
-        final TmfExperiment<?> selectedExperiment = fSelectedExperiment;\r
-        if (selectedExperiment == null || selectedExperiment.getTraces() == null) {\r
-            return;\r
-        }\r
-        for (ITmfTrace<?> trace : selectedExperiment.getTraces()) {\r
-            if (trace == signal.getTrace() && trace instanceof CtfKernelTrace) {\r
-                final Thread thread = new Thread("ControlFlowView build") { //$NON-NLS-1$\r
-                    @Override\r
-                    public void run() {\r
-                        // rebuild the model\r
-                        selectExperiment(selectedExperiment);\r
-                    }\r
-                };\r
-                thread.start();\r
-            }\r
-        }\r
-    }\r
-\r
-    // ------------------------------------------------------------------------\r
-    // Internal\r
-    // ------------------------------------------------------------------------\r
-\r
-    @SuppressWarnings("unchecked")\r
-    private void selectExperiment(TmfExperiment<?> experiment) {\r
-        fStartTime = Long.MAX_VALUE;\r
-        fEndTime = Long.MIN_VALUE;\r
-        fSelectedExperiment = (TmfExperiment<ITmfEvent>) experiment;\r
-        ArrayList<ControlFlowEntry> rootList = new ArrayList<ControlFlowEntry>();\r
-        for (ITmfTrace<?> trace : experiment.getTraces()) {\r
-            if (trace instanceof CtfKernelTrace) {\r
-                ArrayList<ControlFlowEntry> entryList = new ArrayList<ControlFlowEntry>();\r
-                CtfKernelTrace ctfKernelTrace = (CtfKernelTrace) trace;\r
-                IStateSystemQuerier ssq = ctfKernelTrace.getStateSystem();\r
-                long start = ssq.getStartTime();\r
-                long end = ssq.getCurrentEndTime() + 1;\r
-                fStartTime = Math.min(fStartTime, start);\r
-                fEndTime = Math.max(fEndTime, end);\r
-                List<Integer> threadQuarks = ssq.getQuarks(Attributes.THREADS, "*"); //$NON-NLS-1$\r
-                for (int threadQuark : threadQuarks) {\r
-                    String threadName = ssq.getAttributeName(threadQuark);\r
-                    int threadId = -1;\r
-                    try {\r
-                        threadId = Integer.parseInt(threadName);\r
-                    } catch (NumberFormatException e1) {\r
-                        continue;\r
-                    }\r
-                    if (threadId == 0) { // ignore the swapper thread\r
-                        continue;\r
-                    }\r
-                    int execNameQuark = -1;\r
-                    try {\r
-                        try {\r
-                            execNameQuark = ssq.getQuarkRelative(threadQuark, Attributes.EXEC_NAME);\r
-                        } catch (AttributeNotFoundException e) {\r
-                            continue;\r
-                        }\r
-                        int ppidQuark = ssq.getQuarkRelative(threadQuark, Attributes.PPID);\r
-                        List<ITmfStateInterval> execNameIntervals = ssq.queryHistoryRange(execNameQuark, start, end - 1);\r
-                        long birthTime = -1;\r
-                        for (ITmfStateInterval execNameInterval : execNameIntervals) {\r
-                            if (!execNameInterval.getStateValue().isNull() && execNameInterval.getStateValue().getType() == 1) {\r
-                                String execName = execNameInterval.getStateValue().unboxStr();\r
-                                long startTime = execNameInterval.getStartTime();\r
-                                long endTime = execNameInterval.getEndTime() + 1;\r
-                                if (birthTime == -1) {\r
-                                    birthTime = startTime;\r
-                                }\r
-                                int ppid = -1;\r
-                                if (ppidQuark != -1) {\r
-                                    ITmfStateInterval ppidInterval = ssq.querySingleState(startTime, ppidQuark);\r
-                                    ppid = ppidInterval.getStateValue().unboxInt();\r
-                                }\r
-                                ControlFlowEntry entry = new ControlFlowEntry(threadQuark, ctfKernelTrace, execName, threadId, ppid, birthTime, startTime, endTime);\r
-                                entryList.add(entry);\r
-                                entry.addEvent(new TimeEvent(entry, startTime, endTime - startTime));\r
-                            } else {\r
-                                birthTime = -1;\r
-                            }\r
-                        }\r
-                    } catch (AttributeNotFoundException e) {\r
-                        e.printStackTrace();\r
-                    } catch (TimeRangeException e) {\r
-                        e.printStackTrace();\r
-                    } catch (StateValueTypeException e) {\r
-                        e.printStackTrace();\r
-                    }\r
-                }\r
-                buildTree(entryList, rootList);\r
-            }\r
-            Collections.sort(rootList, fControlFlowEntryComparator);\r
-            synchronized (fEntryListSyncObj) {\r
-                fEntryList = (ArrayList<ControlFlowEntry>) rootList.clone();\r
-            }\r
-            refresh(INITIAL_WINDOW_OFFSET);\r
-        }\r
-        for (ControlFlowEntry entry : rootList) {\r
-            buildStatusEvents(entry);\r
-        }\r
-    }\r
-\r
-    private static void buildTree(ArrayList<ControlFlowEntry> entryList,\r
-            ArrayList<ControlFlowEntry> rootList) {\r
-        for (ControlFlowEntry entry : entryList) {\r
-            boolean root = true;\r
-            if (entry.getParentThreadId() > 0) {\r
-                for (ControlFlowEntry parent : entryList) {\r
-                    if (parent.getThreadId() == entry.getParentThreadId() &&\r
-                            entry.getStartTime() >= parent.getStartTime() &&\r
-                            entry.getStartTime() <= parent.getEndTime()) {\r
-                        parent.addChild(entry);\r
-                        root = false;\r
-                        break;\r
-                    }\r
-                }\r
-            }\r
-            if (root) {\r
-                rootList.add(entry);\r
-            }\r
-        }\r
-    }\r
-\r
-    private void buildStatusEvents(ControlFlowEntry entry) {\r
-        IStateSystemQuerier ssq = entry.getTrace().getStateSystem();\r
-        long start = ssq.getStartTime();\r
-        long end = ssq.getCurrentEndTime() + 1;\r
-        long resolution = Math.max(1, (end - start) / fDisplayWidth);\r
-        List<ITimeEvent> eventList = getEventList(entry, entry.getStartTime(), entry.getEndTime(), resolution, new NullProgressMonitor());\r
-        entry.setEventList(eventList);\r
-        redraw();\r
-        for (ITimeGraphEntry child : entry.getChildren()) {\r
-            buildStatusEvents((ControlFlowEntry) child);\r
-        }\r
-    }\r
-\r
-    private static List<ITimeEvent> getEventList(ControlFlowEntry entry,\r
-            long startTime, long endTime, long resolution,\r
-            IProgressMonitor monitor) {\r
-        startTime = Math.max(startTime, entry.getStartTime());\r
-        endTime = Math.min(endTime, entry.getEndTime());\r
-        if (endTime <= startTime) {\r
-            return null;\r
-        }\r
-        IStateSystemQuerier2 ssq = (IStateSystemQuerier2) entry.getTrace().getStateSystem();\r
-        List<ITimeEvent> eventList = null;\r
-        try {\r
-            int statusQuark = ssq.getQuarkRelative(entry.getThreadQuark(), Attributes.STATUS);\r
-            List<ITmfStateInterval> statusIntervals = ssq.queryHistoryRange(statusQuark, startTime, endTime - 1, resolution, monitor);\r
-            eventList = new ArrayList<ITimeEvent>(statusIntervals.size());\r
-            long lastEndTime = -1;\r
-            for (ITmfStateInterval statusInterval : statusIntervals) {\r
-                if (monitor.isCanceled()) {\r
-                    return null;\r
-                }\r
-                long time = statusInterval.getStartTime();\r
-                long duration = statusInterval.getEndTime() - time + 1;\r
-                int status = -1;\r
-                try {\r
-                    status = statusInterval.getStateValue().unboxInt();\r
-                } catch (StateValueTypeException e) {\r
-                    e.printStackTrace();\r
-                }\r
-                if (lastEndTime != time && lastEndTime != -1) {\r
-                    eventList.add(new ControlFlowEvent(entry, lastEndTime, time - lastEndTime, 0));\r
-                }\r
-                eventList.add(new ControlFlowEvent(entry, time, duration, status));\r
-                lastEndTime = time + duration;\r
-            }\r
-        } catch (AttributeNotFoundException e) {\r
-            e.printStackTrace();\r
-        } catch (TimeRangeException e) {\r
-            e.printStackTrace();\r
-        }\r
-        return eventList;\r
-    }\r
-\r
-    private void refresh(final long windowRange) {\r
-        Display.getDefault().asyncExec(new Runnable() {\r
-            @Override\r
-            public void run() {\r
-                if (fTimeGraphCombo.isDisposed()) {\r
-                    return;\r
-                }\r
-                ITimeGraphEntry[] entries = null;\r
-                synchronized (fEntryListSyncObj) {\r
-                    entries = fEntryList.toArray(new ITimeGraphEntry[0]);\r
-                }\r
-                Arrays.sort(entries, fControlFlowEntryComparator);\r
-                fTimeGraphCombo.setInput(entries);\r
-                fTimeGraphCombo.getTimeGraphViewer().setTimeBounds(fStartTime, fEndTime);\r
-\r
-                long endTime = fStartTime + windowRange;\r
-\r
-                if (fEndTime < endTime) {\r
-                    endTime = fEndTime;\r
-                }\r
-                fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(fStartTime, endTime);\r
-                for (TreeColumn column : fTimeGraphCombo.getTreeViewer().getTree().getColumns()) {\r
-                    column.pack();\r
-                }\r
-\r
-                startZoomThread(fStartTime, endTime);\r
-            }\r
-        });\r
-    }\r
-\r
-    private void redraw() {\r
-        synchronized (fSyncObj) {\r
-            if (fRedrawState == State.IDLE) {\r
-                fRedrawState = State.BUSY;\r
-            } else {\r
-                fRedrawState = State.PENDING;\r
-                return;\r
-            }\r
-        }\r
-        Display.getDefault().asyncExec(new Runnable() {\r
-            @Override\r
-            public void run() {\r
-                if (fTimeGraphCombo.isDisposed()) {\r
-                    return;\r
-                }\r
-                fTimeGraphCombo.redraw();\r
-                fTimeGraphCombo.update();\r
-                synchronized (fSyncObj) {\r
-                    if (fRedrawState == State.PENDING) {\r
-                        fRedrawState = State.IDLE;\r
-                        redraw();\r
-                    } else {\r
-                        fRedrawState = State.IDLE;\r
-                    }\r
-                }\r
-            }\r
-        });\r
-    }\r
-\r
-    private void startZoomThread(long startTime, long endTime) {\r
-        if (fZoomThread != null) {\r
-            fZoomThread.cancel();\r
-        }\r
-        fZoomThread = new ZoomThread(startTime, endTime);\r
-        fZoomThread.start();\r
-    }\r
-\r
-    private void makeActions() {\r
-        fPreviousResourceAction = fTimeGraphCombo.getTimeGraphViewer().getPreviousItemAction();\r
-        fPreviousResourceAction.setText(Messages.ControlFlowView_previousProcessActionNameText);\r
-        fPreviousResourceAction.setToolTipText(Messages.ControlFlowView_previousProcessActionToolTipText);\r
-        fNextResourceAction = fTimeGraphCombo.getTimeGraphViewer().getNextItemAction();\r
-        fNextResourceAction.setText(Messages.ControlFlowView_nextProcessActionNameText);\r
-        fNextResourceAction.setToolTipText(Messages.ControlFlowView_nextProcessActionToolTipText);\r
-    }\r
-\r
-    private void contributeToActionBars() {\r
-        IActionBars bars = getViewSite().getActionBars();\r
-        fillLocalToolBar(bars.getToolBarManager());\r
-    }\r
-\r
-    private void fillLocalToolBar(IToolBarManager manager) {\r
-        manager.add(fTimeGraphCombo.getTimeGraphViewer().getShowLegendAction());\r
-        manager.add(new Separator());\r
-        manager.add(fTimeGraphCombo.getTimeGraphViewer().getResetScaleAction());\r
-        manager.add(fTimeGraphCombo.getTimeGraphViewer().getPreviousEventAction());\r
-        manager.add(fTimeGraphCombo.getTimeGraphViewer().getNextEventAction());\r
-        manager.add(fPreviousResourceAction);\r
-        manager.add(fNextResourceAction);\r
-        manager.add(fTimeGraphCombo.getTimeGraphViewer().getZoomInAction());\r
-        manager.add(fTimeGraphCombo.getTimeGraphViewer().getZoomOutAction());\r
-        manager.add(new Separator());\r
-    }\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Ericsson, Ã‰cole Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Patrick Tasse - Initial API and implementation
+ *   Geneviève Bastien - Move code to provide base classes for time graph view
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.controlflow;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.linuxtools.internal.lttng2.kernel.core.Attributes;
+import org.eclipse.linuxtools.internal.lttng2.kernel.ui.Activator;
+import org.eclipse.linuxtools.internal.lttng2.kernel.ui.Messages;
+import org.eclipse.linuxtools.lttng2.kernel.core.trace.LttngKernelTrace;
+import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
+import org.eclipse.linuxtools.tmf.core.exceptions.StateSystemDisposedException;
+import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
+import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
+import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;
+import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
+import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager;
+import org.eclipse.linuxtools.tmf.ui.views.timegraph.AbstractTimeGraphView;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeEvent;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeLinkEvent;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.Resolution;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
+
+/**
+ * The Control Flow view main object
+ *
+ */
+public class ControlFlowView extends AbstractTimeGraphView {
+
+    // ------------------------------------------------------------------------
+    // Constants
+    // ------------------------------------------------------------------------
+
+    /**
+     * View ID.
+     */
+    public static final String ID = "org.eclipse.linuxtools.lttng2.kernel.ui.views.controlflow"; //$NON-NLS-1$
+
+    private static final String PROCESS_COLUMN = Messages.ControlFlowView_processColumn;
+    private static final String TID_COLUMN = Messages.ControlFlowView_tidColumn;
+    private static final String PTID_COLUMN = Messages.ControlFlowView_ptidColumn;
+    private static final String BIRTH_TIME_COLUMN = Messages.ControlFlowView_birthTimeColumn;
+    private static final String TRACE_COLUMN = Messages.ControlFlowView_traceColumn;
+
+    private static final String[] COLUMN_NAMES = new String[] {
+            PROCESS_COLUMN,
+            TID_COLUMN,
+            PTID_COLUMN,
+            BIRTH_TIME_COLUMN,
+            TRACE_COLUMN
+    };
+
+    private static final String[] FILTER_COLUMN_NAMES = new String[] {
+            PROCESS_COLUMN,
+            TID_COLUMN
+    };
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    /**
+     * Constructor
+     */
+    public ControlFlowView() {
+        super(ID, new ControlFlowPresentationProvider());
+        setTreeColumns(COLUMN_NAMES);
+        setTreeLabelProvider(new ControlFlowTreeLabelProvider());
+        setFilterColumns(FILTER_COLUMN_NAMES);
+        setEntryComparator(new ControlFlowEntryComparator());
+    }
+
+    @Override
+    protected void fillLocalToolBar(IToolBarManager manager) {
+        IDialogSettings settings = Activator.getDefault().getDialogSettings();
+        IDialogSettings section = settings.getSection(getClass().getName());
+        if (section == null) {
+            section = settings.addNewSection(getClass().getName());
+        }
+        manager.add(getTimeGraphCombo().getTimeGraphViewer().getHideArrowsAction(section));
+        super.fillLocalToolBar(manager);
+    }
+
+    @Override
+    protected String getNextText() {
+        return Messages.ControlFlowView_nextProcessActionNameText;
+    }
+
+    @Override
+    protected String getNextTooltip() {
+        return Messages.ControlFlowView_nextProcessActionToolTipText;
+    }
+
+    @Override
+    protected String getPrevText() {
+        return Messages.ControlFlowView_previousProcessActionNameText;
+    }
+
+    @Override
+    protected String getPrevTooltip() {
+        return Messages.ControlFlowView_previousProcessActionToolTipText;
+    }
+
+    private static class ControlFlowEntryComparator implements Comparator<ITimeGraphEntry> {
+
+        @Override
+        public int compare(ITimeGraphEntry o1, ITimeGraphEntry o2) {
+
+            int result = 0;
+
+            if ((o1 instanceof ControlFlowEntry) && (o2 instanceof ControlFlowEntry)) {
+                ControlFlowEntry entry1 = (ControlFlowEntry) o1;
+                ControlFlowEntry entry2 = (ControlFlowEntry) o2;
+                result = entry1.getTrace().getStartTime().compareTo(entry2.getTrace().getStartTime());
+                if (result == 0) {
+                    result = entry1.getTrace().getName().compareTo(entry2.getTrace().getName());
+                }
+                if (result == 0) {
+                    result = entry1.getThreadId() < entry2.getThreadId() ? -1 : entry1.getThreadId() > entry2.getThreadId() ? 1 : 0;
+                }
+            }
+
+            if (result == 0) {
+                result = o1.getStartTime() < o2.getStartTime() ? -1 : o1.getStartTime() > o2.getStartTime() ? 1 : 0;
+            }
+
+            return result;
+        }
+    }
+
+    /**
+     * @author gbastien
+     *
+     */
+    protected static class ControlFlowTreeLabelProvider extends TreeLabelProvider {
+
+        @Override
+        public String getColumnText(Object element, int columnIndex) {
+            ControlFlowEntry entry = (ControlFlowEntry) element;
+
+            if (COLUMN_NAMES[columnIndex].equals(Messages.ControlFlowView_processColumn)) {
+                return entry.getName();
+            } else if (COLUMN_NAMES[columnIndex].equals(Messages.ControlFlowView_tidColumn)) {
+                return Integer.toString(entry.getThreadId());
+            } else if (COLUMN_NAMES[columnIndex].equals(Messages.ControlFlowView_ptidColumn)) {
+                if (entry.getParentThreadId() > 0) {
+                    return Integer.toString(entry.getParentThreadId());
+                }
+            } else if (COLUMN_NAMES[columnIndex].equals(Messages.ControlFlowView_birthTimeColumn)) {
+                return Utils.formatTime(entry.getStartTime(), TimeFormat.CALENDAR, Resolution.NANOSEC);
+            } else if (COLUMN_NAMES[columnIndex].equals(Messages.ControlFlowView_traceColumn)) {
+                return entry.getTrace().getName();
+            }
+            return ""; //$NON-NLS-1$
+        }
+
+    }
+
+    // ------------------------------------------------------------------------
+    // Internal
+    // ------------------------------------------------------------------------
+
+    @Override
+    protected void buildEventList(final ITmfTrace trace, IProgressMonitor monitor) {
+        setStartTime(Long.MAX_VALUE);
+        setEndTime(Long.MIN_VALUE);
+
+        ArrayList<TimeGraphEntry> rootList = new ArrayList<TimeGraphEntry>();
+        for (ITmfTrace aTrace : fTraceManager.getActiveTraceSet()) {
+            if (monitor.isCanceled()) {
+                return;
+            }
+            if (aTrace instanceof LttngKernelTrace) {
+                ArrayList<TimeGraphEntry> entryList = new ArrayList<TimeGraphEntry>();
+                LttngKernelTrace ctfKernelTrace = (LttngKernelTrace) aTrace;
+                ITmfStateSystem ssq = ctfKernelTrace.getStateSystems().get(LttngKernelTrace.STATE_ID);
+                if (!ssq.waitUntilBuilt()) {
+                    return;
+                }
+                long start = ssq.getStartTime();
+                long end = ssq.getCurrentEndTime() + 1;
+                setStartTime(Math.min(getStartTime(), start));
+                setEndTime(Math.max(getEndTime(), end));
+                List<Integer> threadQuarks = ssq.getQuarks(Attributes.THREADS, "*"); //$NON-NLS-1$
+                for (int threadQuark : threadQuarks) {
+                    if (monitor.isCanceled()) {
+                        return;
+                    }
+                    String threadName = ssq.getAttributeName(threadQuark);
+                    int threadId = -1;
+                    try {
+                        threadId = Integer.parseInt(threadName);
+                    } catch (NumberFormatException e1) {
+                        continue;
+                    }
+                    if (threadId == 0) { // ignore the swapper thread
+                        continue;
+                    }
+                    int execNameQuark = -1;
+                    try {
+                        try {
+                            execNameQuark = ssq.getQuarkRelative(threadQuark, Attributes.EXEC_NAME);
+                        } catch (AttributeNotFoundException e) {
+                            continue;
+                        }
+                        int ppidQuark = ssq.getQuarkRelative(threadQuark, Attributes.PPID);
+                        List<ITmfStateInterval> execNameIntervals = ssq.queryHistoryRange(execNameQuark, start, end - 1);
+                        // use monitor when available in api
+                        if (monitor.isCanceled()) {
+                            return;
+                        }
+                        TimeGraphEntry entry = null;
+                        for (ITmfStateInterval execNameInterval : execNameIntervals) {
+                            if (monitor.isCanceled()) {
+                                return;
+                            }
+                            if (!execNameInterval.getStateValue().isNull() &&
+                                    execNameInterval.getStateValue().getType() == ITmfStateValue.Type.STRING) {
+                                String execName = execNameInterval.getStateValue().unboxStr();
+                                long startTime = execNameInterval.getStartTime();
+                                long endTime = execNameInterval.getEndTime() + 1;
+                                int ppid = -1;
+                                if (ppidQuark != -1) {
+                                    ITmfStateInterval ppidInterval = ssq.querySingleState(startTime, ppidQuark);
+                                    ppid = ppidInterval.getStateValue().unboxInt();
+                                }
+                                if (entry == null) {
+                                    entry = new ControlFlowEntry(threadQuark, ctfKernelTrace, execName, threadId, ppid, startTime, endTime);
+                                    entryList.add(entry);
+                                } else {
+                                    // update the name of the entry to the
+                                    // latest execName
+                                    entry.setName(execName);
+                                }
+                                entry.addEvent(new TimeEvent(entry, startTime, endTime - startTime));
+                            } else {
+                                entry = null;
+                            }
+                        }
+                    } catch (AttributeNotFoundException e) {
+                        e.printStackTrace();
+                    } catch (TimeRangeException e) {
+                        e.printStackTrace();
+                    } catch (StateValueTypeException e) {
+                        e.printStackTrace();
+                    } catch (StateSystemDisposedException e) {
+                        /* Ignored */
+                    }
+                }
+                buildTree(entryList, rootList);
+            }
+            Collections.sort(rootList, getEntryComparator());
+            putEntryList(trace, (ArrayList<TimeGraphEntry>) rootList.clone());
+
+            if (trace.equals(getTrace())) {
+                refresh();
+            }
+        }
+        for (TimeGraphEntry entry : rootList) {
+            if (monitor.isCanceled()) {
+                return;
+            }
+            buildStatusEvents(trace, entry, monitor);
+        }
+    }
+
+    private static void buildTree(ArrayList<TimeGraphEntry> entryList,
+            ArrayList<TimeGraphEntry> rootList) {
+        for (TimeGraphEntry listentry : entryList) {
+            ControlFlowEntry entry = (ControlFlowEntry) listentry;
+            boolean root = true;
+            if (entry.getParentThreadId() > 0) {
+                for (TimeGraphEntry parententry : entryList) {
+                    ControlFlowEntry parent = (ControlFlowEntry) parententry;
+                    if (parent.getThreadId() == entry.getParentThreadId() &&
+                            entry.getStartTime() >= parent.getStartTime() &&
+                            entry.getStartTime() <= parent.getEndTime()) {
+                        parent.addChild(entry);
+                        root = false;
+                        break;
+                    }
+                }
+            }
+            if (root) {
+                rootList.add(entry);
+            }
+        }
+    }
+
+    private void buildStatusEvents(ITmfTrace trace, TimeGraphEntry entry, IProgressMonitor monitor) {
+        ITmfStateSystem ssq = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID);
+
+        long start = ssq.getStartTime();
+        long end = ssq.getCurrentEndTime() + 1;
+        long resolution = Math.max(1, (end - start) / getDisplayWidth());
+        List<ITimeEvent> eventList = getEventList(entry, entry.getStartTime(), entry.getEndTime(), resolution, monitor);
+        if (monitor.isCanceled()) {
+            return;
+        }
+        entry.setEventList(eventList);
+        if (trace.equals(getTrace())) {
+            redraw();
+        }
+        for (ITimeGraphEntry child : entry.getChildren()) {
+            if (monitor.isCanceled()) {
+                return;
+            }
+            buildStatusEvents(trace, (TimeGraphEntry) child, monitor);
+        }
+    }
+
+    @Override
+    protected List<ITimeEvent> getEventList(TimeGraphEntry tgentry, long startTime, long endTime, long resolution, IProgressMonitor monitor) {
+        List<ITimeEvent> eventList = null;
+        if (!(tgentry instanceof ControlFlowEntry)) {
+            return eventList;
+        }
+        ControlFlowEntry entry = (ControlFlowEntry) tgentry;
+        final long realStart = Math.max(startTime, entry.getStartTime());
+        final long realEnd = Math.min(endTime, entry.getEndTime());
+        if (realEnd <= realStart) {
+            return null;
+        }
+        ITmfStateSystem ssq = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID);
+        try {
+            int statusQuark = ssq.getQuarkRelative(entry.getThreadQuark(), Attributes.STATUS);
+            List<ITmfStateInterval> statusIntervals = ssq.queryHistoryRange(statusQuark, realStart, realEnd - 1, resolution, monitor);
+            eventList = new ArrayList<ITimeEvent>(statusIntervals.size());
+            long lastEndTime = -1;
+            for (ITmfStateInterval statusInterval : statusIntervals) {
+                if (monitor.isCanceled()) {
+                    return null;
+                }
+                long time = statusInterval.getStartTime();
+                long duration = statusInterval.getEndTime() - time + 1;
+                int status = -1;
+                try {
+                    status = statusInterval.getStateValue().unboxInt();
+                } catch (StateValueTypeException e) {
+                    e.printStackTrace();
+                }
+                if (lastEndTime != time && lastEndTime != -1) {
+                    eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime));
+                }
+                eventList.add(new TimeEvent(entry, time, duration, status));
+                lastEndTime = time + duration;
+            }
+        } catch (AttributeNotFoundException e) {
+            e.printStackTrace();
+        } catch (TimeRangeException e) {
+            e.printStackTrace();
+        } catch (StateSystemDisposedException e) {
+            /* Ignored */
+        }
+        return eventList;
+    }
+
+    /**
+     * Returns a value corresponding to the selected entry.
+     *
+     * Used in conjunction with selectEntry to change the selected entry. If one
+     * of these methods is overridden in child class, then both should be.
+     *
+     * @param time
+     *            The currently selected time
+     * @return a value identifying the entry
+     */
+    private int getSelectionValue(long time) {
+        int thread = -1;
+        for (ITmfTrace trace : fTraceManager.getActiveTraceSet()) {
+            if (thread > 0) {
+                break;
+            }
+            if (trace instanceof LttngKernelTrace) {
+                LttngKernelTrace ctfKernelTrace = (LttngKernelTrace) trace;
+                ITmfStateSystem ssq = ctfKernelTrace.getStateSystems().get(LttngKernelTrace.STATE_ID);
+                if (time >= ssq.getStartTime() && time <= ssq.getCurrentEndTime()) {
+                    List<Integer> currentThreadQuarks = ssq.getQuarks(Attributes.CPUS, "*", Attributes.CURRENT_THREAD); //$NON-NLS-1$
+                    for (int currentThreadQuark : currentThreadQuarks) {
+                        try {
+                            ITmfStateInterval currentThreadInterval = ssq.querySingleState(time, currentThreadQuark);
+                            int currentThread = currentThreadInterval.getStateValue().unboxInt();
+                            if (currentThread > 0) {
+                                int statusQuark = ssq.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThread), Attributes.STATUS);
+                                ITmfStateInterval statusInterval = ssq.querySingleState(time, statusQuark);
+                                if (statusInterval.getStartTime() == time) {
+                                    thread = currentThread;
+                                    break;
+                                }
+                            }
+                        } catch (AttributeNotFoundException e) {
+                            e.printStackTrace();
+                        } catch (TimeRangeException e) {
+                            e.printStackTrace();
+                        } catch (StateValueTypeException e) {
+                            e.printStackTrace();
+                        } catch (StateSystemDisposedException e) {
+                            /* Ignored */
+                        }
+                    }
+                }
+            }
+        }
+        return thread;
+    }
+
+    @Override
+    protected void synchingToTime(long time) {
+        int selected = getSelectionValue(time);
+        if (selected > 0) {
+            for (Object element : getTimeGraphViewer().getExpandedElements()) {
+                if (element instanceof ControlFlowEntry) {
+                    ControlFlowEntry entry = (ControlFlowEntry) element;
+                    if (entry.getThreadId() == selected) {
+                        getTimeGraphCombo().setSelection(entry);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    protected List<ILinkEvent> getLinkList(long startTime, long endTime, long resolution, IProgressMonitor monitor) {
+        List<ILinkEvent> list = new ArrayList<ILinkEvent>();
+        ITmfTrace[] traces = TmfTraceManager.getTraceSet(getTrace());
+        List<TimeGraphEntry> entryList = getEntryListMap().get(getTrace());
+        if (traces == null || entryList == null) {
+            return list;
+        }
+        for (ITmfTrace trace : traces) {
+            if (trace instanceof LttngKernelTrace) {
+                ITmfStateSystem ssq = trace.getStateSystems().get(LttngKernelTrace.STATE_ID);
+                try {
+                    long start = Math.max(startTime, ssq.getStartTime());
+                    long end = Math.min(endTime, ssq.getCurrentEndTime());
+                    if (end < start) {
+                        continue;
+                    }
+                    List<Integer> currentThreadQuarks = ssq.getQuarks(Attributes.CPUS, "*", Attributes.CURRENT_THREAD); //$NON-NLS-1$
+                    for (int currentThreadQuark : currentThreadQuarks) {
+                        List<ITmfStateInterval> currentThreadIntervals = ssq.queryHistoryRange(currentThreadQuark, start, end, resolution, monitor);
+                        int prevThread = 0;
+                        long prevEnd = 0;
+                        for (ITmfStateInterval currentThreadInterval : currentThreadIntervals) {
+                            if (monitor.isCanceled()) {
+                                return null;
+                            }
+                            long time = currentThreadInterval.getStartTime();
+                            int thread = currentThreadInterval.getStateValue().unboxInt();
+                            if (thread > 0 && prevThread > 0 && thread != prevThread && time == prevEnd) {
+                                ITimeGraphEntry prevEntry = findEntry(entryList, trace, prevThread);
+                                ITimeGraphEntry nextEntry = findEntry(entryList, trace, thread);
+                                list.add(new TimeLinkEvent(prevEntry, nextEntry, time, 0, 0));
+                            }
+                            prevThread = thread;
+                            prevEnd = currentThreadInterval.getEndTime() + 1;
+                        }
+                    }
+                } catch (TimeRangeException e) {
+                    e.printStackTrace();
+                } catch (AttributeNotFoundException e) {
+                    e.printStackTrace();
+                } catch (StateValueTypeException e) {
+                    e.printStackTrace();
+                } catch (StateSystemDisposedException e) {
+                    /* Ignored */
+                }
+            }
+        }
+        return list;
+    }
+
+    private ControlFlowEntry findEntry(List<TimeGraphEntry> entryList, ITmfTrace trace, int threadId) {
+        for (TimeGraphEntry entry : entryList) {
+            if (entry instanceof ControlFlowEntry) {
+                ControlFlowEntry controlFlowEntry = (ControlFlowEntry) entry;
+                if (controlFlowEntry.getThreadId() == threadId && controlFlowEntry.getTrace() == trace) {
+                    return controlFlowEntry;
+                } else if (entry.hasChildren()) {
+                    controlFlowEntry = findEntry(entry.getChildren(), trace, threadId);
+                    if (controlFlowEntry != null) {
+                        return controlFlowEntry;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+}
This page took 0.038919 seconds and 5 git commands to generate.