From 1d46dc38f8ffd79b753e74de057a59525662c589 Mon Sep 17 00:00:00 2001 From: Patrick Tasse Date: Fri, 5 Jul 2013 13:39:21 -0400 Subject: [PATCH] lttng: Fix Resources view event list With the fix to the event iterator (42acdc2), it is no longer required to add 'null' events in the zoomed event list for all empty ranges to hide underlying events in the full range event list. This simplifies the building of event list in the Resources view. If required, 'null' events are added at the start or end of the list to properly identify the time range that the list represents. Adds an interface to TimeEvent to split an event while keeping it's class type and value. Some trace specific fields are moved out of the generic TimeGraphEntry. Change-Id: I6b3058227e64e456601b40fa2ea6c0afe3886f14 Signed-off-by: Patrick Tasse Reviewed-on: https://git.eclipse.org/r/14326 Tested-by: Hudson CI Reviewed-by: Bernd Hufmann Reviewed-by: Matthew Khouzam --- .../views/controlflow/ControlFlowEntry.java | 12 ++- .../ControlFlowPresentationProvider.java | 95 +++++++++---------- .../ui/views/controlflow/ControlFlowView.java | 26 +++-- .../ui/views/resources/ResourcesEntry.java | 12 ++- .../ResourcesPresentationProvider.java | 37 +++----- .../ui/views/resources/ResourcesView.java | 57 ++++++----- .../timegraph/model/EventIterator.java | 12 ++- .../widgets/timegraph/model/ITimeEvent2.java | 35 +++++++ .../ui/widgets/timegraph/model/TimeEvent.java | 25 ++++- .../timegraph/model/TimeGraphEntry.java | 55 ++--------- 10 files changed, 200 insertions(+), 166 deletions(-) create mode 100644 org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ITimeEvent2.java diff --git a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowEntry.java b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowEntry.java index 60a752243e..cd591ce5a0 100644 --- a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowEntry.java +++ b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowEntry.java @@ -21,6 +21,7 @@ import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry; */ public class ControlFlowEntry extends TimeGraphEntry { + private final LttngKernelTrace fTrace; private final int fThreadId; private final int fParentThreadId; private final int fThreadQuark; @@ -44,7 +45,8 @@ public class ControlFlowEntry extends TimeGraphEntry { * The end time of this process */ public ControlFlowEntry(int quark, LttngKernelTrace trace, String execName, int threadId, int parentThreadId, long startTime, long endTime) { - super(quark, trace, execName, startTime, endTime); + super(execName, startTime, endTime); + fTrace = trace; fThreadId = threadId; fParentThreadId = parentThreadId; fThreadQuark = quark; @@ -59,9 +61,13 @@ public class ControlFlowEntry extends TimeGraphEntry { return fThreadId; } - @Override + /** + * Get the entry's kernel trace + * + * @return the entry's kernel trace + */ public LttngKernelTrace getTrace() { - return (LttngKernelTrace) super.getTrace(); + return fTrace; } /** diff --git a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowPresentationProvider.java b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowPresentationProvider.java index cb148e03d1..bbfd7a5d11 100644 --- a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowPresentationProvider.java +++ b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowPresentationProvider.java @@ -32,7 +32,6 @@ import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.StateItem; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; 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.widgets.Utils; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.GC; @@ -122,58 +121,56 @@ public class ControlFlowPresentationProvider extends TimeGraphPresentationProvid @Override public Map getEventHoverToolTipInfo(ITimeEvent event) { Map retMap = new LinkedHashMap(); + if (!(event instanceof TimeEvent) || !((TimeEvent) event).hasValue() || + !(event.getEntry() instanceof ControlFlowEntry)) { + return retMap; + } + ControlFlowEntry entry = (ControlFlowEntry) event.getEntry(); + ITmfStateSystem ssq = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID); + int tid = entry.getThreadId(); - if (event instanceof TimeEvent && ((TimeEvent) event).hasValue()) { - TimeGraphEntry entry = (TimeGraphEntry) event.getEntry(); - ITmfStateSystem ssq = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID); - if (entry instanceof ControlFlowEntry) { - ControlFlowEntry entry2 = (ControlFlowEntry) entry; - int tid = entry2.getThreadId(); - - try { - // Find every CPU first, then get the current thread - int cpusQuark = ssq.getQuarkAbsolute(Attributes.CPUS); - List cpuQuarks = ssq.getSubAttributes(cpusQuark, false); - for (Integer cpuQuark : cpuQuarks) { - int currentThreadQuark = ssq.getQuarkRelative(cpuQuark, Attributes.CURRENT_THREAD); - ITmfStateInterval interval = ssq.querySingleState(event.getTime(), currentThreadQuark); - if (!interval.getStateValue().isNull()) { - ITmfStateValue state = interval.getStateValue(); - int currentThreadId = state.unboxInt(); - if (tid == currentThreadId) { - retMap.put(Messages.ControlFlowView_attributeCpuName, ssq.getAttributeName(cpuQuark)); - break; - } - } + try { + // Find every CPU first, then get the current thread + int cpusQuark = ssq.getQuarkAbsolute(Attributes.CPUS); + List cpuQuarks = ssq.getSubAttributes(cpusQuark, false); + for (Integer cpuQuark : cpuQuarks) { + int currentThreadQuark = ssq.getQuarkRelative(cpuQuark, Attributes.CURRENT_THREAD); + ITmfStateInterval interval = ssq.querySingleState(event.getTime(), currentThreadQuark); + if (!interval.getStateValue().isNull()) { + ITmfStateValue state = interval.getStateValue(); + int currentThreadId = state.unboxInt(); + if (tid == currentThreadId) { + retMap.put(Messages.ControlFlowView_attributeCpuName, ssq.getAttributeName(cpuQuark)); + break; } - - } catch (AttributeNotFoundException e) { - e.printStackTrace(); - } catch (TimeRangeException e) { - e.printStackTrace(); - } catch (StateValueTypeException e) { - e.printStackTrace(); - } catch (StateSystemDisposedException e) { - /* Ignored */ } - int status = ((TimeEvent) event).getValue(); - if (status == StateValues.PROCESS_STATUS_RUN_SYSCALL) { - try { - int syscallQuark = ssq.getQuarkRelative(entry2.getThreadQuark(), Attributes.SYSTEM_CALL); - ITmfStateInterval value = ssq.querySingleState(event.getTime(), syscallQuark); - if (!value.getStateValue().isNull()) { - ITmfStateValue state = value.getStateValue(); - retMap.put(Messages.ControlFlowView_attributeSyscallName, state.toString()); - } - - } catch (AttributeNotFoundException e) { - e.printStackTrace(); - } catch (TimeRangeException e) { - e.printStackTrace(); - } catch (StateSystemDisposedException e) { - /* Ignored */ - } + } + + } catch (AttributeNotFoundException e) { + e.printStackTrace(); + } catch (TimeRangeException e) { + e.printStackTrace(); + } catch (StateValueTypeException e) { + e.printStackTrace(); + } catch (StateSystemDisposedException e) { + /* Ignored */ + } + int status = ((TimeEvent) event).getValue(); + if (status == StateValues.PROCESS_STATUS_RUN_SYSCALL) { + try { + int syscallQuark = ssq.getQuarkRelative(entry.getThreadQuark(), Attributes.SYSTEM_CALL); + ITmfStateInterval value = ssq.querySingleState(event.getTime(), syscallQuark); + if (!value.getStateValue().isNull()) { + ITmfStateValue state = value.getStateValue(); + retMap.put(Messages.ControlFlowView_attributeSyscallName, state.toString()); } + + } catch (AttributeNotFoundException e) { + e.printStackTrace(); + } catch (TimeRangeException e) { + e.printStackTrace(); + } catch (StateSystemDisposedException e) { + /* Ignored */ } } diff --git a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java index 79fe9203e1..b6ed8dc3cd 100644 --- a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java +++ b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java @@ -191,13 +191,13 @@ public class ControlFlowView extends AbstractTimeGraphView { setStartTime(Long.MAX_VALUE); setEndTime(Long.MIN_VALUE); - ArrayList rootList = new ArrayList(); - for (ITmfTrace aTrace : fTraceManager.getActiveTraceSet()) { + ArrayList rootList = new ArrayList(); + for (ITmfTrace aTrace : TmfTraceManager.getTraceSet(trace)) { if (monitor.isCanceled()) { return; } if (aTrace instanceof LttngKernelTrace) { - ArrayList entryList = new ArrayList(); + ArrayList entryList = new ArrayList(); LttngKernelTrace ctfKernelTrace = (LttngKernelTrace) aTrace; ITmfStateSystem ssq = ctfKernelTrace.getStateSystems().get(LttngKernelTrace.STATE_ID); if (!ssq.waitUntilBuilt()) { @@ -235,7 +235,7 @@ public class ControlFlowView extends AbstractTimeGraphView { if (monitor.isCanceled()) { return; } - TimeGraphEntry entry = null; + ControlFlowEntry entry = null; for (ITmfStateInterval execNameInterval : execNameIntervals) { if (monitor.isCanceled()) { return; @@ -282,22 +282,20 @@ public class ControlFlowView extends AbstractTimeGraphView { refresh(); } } - for (TimeGraphEntry entry : rootList) { + for (ControlFlowEntry entry : rootList) { if (monitor.isCanceled()) { return; } - buildStatusEvents(trace, entry, monitor); + buildStatusEvents(entry.getTrace(), entry, monitor); } } - private static void buildTree(ArrayList entryList, - ArrayList rootList) { - for (TimeGraphEntry listentry : entryList) { - ControlFlowEntry entry = (ControlFlowEntry) listentry; + private static void buildTree(ArrayList entryList, + ArrayList rootList) { + for (ControlFlowEntry entry : entryList) { boolean root = true; if (entry.getParentThreadId() > 0) { - for (TimeGraphEntry parententry : entryList) { - ControlFlowEntry parent = (ControlFlowEntry) parententry; + for (ControlFlowEntry parent : entryList) { if (parent.getThreadId() == entry.getParentThreadId() && entry.getStartTime() >= parent.getStartTime() && entry.getStartTime() <= parent.getEndTime()) { @@ -313,7 +311,7 @@ public class ControlFlowView extends AbstractTimeGraphView { } } - private void buildStatusEvents(ITmfTrace trace, TimeGraphEntry entry, IProgressMonitor monitor) { + private void buildStatusEvents(ITmfTrace trace, ControlFlowEntry entry, IProgressMonitor monitor) { ITmfStateSystem ssq = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID); long start = ssq.getStartTime(); @@ -331,7 +329,7 @@ public class ControlFlowView extends AbstractTimeGraphView { if (monitor.isCanceled()) { return; } - buildStatusEvents(trace, (TimeGraphEntry) child, monitor); + buildStatusEvents(trace, (ControlFlowEntry) child, monitor); } } diff --git a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesEntry.java b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesEntry.java index 34d43c4185..81da0d2bf7 100644 --- a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesEntry.java +++ b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesEntry.java @@ -36,6 +36,7 @@ public class ResourcesEntry extends TimeGraphEntry { } private final int fId; + private final LttngKernelTrace fTrace; private final Type fType; private final int fQuark; @@ -58,8 +59,9 @@ public class ResourcesEntry extends TimeGraphEntry { * The id of this entry */ public ResourcesEntry(int quark, LttngKernelTrace trace, String name, long startTime, long endTime, Type type, int id) { - super(quark, trace, name, startTime, endTime); + super(name, startTime, endTime); fId = id; + fTrace = trace; fType = type; fQuark = quark; } @@ -111,9 +113,13 @@ public class ResourcesEntry extends TimeGraphEntry { return fId; } - @Override + /** + * Get the entry's kernel trace + * + * @return the entry's kernel trace + */ public LttngKernelTrace getTrace() { - return (LttngKernelTrace) super.getTrace(); + return fTrace; } /** diff --git a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesPresentationProvider.java b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesPresentationProvider.java index 52ad1a023f..88043dd021 100644 --- a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesPresentationProvider.java +++ b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesPresentationProvider.java @@ -33,6 +33,7 @@ import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.StateItem; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider; 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.NullTimeEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.ITmfTimeGraphDrawingHelper; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils; @@ -55,12 +56,12 @@ public class ResourcesPresentationProvider extends TimeGraphPresentationProvider private enum State { IDLE (new RGB(200, 200, 200)), - USERMODE (new RGB(0, 200, 0)), - SYSCALL (new RGB(0, 0, 200)), + USERMODE (new RGB( 0, 200, 0)), + SYSCALL (new RGB( 0, 0, 200)), IRQ (new RGB(200, 0, 100)), SOFT_IRQ (new RGB(200, 150, 100)), IRQ_ACTIVE (new RGB(200, 0, 100)), - SOFT_IRQ_RAISED (new RGB(200, 200, 0)), + SOFT_IRQ_RAISED (new RGB(200, 200, 0)), SOFT_IRQ_ACTIVE (new RGB(200, 150, 100)); public final RGB rgb; @@ -81,12 +82,10 @@ public class ResourcesPresentationProvider extends TimeGraphPresentationProvider return State.values(); } - private static State getEventState(ITimeEvent event) { - if (event instanceof TimeEvent && ((TimeEvent) event).hasValue()) { - TimeEvent tcEvent = (TimeEvent) event; - + private static State getEventState(TimeEvent event) { + if (event.hasValue()) { ResourcesEntry entry = (ResourcesEntry) event.getEntry(); - int value = tcEvent.getValue(); + int value = event.getValue(); if (entry.getType() == Type.CPU) { if (value == StateValues.CPU_STATUS_IDLE) { @@ -100,9 +99,9 @@ public class ResourcesPresentationProvider extends TimeGraphPresentationProvider } else if (value == StateValues.CPU_STATUS_SOFTIRQ) { return State.SOFT_IRQ; } - } else if ((entry.getType() == Type.IRQ) && (tcEvent.hasValue()) && (value != ResourcesView.NO_VALUE_EVENT)) { + } else if (entry.getType() == Type.IRQ) { return State.IRQ_ACTIVE; - } else if ((entry.getType() == Type.SOFT_IRQ) && (tcEvent.hasValue()) && (value != ResourcesView.NO_VALUE_EVENT)) { + } else if (entry.getType() == Type.SOFT_IRQ) { if (value == StateValues.SOFT_IRQ_RAISED) { return State.SOFT_IRQ_RAISED; } @@ -114,15 +113,12 @@ public class ResourcesPresentationProvider extends TimeGraphPresentationProvider @Override public int getStateTableIndex(ITimeEvent event) { - State state = getEventState(event); + State state = getEventState((TimeEvent) event); if (state != null) { return state.ordinal(); } - if (event instanceof TimeEvent) { - TimeEvent tcEvent = (TimeEvent) event; - if (tcEvent.hasValue()) { - return INVISIBLE; - } + if (event instanceof NullTimeEvent) { + return INVISIBLE; } return TRANSPARENT; } @@ -140,15 +136,12 @@ public class ResourcesPresentationProvider extends TimeGraphPresentationProvider @Override public String getEventName(ITimeEvent event) { - State state = getEventState(event); + State state = getEventState((TimeEvent) event); if (state != null) { return state.toString(); } - if (event instanceof TimeEvent) { - TimeEvent tcEvent = (TimeEvent) event; - if (tcEvent.hasValue()) { - return null; - } + if (event instanceof NullTimeEvent) { + return null; } return Messages.ResourcesView_multipleStates; } diff --git a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesView.java b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesView.java index 135b452593..5bf034f62f 100644 --- a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesView.java +++ b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesView.java @@ -28,8 +28,10 @@ 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.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.ITimeEvent; +import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.NullTimeEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry; @@ -43,12 +45,6 @@ public class ResourcesView extends AbstractTimeGraphView { /** View ID. */ public static final String ID = "org.eclipse.linuxtools.lttng2.kernel.ui.views.resources"; //$NON-NLS-1$ - /** - * Default value for events with no other value. Since value in this case is - * often a CPU number, this constant should be <0 - */ - public static final int NO_VALUE_EVENT = -999; - private static final String[] FILTER_COLUMN_NAMES = new String[] { Messages.ResourcesView_stateTypeName }; @@ -95,7 +91,7 @@ public class ResourcesView extends AbstractTimeGraphView { setEndTime(Long.MIN_VALUE); ArrayList entryList = new ArrayList(); - for (ITmfTrace aTrace : fTraceManager.getActiveTraceSet()) { + for (ITmfTrace aTrace : TmfTraceManager.getTraceSet(trace)) { if (monitor.isCanceled()) { return; } @@ -166,18 +162,14 @@ public class ResourcesView extends AbstractTimeGraphView { protected List getEventList(TimeGraphEntry entry, long startTime, long endTime, long resolution, IProgressMonitor monitor) { - ITmfStateSystem ssq = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID); + ResourcesEntry resourcesEntry = (ResourcesEntry) entry; + ITmfStateSystem ssq = resourcesEntry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID); final long realStart = Math.max(startTime, ssq.getStartTime()); final long realEnd = Math.min(endTime, ssq.getCurrentEndTime() + 1); if (realEnd <= realStart) { return null; } List eventList = null; - - if (!(entry instanceof ResourcesEntry)) { - return eventList; - } - ResourcesEntry resourcesEntry = (ResourcesEntry) entry; int quark = resourcesEntry.getQuark(); try { @@ -198,12 +190,11 @@ public class ResourcesView extends AbstractTimeGraphView { eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime)); } eventList.add(new TimeEvent(entry, time, duration, status)); - lastEndTime = time + duration; - } else { - if (true) {// includeNull) { - eventList.add(new TimeEvent(entry, time, duration, NO_VALUE_EVENT)); - } + } else if (lastEndTime == -1 || time + duration >= endTime) { + // add null event if it intersects the start or end time + eventList.add(new NullTimeEvent(entry, time, duration)); } + lastEndTime = time + duration; } } else if (resourcesEntry.getType().equals(Type.IRQ)) { List irqIntervals = ssq.queryHistoryRange(quark, realStart, realEnd - 1, resolution, monitor); @@ -221,11 +212,18 @@ public class ResourcesView extends AbstractTimeGraphView { eventList.add(new TimeEvent(entry, time, duration, cpu)); lastIsNull = false; } else { - if (lastEndTime != time && lastEndTime != -1 && lastIsNull) { - /* This is a special case where we want to show IRQ_ACTIVE state but we don't know the CPU (it is between two null samples) */ - eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime, -1)); + if (lastEndTime == -1) { + // add null event if it intersects the start time + eventList.add(new NullTimeEvent(entry, time, duration)); } else { - eventList.add(new TimeEvent(entry, time, duration, NO_VALUE_EVENT)); + if (lastEndTime != time && lastIsNull) { + /* This is a special case where we want to show IRQ_ACTIVE state but we don't know the CPU (it is between two null samples) */ + eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime, -1)); + } + if (time + duration >= endTime) { + // add null event if it intersects the end time + eventList.add(new NullTimeEvent(entry, time, duration)); + } } lastIsNull = true; } @@ -246,11 +244,18 @@ public class ResourcesView extends AbstractTimeGraphView { int cpu = softIrqInterval.getStateValue().unboxInt(); eventList.add(new TimeEvent(entry, time, duration, cpu)); } else { - if (lastEndTime != time && lastEndTime != -1 && lastIsNull) { - /* This is a special case where we want to show IRQ_ACTIVE state but we don't know the CPU (it is between two null samples) */ - eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime, -1)); + if (lastEndTime == -1) { + // add null event if it intersects the start time + eventList.add(new NullTimeEvent(entry, time, duration)); } else { - eventList.add(new TimeEvent(entry, time, duration, NO_VALUE_EVENT)); + if (lastEndTime != time && lastIsNull) { + /* This is a special case where we want to show IRQ_ACTIVE state but we don't know the CPU (it is between two null samples) */ + eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime, -1)); + } + if (time + duration >= endTime) { + // add null event if it intersects the end time + eventList.add(new NullTimeEvent(entry, time, duration)); + } } lastIsNull = true; } diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/EventIterator.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/EventIterator.java index 7ab57c59e1..9b386f1176 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/EventIterator.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/EventIterator.java @@ -91,12 +91,20 @@ public class EventIterator implements Iterator { fNext = null; if (event.getTime() + event.getDuration() > fZoomedEndTime && fZoomedEndTime < fEndTime) { // the end of the event is partially hidden by the zoomed events and is visible - fNext = new TimeEvent(event.getEntry(), fZoomedEndTime, event.getTime() + event.getDuration() - fZoomedEndTime); + if (event instanceof ITimeEvent2) { + fNext = ((ITimeEvent2) event).split(fZoomedEndTime).getSecond(); + } else { + fNext = new TimeEvent(event.getEntry(), fZoomedEndTime, event.getTime() + event.getDuration() - fZoomedEndTime); + } } if (event.getTime() < fZoomedStartTime && fZoomedStartTime > fStartTime) { // the start of the event is partially hidden by the zoomed events and is visible fSplitNext = fNext; - fNext = new TimeEvent(event.getEntry(), event.getTime(), fZoomedStartTime - event.getTime()); + if (event instanceof ITimeEvent2) { + fNext = ((ITimeEvent2) event).split(fZoomedStartTime).getFirst(); + } else { + fNext = new TimeEvent(event.getEntry(), event.getTime(), fZoomedStartTime - event.getTime()); + } } } if (fNext != null) { diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ITimeEvent2.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ITimeEvent2.java new file mode 100644 index 0000000000..39b4aa3902 --- /dev/null +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ITimeEvent2.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * 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 + *******************************************************************************/ + +package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model; + +import org.eclipse.linuxtools.tmf.core.util.Pair; + +/** + * Extend ITimeEvent interface + * + * @author Patrick Tasse + * @since 2.1 + */ +public interface ITimeEvent2 extends ITimeEvent { + + /** + * Split an event in two at the specified time. If the time is smaller or + * equal to the event's start, the first split event is null. If the time is + * greater or equal to the event's end, the second split event is null. + * + * @param time + * the time at which the event is to be split + * @return a pair of time events + */ + Pair split(long time); +} diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeEvent.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeEvent.java index 8aeade9f37..cf47461162 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeEvent.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeEvent.java @@ -13,13 +13,15 @@ package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model; +import org.eclipse.linuxtools.tmf.core.util.Pair; + /** * Generic TimeEvent implementation * * @version 1.0 * @author Patrick Tasse */ -public class TimeEvent implements ITimeEvent { +public class TimeEvent implements ITimeEvent2 { /** TimeGraphEntry matching this time event */ protected ITimeGraphEntry fEntry; @@ -108,6 +110,27 @@ public class TimeEvent implements ITimeEvent { return fDuration; } + /** + * Split an event in two at the specified time. If the time is smaller or + * equal to the event's start, the first split event is null. If the time is + * greater or equal to the event's end, the second split event is null. + *

+ * Subclasses should re-implement this method + * + * @since 2.1 + */ + @Override + public Pair split(long time) { + Pair pair = new Pair(); + if (time > fTime) { + pair.setFirst(new TimeEvent(fEntry, fTime, Math.min(fDuration, time - fTime), fValue)); + } + if (time < fTime + fDuration) { + pair.setSecond(new TimeEvent(fEntry, Math.max(fTime, time), fDuration - Math.max(0, time - fTime), fValue)); + } + return pair; + } + @Override public String toString() { return getClass().getSimpleName() + " start=" + fTime + " end=" + (fTime + fDuration) + " duration=" + fDuration + (hasValue() ? (" value=" + fValue) : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java index dafb900f7a..cd4242bcf6 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java @@ -17,8 +17,6 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - /** * An entry for use in the time graph views * @@ -26,10 +24,6 @@ import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; */ public class TimeGraphEntry implements ITimeGraphEntry { - /** Id field that may be used by views, so they don't have to extend this class if they don't need to */ - private final int fEntryId; - private final ITmfTrace fTrace; - /** Entry's parent */ private TimeGraphEntry fParent = null; @@ -41,26 +35,19 @@ public class TimeGraphEntry implements ITimeGraphEntry { private long fStartTime = -1; private long fEndTime = -1; private List fEventList = new ArrayList(); - private List fZoomedEventList = null; + private List fZoomedEventList = new ArrayList(); /** * Constructor * - * @param entryid - * Some id attribute for the entry whose state is shown on this - * row - * @param trace - * The trace on which we are working * @param name - * The exec_name of this entry + * The name of this entry * @param startTime - * The start time of this process's lifetime + * The start time of this entry * @param endTime - * The end time of this process + * The end time of this entry */ - public TimeGraphEntry(int entryid, ITmfTrace trace, String name, long startTime, long endTime) { - fEntryId = entryid; - fTrace = trace; + public TimeGraphEntry(String name, long startTime, long endTime) { fName = name; fStartTime = startTime; fEndTime = endTime; @@ -141,25 +128,8 @@ public class TimeGraphEntry implements ITimeGraphEntry { } /** - * Get the id of this entry - * - * @return The entry id - */ - public int getEntryId() { - return fEntryId; - } - - /** - * Get the trace object - * - * @return The trace - */ - public ITmfTrace getTrace() { - return fTrace; - } - - /** - * Add an event to this process's timeline + * Add an event to this entry's event list. If necessary, update the start + * and end time of the entry. * * @param event * The time event @@ -181,8 +151,6 @@ public class TimeGraphEntry implements ITimeGraphEntry { /** * Set the general event list of this entry. * - * Creates a copy of the list to avoid the caller still modifying the list - * * @param eventList * The list of time events */ @@ -190,7 +158,6 @@ public class TimeGraphEntry implements ITimeGraphEntry { if (eventList != null) { fEventList = new ArrayList(eventList); } else { - // the event list should never be null fEventList = new ArrayList(); } } @@ -198,8 +165,6 @@ public class TimeGraphEntry implements ITimeGraphEntry { /** * Set the zoomed event list of this entry. * - * Creates a copy of the list to avoid the caller still modifying the list - * * @param eventList * The list of time events */ @@ -207,14 +172,12 @@ public class TimeGraphEntry implements ITimeGraphEntry { if (eventList != null) { fZoomedEventList = new ArrayList(eventList); } else { - // the zoomed event list can be null - fZoomedEventList = null; + fZoomedEventList = new ArrayList(); } } /** - * Add a child entry to this one (to show relationships between processes as - * a tree) + * Add a child entry to this one * * @param child * The child entry -- 2.34.1