lttng: Fix most compiler warnings as per the new settings
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng2.kernel.ui / src / org / eclipse / linuxtools / internal / lttng2 / kernel / ui / views / controlflow / ControlFlowView.java
index b759a9692155e8412f83255fa21d766efdf036cb..03d2c4f94dfd5f9ac7b8c7f1dbcb542e5fc2cc05 100644 (file)
@@ -1,11 +1,11 @@
 /*******************************************************************************\r
  * Copyright (c) 2012 Ericsson\r
- * \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
+ *\r
  * Contributors:\r
  *   Patrick Tasse - Initial API and implementation\r
  *******************************************************************************/\r
@@ -14,25 +14,37 @@ package org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.controlflow;
 \r
 import java.util.ArrayList;\r
 import java.util.Arrays;\r
-import java.util.HashMap;\r
+import java.util.Collections;\r
+import java.util.Comparator;\r
 import java.util.List;\r
-import java.util.Map;\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.Attributes;\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
@@ -40,18 +52,26 @@ import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphRangeListener;
 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.TimeGraphProvider;\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
@@ -63,26 +83,30 @@ public class ControlFlowView extends TmfView {
      */\r
     public static final String ID = "org.eclipse.linuxtools.lttng2.kernel.ui.views.controlflow"; //$NON-NLS-1$\r
 \r
-    private final String PROCESS_COLUMN    = Messages.ControlFlowView_processColumn;\r
-    private final String TID_COLUMN        = Messages.ControlFlowView_tidColumn;\r
-    private final String TGID_COLUMN       = Messages.ControlFlowView_tgidColumn;\r
-    private final String PPID_COLUMN       = Messages.ControlFlowView_ppidColumn;\r
-    private final String CPU_COLUMN        = Messages.ControlFlowView_cpuColumn;\r
-    private final String BIRTH_SEC_COLUMN  = Messages.ControlFlowView_birthSecColumn;\r
-    private final String BIRTH_NSEC_COLUMN = Messages.ControlFlowView_birthNsecColumn;\r
-    private final String TRACE_COLUMN      = Messages.ControlFlowView_traceColumn;\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
-            TGID_COLUMN,\r
-            PPID_COLUMN,\r
-            CPU_COLUMN,\r
-            BIRTH_SEC_COLUMN,\r
-            BIRTH_NSEC_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
@@ -94,7 +118,10 @@ public class ControlFlowView extends TmfView {
     private TmfExperiment<ITmfEvent> fSelectedExperiment;\r
 \r
     // The timegraph entry list\r
-    private ArrayList<ITimeGraphEntry> fEntryList;\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
@@ -102,6 +129,27 @@ public class ControlFlowView extends TmfView {
     // 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
@@ -138,7 +186,7 @@ public class ControlFlowView extends TmfView {
             ITimeGraphEntry entry = (ITimeGraphEntry) element;\r
             return entry.hasChildren();\r
         }\r
-        \r
+\r
     }\r
 \r
     private class TreeLabelProvider implements ITableLabelProvider {\r
@@ -172,22 +220,111 @@ public class ControlFlowView extends TmfView {
                 return entry.getName();\r
             } else if (columnIndex == 1) {\r
                 return Integer.toString(entry.getThreadId());\r
-            } else if (columnIndex == 3) {\r
-                if (entry.getPPID() != -1) {\r
-                    return Integer.toString(entry.getPPID());\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
+\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
@@ -205,41 +342,22 @@ public class ControlFlowView extends TmfView {
 \r
         fTimeGraphCombo.setTreeLabelProvider(new TreeLabelProvider());\r
 \r
-        fTimeGraphCombo.setTimeGraphProvider(new TimeGraphProvider() {\r
-            @Override\r
-            public String getTraceClassName(ITimeGraphEntry trace) {\r
-                return "trace class"; //$NON-NLS-1$\r
-            }\r
-            \r
-            @Override\r
-            public String getStateName(StateColor color) {\r
-                return "state name"; //$NON-NLS-1$\r
-            }\r
-            \r
-            @Override\r
-            public String getEventName(ITimeEvent event, boolean upper, boolean extInfo) {\r
-                return "event name"; //$NON-NLS-1$\r
-            }\r
-            \r
-            @Override\r
-            public Map<String, String> getEventHoverToolTipInfo(ITimeEvent event) {\r
-                return new HashMap<String, String>();\r
-            }\r
-            \r
-            @Override\r
-            public StateColor getEventColor(ITimeEvent event) {\r
-                return StateColor.BLACK;\r
-            }\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
-                long startTime = event.getStartTime();\r
-                long endTime = event.getEndTime();\r
-                System.out.println("timeRangeUpdated: startTime="+startTime+" endTime="+endTime);\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
@@ -247,19 +365,20 @@ public class ControlFlowView extends TmfView {
             @Override\r
             public void timeSelected(TimeGraphTimeEvent event) {\r
                 long time = event.getTime();\r
-                System.out.println("timeSelected: time="+time);\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
-                System.out.println("selectionChanged: source="+event.getSource()+" selection="+ (selection == null ? selection : selection.getName()));\r
+                //ITimeGraphEntry selection = event.getSelection();\r
             }\r
         });\r
 \r
-        final Thread thread = new Thread() {\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
@@ -268,6 +387,10 @@ public class ControlFlowView extends TmfView {
             }\r
         };\r
         thread.start();\r
+\r
+        // View Action Handling\r
+        makeActions();\r
+        contributeToActionBars();\r
     }\r
 \r
     /* (non-Javadoc)\r
@@ -282,34 +405,169 @@ public class ControlFlowView extends TmfView {
     // 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() {\r
+        final Thread thread = new Thread("ControlFlowView build") { //$NON-NLS-1$\r
             @Override\r
             public void run() {\r
                 selectExperiment(signal.getExperiment());\r
-            }};\r
-        thread.run();\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
-        HashMap<String, ITimeGraphEntry> traces = new HashMap<String, ITimeGraphEntry>();\r
-        fEntryList = new ArrayList<ITimeGraphEntry>();\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
-                ControlFlowEntry swapperEntry = null;\r
                 long start = ssq.getStartTime();\r
-                long end = ssq.getCurrentEndTime();\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
@@ -321,6 +579,9 @@ public class ControlFlowView extends TmfView {
                     } 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
@@ -329,29 +590,26 @@ public class ControlFlowView extends TmfView {
                             continue;\r
                         }\r
                         int ppidQuark = ssq.getQuarkRelative(threadQuark, Attributes.PPID);\r
-                        List<ITmfStateInterval> execNameIntervals = ssq.queryHistoryRange(execNameQuark, start, end);\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();\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;\r
-                                if (threadId == 0) {\r
-                                    if (swapperEntry == null) {\r
-                                        swapperEntry = new ControlFlowEntry(ctfKernelTrace, "swapper", threadId, ppid, startTime, endTime);\r
-                                        fEntryList.add(swapperEntry);\r
-                                    }\r
-                                    entry = swapperEntry;\r
-                                } else {\r
-                                    entry = new ControlFlowEntry(ctfKernelTrace, execName, threadId, ppid, startTime, endTime);\r
-                                    fEntryList.add(entry);\r
-                                }\r
-                                entry.addTraceEvent(new TimeEvent(entry, startTime, endTime - startTime));\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
@@ -362,25 +620,185 @@ public class ControlFlowView extends TmfView {
                         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();\r
+            refresh(INITIAL_WINDOW_OFFSET);\r
+        }\r
+        for (ControlFlowEntry entry : rootList) {\r
+            buildStatusEvents(entry);\r
         }\r
     }\r
 \r
-    private void refresh() {\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 = fEntryList.toArray(new ITimeGraphEntry[0]);\r
-                Arrays.sort(entries);\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
-                fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(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
This page took 0.033329 seconds and 5 git commands to generate.