lttng: Add Next/Previous TID event action in CFV next-previous-event
authorAlexandre Montplaisir <alexmonthy@efficios.com>
Wed, 15 Jun 2016 19:41:45 +0000 (15:41 -0400)
committerAlexandre Montplaisir <alexmonthy@efficios.com>
Wed, 15 Jun 2016 22:27:48 +0000 (18:27 -0400)
Expose actions in the Control Flow View to navigate to the
previous or next trace event for a given row/thread.

Unlike the "Go to state change" action, this action will stop
on all trace events related to that thread. To do so, we need
to stop on every trace event to test if they match. Since this
operation is unbounded in terms of number of events to read,
it is deferred to a separate Job.

Change-Id: Ie0f4f7dc3f2d0c6e3f2d0111fa95f265dfcdf75f
Signed-off-by: Alexandre Montplaisir <alexmonthy@efficios.com>
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/icons/obj16/shift_l_edit.gif [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/icons/obj16/shift_r_edit.gif [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowView.java
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/PackageMessages.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/messages.properties [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java

diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/icons/obj16/shift_l_edit.gif b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/icons/obj16/shift_l_edit.gif
new file mode 100644 (file)
index 0000000..328e97e
Binary files /dev/null and b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/icons/obj16/shift_l_edit.gif differ
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/icons/obj16/shift_r_edit.gif b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/icons/obj16/shift_r_edit.gif
new file mode 100644 (file)
index 0000000..c39cf62
Binary files /dev/null and b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/icons/obj16/shift_r_edit.gif differ
index 0f96a61fe835326153506dc548644a108c19b32d..adb293bfc8d4270640004772965d291c89261a3b 100644 (file)
@@ -23,10 +23,14 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.jface.action.Action;
@@ -39,6 +43,7 @@ import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
+import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelTidAspect;
 import org.eclipse.tracecompass.common.core.StreamUtils.StreamFlattener;
 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.Attributes;
 import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Activator;
@@ -51,11 +56,17 @@ import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeExcept
 import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
 import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
 import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
 import org.eclipse.tracecompass.tmf.core.util.Pair;
 import org.eclipse.tracecompass.tmf.ui.views.timegraph.AbstractStateSystemTimeGraphView;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent;
@@ -65,6 +76,7 @@ import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.NullTimeEvent;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeLinkEvent;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.Resolution;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
@@ -90,6 +102,9 @@ public class ControlFlowView extends AbstractStateSystemTimeGraphView {
     private static final String PTID_COLUMN = Messages.ControlFlowView_ptidColumn;
     private static final String BIRTH_TIME_COLUMN = Messages.ControlFlowView_birthTimeColumn;
 
+    private static final String NEXT_EVENT_ICON_PATH = "icons/obj16/shift_r_edit.gif"; //$NON-NLS-1$
+    private static final String PREV_EVENT_ICON_PATH = "icons/obj16/shift_l_edit.gif"; //$NON-NLS-1$
+
     private static final String[] COLUMN_NAMES = new String[] {
             PROCESS_COLUMN,
             TID_COLUMN,
@@ -188,6 +203,18 @@ public class ControlFlowView extends AbstractStateSystemTimeGraphView {
         followArrowFwdAction.setText(Messages.ControlFlowView_followCPUFwdText);
         followArrowFwdAction.setToolTipText(Messages.ControlFlowView_followCPUFwdText);
         manager.add(followArrowFwdAction);
+
+        IAction previousEventAction = new SearchEventAction(false, PackageMessages.ControlFlowView_PreviousEventJobName);
+        previousEventAction.setText(PackageMessages.ControlFlowView_PreviousEventActionName);
+        previousEventAction.setToolTipText(PackageMessages.ControlFlowView_PreviousEventActionTooltip);
+        previousEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(PREV_EVENT_ICON_PATH));
+        manager.add(previousEventAction);
+
+        IAction nextEventAction = new SearchEventAction(true, PackageMessages.ControlFlowView_NextEventJobName);
+        nextEventAction.setText(PackageMessages.ControlFlowView_NextEventActionName);
+        nextEventAction.setToolTipText(PackageMessages.ControlFlowView_NextEventActionTooltip);
+        nextEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(NEXT_EVENT_ICON_PATH));
+        manager.add(nextEventAction);
     }
 
     @Override
@@ -203,6 +230,72 @@ public class ControlFlowView extends AbstractStateSystemTimeGraphView {
 
     }
 
+    /**
+     * Base Action for the "Go to Next/Previous Event for thread" actions
+     */
+    private class SearchEventAction extends Action {
+
+        private final boolean ifDirection;
+        private final String ifJobName;
+
+        /**
+         * Constructor
+         *
+         * @param direction
+         *            The direction of the search, "true" for forwards and
+         *            "false" for backwards.
+         * @param jobName
+         *            The name of the job that will be spawned
+         */
+        public SearchEventAction(boolean direction, String jobName) {
+            ifDirection = direction;
+            ifJobName = jobName;
+        }
+
+        @Override
+        public void run() {
+            TimeGraphControl ctrl = getTimeGraphViewer().getTimeGraphControl();
+
+            ITimeGraphEntry traceEntry = ctrl.getSelectedTrace();
+            long ts = ctrl.getTimeDataProvider().getSelectionBegin();
+            ITmfTimestamp ts2 = TmfTraceManager.getInstance().getCurrentTraceContext().getSelectionRange().getStartTime();
+            ITimeEvent selectedState = Utils.findEvent(traceEntry, ts, 0);
+
+            if (selectedState == null) {
+                return;
+            }
+            ITimeGraphEntry entry = selectedState.getEntry();
+            if (!(entry instanceof ControlFlowEntry)) {
+                return;
+            }
+            ControlFlowEntry cfEntry = (ControlFlowEntry) entry;
+            int tid = cfEntry.getThreadId();
+
+            Job job = new Job(ifJobName) {
+                @Override
+                protected IStatus run(IProgressMonitor monitor) {
+                    ITmfTrace trace = cfEntry.getTrace();
+                    ITmfContext ctx = trace.seekEvent(ts2);
+                    long rank = ctx.getRank();
+
+                    Predicate<@NonNull ITmfEvent> predicate = event -> {
+                        Integer eventTid = KernelTidAspect.INSTANCE.resolve(event);
+                        return (eventTid != null && eventTid.intValue() == tid);
+                    };
+
+                    ITmfEvent event = (ifDirection ?
+                            TmfTraceUtils.getNextEventMatching(cfEntry.getTrace(), rank, predicate) :
+                            TmfTraceUtils.getPreviousEventMatching(cfEntry.getTrace(), rank, predicate));
+                    if (event != null) {
+                        TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(this, event.getTimestamp()));
+                    }
+                    return Status.OK_STATUS;
+                }
+            };
+            job.schedule();
+        }
+    }
+
     private IAction createHierarchicalAction() {
         IAction action = new Action(Messages.ControlFlowView_hierarchicalViewLabel, IAction.AS_RADIO_BUTTON) {
             @Override
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/PackageMessages.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/PackageMessages.java
new file mode 100644 (file)
index 0000000..42b2b4e
--- /dev/null
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EfficiOS Inc. and others
+ *
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.controlflow;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Message bundle for the package
+ *
+ * @noreference Messages class
+ */
+@SuppressWarnings("javadoc")
+public class PackageMessages extends NLS {
+
+    private static final String BUNDLE_NAME = PackageMessages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$
+
+    public static String ControlFlowView_NextEventActionName;
+    public static String ControlFlowView_NextEventActionTooltip;
+    public static String ControlFlowView_NextEventJobName;
+
+    public static String ControlFlowView_PreviousEventActionName;
+    public static String ControlFlowView_PreviousEventActionTooltip;
+    public static String ControlFlowView_PreviousEventJobName;
+
+
+    static {
+        NLS.initializeMessages(BUNDLE_NAME, PackageMessages.class);
+    }
+
+    private PackageMessages() {
+    }
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/messages.properties b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/messages.properties
new file mode 100644 (file)
index 0000000..9b6cddb
--- /dev/null
@@ -0,0 +1,16 @@
+###############################################################################
+# Copyright (c) 2016 EfficiOS Inc. and others
+#
+# 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
+###############################################################################
+
+ControlFlowView_NextEventActionName = Go to next event
+ControlFlowView_NextEventActionTooltip = Go to next event of the selected thread
+ControlFlowView_NextEventJobName = Searching for next matching event
+
+ControlFlowView_PreviousEventActionName = Go to previous event
+ControlFlowView_PreviousEventActionTooltip = Go to previous event of the selected thread
+ControlFlowView_PreviousEventJobName = Searching for previous matching event
index 3727a46ad3a03d339338dca3f8a34af1053ad320..2f5c35895a97bfd14661edb75131ff0076479f36 100644 (file)
@@ -244,6 +244,15 @@ public class TimeGraphControl extends TimeGraphBaseControl
         return fTimeGraphProvider;
     }
 
+    /**
+     * Gets the time data provider used by this viewer.
+     *
+     * @return The time data provider, or <code>null</code> if not set
+     */
+    public ITimeDataProvider getTimeDataProvider() {
+        return fTimeProvider;
+    }
+
     /**
      * Gets the color map used by this timegraph viewer.
      *
This page took 0.029297 seconds and 5 git commands to generate.