From 03bcc394a3af442aab88d4e5c00bcaa886a188cd Mon Sep 17 00:00:00 2001 From: Patrick Tasse Date: Mon, 18 Jun 2012 17:57:06 -0400 Subject: [PATCH] Fix for bug 382910: Improve responsiveness of Control Flow and Resources views. --- .../ui/views/controlflow/ControlFlowView.java | 31 ++++++++++++++-- .../ui/views/resources/ResourcesView.java | 35 ++++++++++++++++--- .../core/statesystem/StateHistorySystem.java | 12 +++++++ .../core/statesystem/IStateSystemQuerier.java | 32 +++++++++++++++++ 4 files changed, 104 insertions(+), 6 deletions(-) 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 157d45eafb..eaaf90ec87 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 @@ -101,6 +101,11 @@ public class ControlFlowView extends TmfView { TRACE_COLUMN }; + /** + * Redraw state enum + */ + private enum State { IDLE, BUSY, PENDING }; + // ------------------------------------------------------------------------ // Fields // ------------------------------------------------------------------------ @@ -138,6 +143,12 @@ public class ControlFlowView extends TmfView { // A comparator class private final ControlFlowEntryComparator fControlFlowEntryComparator = new ControlFlowEntryComparator(); + // The redraw state used to prevent unnecessary queuing of display runnables + private State fRedrawState = State.IDLE; + + // The redraw synchronization object + final private Object fSyncObj = new Object(); + // ------------------------------------------------------------------------ // Classes // ------------------------------------------------------------------------ @@ -278,7 +289,6 @@ public class ControlFlowView extends TmfView { } zoom(entry, fMonitor); } - redraw(); } private void zoom(ControlFlowEntry entry, IProgressMonitor monitor) { @@ -290,6 +300,7 @@ public class ControlFlowView extends TmfView { entry.setZoomedEventList(zoomedEventList); } } + redraw(); for (ControlFlowEntry child : entry.getChildren()) { if (fMonitor.isCanceled()) { return; @@ -667,7 +678,7 @@ public class ControlFlowView extends TmfView { List eventList = null; try { int statusQuark = ssq.getQuarkRelative(entry.getThreadQuark(), Attributes.STATUS); - List statusIntervals = ssq.queryHistoryRange(statusQuark, startTime, endTime - 1, resolution); + List statusIntervals = ssq.queryHistoryRange(statusQuark, startTime, endTime - 1, resolution, monitor); eventList = new ArrayList(statusIntervals.size()); long lastEndTime = -1; for (ITmfStateInterval statusInterval : statusIntervals) { @@ -727,6 +738,14 @@ public class ControlFlowView extends TmfView { } private void redraw() { + synchronized (fSyncObj) { + if (fRedrawState == State.IDLE) { + fRedrawState = State.BUSY; + } else { + fRedrawState = State.PENDING; + return; + } + } Display.getDefault().asyncExec(new Runnable() { @Override public void run() { @@ -735,6 +754,14 @@ public class ControlFlowView extends TmfView { } fTimeGraphCombo.redraw(); fTimeGraphCombo.update(); + synchronized (fSyncObj) { + if (fRedrawState == State.PENDING) { + fRedrawState = State.IDLE; + redraw(); + } else { + fRedrawState = State.IDLE; + } + } } }); } 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 5f6680d3d2..51e0abceaf 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 @@ -75,6 +75,11 @@ public class ResourcesView extends TmfView { /** Initial time range */ private static final long INITIAL_WINDOW_OFFSET = (1L * 100 * 1000 * 1000); // .1sec + /** + * Redraw state enum + */ + private enum State { IDLE, BUSY, PENDING }; + // ------------------------------------------------------------------------ // Fields // ------------------------------------------------------------------------ @@ -109,6 +114,12 @@ public class ResourcesView extends TmfView { // The zoom thread private ZoomThread fZoomThread; + // The redraw state used to prevent unnecessary queuing of display runnables + private State fRedrawState = State.IDLE; + + // The redraw synchronization object + final private Object fSyncObj = new Object(); + // ------------------------------------------------------------------------ // Classes // ------------------------------------------------------------------------ @@ -246,9 +257,9 @@ public class ResourcesView extends TmfView { entry.setZoomedEventList(zoomedEventList); } } + redraw(); } } - redraw(); } public void cancel() { @@ -509,7 +520,7 @@ public class ResourcesView extends TmfView { try { if (entry.getType().equals(Type.CPU)) { int statusQuark = ssq.getQuarkRelative(quark, Attributes.STATUS); - List statusIntervals = ssq.queryHistoryRange(statusQuark, startTime, endTime - 1, resolution); + List statusIntervals = ssq.queryHistoryRange(statusQuark, startTime, endTime - 1, resolution, monitor); eventList = new ArrayList(statusIntervals.size()); long lastEndTime = -1; for (ITmfStateInterval statusInterval : statusIntervals) { @@ -532,7 +543,7 @@ public class ResourcesView extends TmfView { } } } else if (entry.getType().equals(Type.IRQ)) { - List irqIntervals = ssq.queryHistoryRange(quark, startTime, endTime - 1, resolution); + List irqIntervals = ssq.queryHistoryRange(quark, startTime, endTime - 1, resolution, monitor); eventList = new ArrayList(irqIntervals.size()); long lastEndTime = -1; boolean lastIsNull = true; @@ -558,7 +569,7 @@ public class ResourcesView extends TmfView { lastEndTime = time + duration; } } else if (entry.getType().equals(Type.SOFT_IRQ)) { - List softIrqIntervals = ssq.queryHistoryRange(quark, startTime, endTime - 1, resolution); + List softIrqIntervals = ssq.queryHistoryRange(quark, startTime, endTime - 1, resolution, monitor); eventList = new ArrayList(softIrqIntervals.size()); long lastEndTime = -1; boolean lastIsNull = true; @@ -622,6 +633,14 @@ public class ResourcesView extends TmfView { private void redraw() { + synchronized (fSyncObj) { + if (fRedrawState == State.IDLE) { + fRedrawState = State.BUSY; + } else { + fRedrawState = State.PENDING; + return; + } + } Display.getDefault().asyncExec(new Runnable() { @Override public void run() { @@ -630,6 +649,14 @@ public class ResourcesView extends TmfView { } fTimeGraphViewer.getControl().redraw(); fTimeGraphViewer.getControl().update(); + synchronized (fSyncObj) { + if (fRedrawState == State.PENDING) { + fRedrawState = State.IDLE; + redraw(); + } else { + fRedrawState = State.IDLE; + } + } } }); } diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/StateHistorySystem.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/StateHistorySystem.java index 4ee5cdcde7..fb4f585f56 100644 --- a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/StateHistorySystem.java +++ b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/StateHistorySystem.java @@ -18,6 +18,8 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.linuxtools.internal.tmf.core.Tracer; import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException; import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException; @@ -214,6 +216,13 @@ public class StateHistorySystem extends StateSystem implements public List queryHistoryRange(int attributeQuark, long t1, long t2, long resolution) throws TimeRangeException, AttributeNotFoundException { + return queryHistoryRange(attributeQuark, t1, t2, resolution, new NullProgressMonitor()); + } + + @Override + public List queryHistoryRange(int attributeQuark, + long t1, long t2, long resolution, IProgressMonitor monitor) throws TimeRangeException, + AttributeNotFoundException { List intervals; ITmfStateInterval currentInterval; long ts, tEnd; @@ -241,6 +250,9 @@ public class StateHistorySystem extends StateSystem implements */ for (ts = t1; (currentInterval.getEndTime() != -1) && (ts < tEnd); ts += resolution) { + if (monitor.isCanceled()) { + return intervals; + } if (ts <= currentInterval.getEndTime()) { continue; } diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/IStateSystemQuerier.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/IStateSystemQuerier.java index 1e1a68f759..6a2e36125b 100644 --- a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/IStateSystemQuerier.java +++ b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/IStateSystemQuerier.java @@ -14,6 +14,7 @@ package org.eclipse.linuxtools.tmf.core.statesystem; import java.util.List; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException; import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException; import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval; @@ -273,4 +274,35 @@ public interface IStateSystemQuerier { public List queryHistoryRange(int attributeQuark, long t1, long t2, long resolution) throws TimeRangeException, AttributeNotFoundException; + + /** + * Return the state history of a given attribute, but with at most one + * update per "resolution". This can be useful for populating views (where + * it's useless to have more than one query per pixel, for example). + * A progress monitor can be used to cancel the query before completion. + * + * @param attributeQuark + * Which attribute this query is interested in + * @param t1 + * Start time of the range query + * @param t2 + * Target end time of the query. If t2 is greater than the end of + * the trace, we will return what we have up to the end of the + * history. + * @param resolution + * The "step" of this query + * @param monitor + * A progress monitor. If the monitor is canceled during a query, + * we will return what has been found up to that point. + * @return The List of states that happened between t1 and t2 + * @throws TimeRangeException + * If t1 is invalid, if t2 <= t1, or if the resolution isn't + * greater than zero. + * @throws AttributeNotFoundException + * If the attribute doesn't exist + * @since 1.1 + */ + public List queryHistoryRange(int attributeQuark, + long t1, long t2, long resolution, IProgressMonitor monitor) throws TimeRangeException, + AttributeNotFoundException; } -- 2.34.1