The vertical blue line with T1 above it is the '''current selection indicator'''. When a time range is selected, the region between the begin and end time of the selection will be shaded and two lines with T1 and T2 above will be displayed. The time stamps corresponding to T1, T2 and their delta are shown in the status line when the mouse is hovering over the control flow.
-Arrows can be displayed that follow the execution of each CPU across processes. The arrows indicate when the scheduler switches from one process to another for a given CPU. The CPU being followed is indicated on the state tooltip. When the scheduler switches to or from the idle process, no arrow is displayed.
+Arrows can be displayed that follow the execution of each CPU across processes. The arrows indicate when the scheduler switches from one process to another for a given CPU. The CPU being followed is indicated on the state tooltip. When the scheduler switches to and from the idle process, the arrow skips to the next process which executes on the CPU after the idle process. Note that an appropriate zoom level is required for all arrows to be displayed.
-The display of arrows is optional and can be toggled using the '''Hide Arrows''' toolbar button. It is also possible to follow a CPU's execution across state changes and scheduler switching using the '''Follow Arrow Forward/Backward''' toolbar buttons.
+The display of arrows is optional and can be toggled using the '''Hide Arrows''' toolbar button. It is also possible to follow a CPU's execution across state changes and the scheduler's process switching using the '''Follow CPU Forward/Backward''' toolbar buttons.
==== Using the mouse ====
| Toggles the display of arrows on or off
|-
| [[Image:images/follow_arrow_bwd.gif]]
-| Follow Arrow Backward
+| Follow CPU Backward
| Selects the previous state following CPU execution across processes
|-
| [[Image:images/follow_arrow_fwd.gif]]
-| Follow Arrow Forward
+| Follow CPU Forward
| Selects the next state following CPU execution across processes
|}
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.linuxtools.internal.lttng2.kernel.core.Attributes;
if (section == null) {
section = settings.addNewSection(getClass().getName());
}
- manager.add(getTimeGraphCombo().getTimeGraphViewer().getHideArrowsAction(section));
- manager.add(getTimeGraphCombo().getTimeGraphViewer().getFollowArrowBwdAction());
- manager.add(getTimeGraphCombo().getTimeGraphViewer().getFollowArrowFwdAction());
+
+ IAction hideArrowsAction = getTimeGraphCombo().getTimeGraphViewer().getHideArrowsAction(section);
+ manager.add(hideArrowsAction);
+
+ IAction followArrowBwdAction = getTimeGraphCombo().getTimeGraphViewer().getFollowArrowBwdAction();
+ followArrowBwdAction.setText(Messages.ControlFlowView_followCPUBwdText);
+ followArrowBwdAction.setToolTipText(Messages.ControlFlowView_followCPUBwdText);
+ manager.add(followArrowBwdAction);
+
+ IAction followArrowFwdAction = getTimeGraphCombo().getTimeGraphViewer().getFollowArrowFwdAction();
+ followArrowFwdAction.setText(Messages.ControlFlowView_followCPUFwdText);
+ followArrowFwdAction.setToolTipText(Messages.ControlFlowView_followCPUFwdText);
+ manager.add(followArrowFwdAction);
}
@Override
}
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);
+ // adjust the query range to include the previous and following intervals
+ long qstart = Math.max(ssq.querySingleState(start, currentThreadQuark).getStartTime() - 1, ssq.getStartTime());
+ long qend = Math.min(ssq.querySingleState(end, currentThreadQuark).getEndTime() + 1, ssq.getCurrentEndTime());
+ List<ITmfStateInterval> currentThreadIntervals = ssq.queryHistoryRange(currentThreadQuark, qstart, qend, resolution, monitor);
int prevThread = 0;
long prevEnd = 0;
+ long lastEnd = 0;
for (ITmfStateInterval currentThreadInterval : currentThreadIntervals) {
if (monitor.isCanceled()) {
return null;
}
long time = currentThreadInterval.getStartTime();
+ if (time != lastEnd) {
+ // don't create links where there are gaps in intervals due to the resolution
+ prevThread = 0;
+ prevEnd = 0;
+ }
int thread = currentThreadInterval.getStateValue().unboxInt();
- if (thread > 0 && prevThread > 0 && thread != prevThread && time == prevEnd) {
+ if (thread > 0 && prevThread > 0) {
ITimeGraphEntry prevEntry = findEntry(entryList, trace, prevThread);
ITimeGraphEntry nextEntry = findEntry(entryList, trace, thread);
- list.add(new TimeLinkEvent(prevEntry, nextEntry, time, 0, 0));
+ list.add(new TimeLinkEvent(prevEntry, nextEntry, prevEnd, time - prevEnd, 0));
+ }
+ lastEnd = currentThreadInterval.getEndTime() + 1;
+ if (thread != 0) {
+ prevThread = thread;
+ prevEnd = lastEnd;
}
- prevThread = thread;
- prevEnd = currentThreadInterval.getEndTime() + 1;
}
}
} catch (TimeRangeException e) {
int x0 = getXForTime(event.getTime());
int x1 = getXForTime(event.getTime() + event.getDuration());
+
+ // limit the x-coordinates to prevent integer overflow in calculations
+ // and also GC.drawLine doesn't draw properly with large coordinates
+ final int limit = Integer.MAX_VALUE / 1024;
+ x0 = Math.max(-limit, Math.min(x0, limit));
+ x1 = Math.max(-limit, Math.min(x1, limit));
+
int y0 = src.y + src.height / 2;
int y1 = dst.y + dst.height / 2;
drawArrow(getColorScheme(), event, new Rectangle(x0, y0, x1 - x0, y1 - y0), gc);
int factor = 10;
double cos = 0.9510;
double sin = 0.3090;
- int lenx = x1 - x0;
- int leny = y1 - y0;
+ long lenx = x1 - x0;
+ long leny = y1 - y0;
double len = Math.sqrt(lenx * lenx + leny * leny);
double dx = factor * lenx / len;