From e50f28e65161fed6d0a895cbafaca5ed7aa73aa0 Mon Sep 17 00:00:00 2001 From: Alexandre Montplaisir Date: Wed, 15 Jun 2016 15:41:45 -0400 Subject: [PATCH] lttng: Add Next/Previous TID event action in CFV 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 --- .../icons/obj16/shift_l_edit.gif | Bin 0 -> 323 bytes .../icons/obj16/shift_r_edit.gif | Bin 0 -> 328 bytes .../ui/views/controlflow/ControlFlowView.java | 93 ++++++++++++++++++ .../ui/views/controlflow/PackageMessages.java | 39 ++++++++ .../ui/views/controlflow/messages.properties | 16 +++ .../timegraph/widgets/TimeGraphControl.java | 9 ++ 6 files changed, 157 insertions(+) create mode 100644 analysis/org.eclipse.tracecompass.analysis.os.linux.ui/icons/obj16/shift_l_edit.gif create mode 100644 analysis/org.eclipse.tracecompass.analysis.os.linux.ui/icons/obj16/shift_r_edit.gif create mode 100644 analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/PackageMessages.java create mode 100644 analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/messages.properties 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 index 0000000000000000000000000000000000000000..328e97ee6f1cedd14d01aa172345a2d5511d6f7c GIT binary patch literal 323 zcmZ?wbhEHb6krfwxXQqg+r2ZUX63)X@BjX|_4oU&-!B*Z`LO5DhrPcaPx$?0!tciu ze?OV{=f#3QK=Bs~f4^Ap`^CaP@Av$^*ZTW@+wTXRzaMt~zT3RFMQme*@UBMDZ8f6X zYDIT7iml8OSOG$UYm0<7l?yM+7Wn`FKLZVb;!hSv1_osY9gx`|KQXW+9GF<(p(E9Q zlz|~LL`;AB;^GQHm)YJATMZhj)(7_`=5)xMm^m@{bAp9bt2?vP{T0&{S(!FQsQjyz tD0fm25p8d46IEz-k`)q`my?yB>J;pxB&HM;>8vy-!e{Z4rOu8F)&O(kaa;fZ literal 0 HcmV?d00001 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 index 0000000000000000000000000000000000000000..c39cf62bbca0ba8464a3fc81aaf7602dab464694 GIT binary patch literal 328 zcmZ?wbhEHb6krfwxXQqg+r2ZUX63)X@BjX|_4oU&-!B*Z`LO5DhrPcaPx$?0!tciu ze?OV{=f#3QK=Bs~f4^Ap`^CaP@Av$^*ZTW@+wTXRzaMt~zT3RJNpx?E*v@*9t<@rX znt%+^-A!UEas^fw2(B&^TvZ^rB2RE#vCz5_q16RKo63ckWefcO|DS;xK=CIFBLjm5 zgAT|rke?XXQXQrgc<4y=pHSfvut+j+T^7tB>lHZL`}rbS0ljN##~tikPCV%eSk<^g zy5H&W!HSG&zQRfe{dL4RIJnd*G*m=IL^?!!M3l3AH53(873JlHh2#_6mBi#+!d=zX P11EY-Sh32}k--`OoA`AT literal 0 HcmV?d00001 diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowView.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowView.java index 0f96a61fe8..adb293bfc8 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowView.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowView.java @@ -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 index 0000000000..42b2b4ec26 --- /dev/null +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/PackageMessages.java @@ -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 index 0000000000..9b6cddbf7c --- /dev/null +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/messages.properties @@ -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 diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java index 3727a46ad3..2f5c35895a 100644 --- a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java +++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java @@ -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 null if not set + */ + public ITimeDataProvider getTimeDataProvider() { + return fTimeProvider; + } + /** * Gets the color map used by this timegraph viewer. * -- 2.34.1