From: Geneviève Bastien Date: Fri, 13 May 2016 18:39:28 +0000 (-0400) Subject: critical path: bug 489360 Build the critical path in a separate thread X-Git-Url: http://git.efficios.com/?p=deliverable%2Ftracecompass.git;a=commitdiff_plain;h=585f9916e169ebd5e87db4778d5d7e5c7805218c critical path: bug 489360 Build the critical path in a separate thread The critical path content provider was waiting for the analysis to be completed but this often happens in the main thread and the first time, it is the whole graph that needs to be computed and that can block the main thread for a while. This patch uses a separate build thread when the input is changed so it does not block anymore. Change-Id: I9cb99c0d93524961c5f8b45ada59d8a02db49bb0 Signed-off-by: Geneviève Bastien Reviewed-on: https://git.eclipse.org/r/72759 Reviewed-by: Hudson CI Reviewed-by: Bernd Hufmann Tested-by: Bernd Hufmann --- diff --git a/analysis/org.eclipse.tracecompass.analysis.graph.core/src/org/eclipse/tracecompass/analysis/graph/core/criticalpath/CriticalPathModule.java b/analysis/org.eclipse.tracecompass.analysis.graph.core/src/org/eclipse/tracecompass/analysis/graph/core/criticalpath/CriticalPathModule.java index 9b989ad956..30e9289afd 100644 --- a/analysis/org.eclipse.tracecompass.analysis.graph.core/src/org/eclipse/tracecompass/analysis/graph/core/criticalpath/CriticalPathModule.java +++ b/analysis/org.eclipse.tracecompass.analysis.graph.core/src/org/eclipse/tracecompass/analysis/graph/core/criticalpath/CriticalPathModule.java @@ -50,7 +50,7 @@ public class CriticalPathModule extends TmfAbstractAnalysisModule { private @Nullable TmfGraphBuilderModule fGraphModule; - private @Nullable TmfGraph fCriticalPath; + private volatile @Nullable TmfGraph fCriticalPath; /** * Default constructor @@ -138,6 +138,7 @@ public class CriticalPathModule extends TmfAbstractAnalysisModule { @Override protected void parameterChanged(String name) { + fCriticalPath = null; cancel(); resetAnalysis(); schedule(); diff --git a/analysis/org.eclipse.tracecompass.analysis.graph.ui/src/org/eclipse/tracecompass/internal/analysis/graph/ui/criticalpath/view/CriticalPathView.java b/analysis/org.eclipse.tracecompass.analysis.graph.ui/src/org/eclipse/tracecompass/internal/analysis/graph/ui/criticalpath/view/CriticalPathView.java index e716284d5d..1fab74e3e3 100644 --- a/analysis/org.eclipse.tracecompass.analysis.graph.ui/src/org/eclipse/tracecompass/internal/analysis/graph/ui/criticalpath/view/CriticalPathView.java +++ b/analysis/org.eclipse.tracecompass.analysis.graph.ui/src/org/eclipse/tracecompass/internal/analysis/graph/ui/criticalpath/view/CriticalPathView.java @@ -17,8 +17,11 @@ import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jface.viewers.Viewer; @@ -195,10 +198,48 @@ public class CriticalPathView extends AbstractTimeGraphView { } } - private Map> workerMaps = new HashMap<>(); - private Map> workerEntries = new HashMap<>(); - private Map> linkMap = new HashMap<>(); + private class BuildThread extends Thread { + private final ITmfTrace fBuildTrace; + private final IProgressMonitor fMonitor; + + public BuildThread(final ITmfTrace trace) { + super("Critical path view build"); //$NON-NLS-1$ + fBuildTrace = trace; + fMonitor = new NullProgressMonitor(); + } + + @Override + public void run() { + try { + CriticalPathModule module = Iterables.<@Nullable CriticalPathModule> getFirst( + TmfTraceUtils.getAnalysisModulesOfClass(fBuildTrace, CriticalPathModule.class), + null); + if (module == null) { + return; + } + module.schedule(); + if (module.waitForCompletion(fMonitor)) { + refresh(); + } + + } finally { + fSyncLock.lock(); + fBuildThread = null; + fSyncLock.unlock(); + } + } + + public void cancel() { + fMonitor.setCanceled(true); + } + } + + private final Lock fSyncLock = new ReentrantLock(); + private final Map> workerMaps = new HashMap<>(); + private final Map> workerEntries = new HashMap<>(); + private final Map> linkMap = new HashMap<>(); private @Nullable Object fCurrentObject; + private @Nullable BuildThread fBuildThread = null; @Override public ITimeGraphEntry[] getElements(@Nullable Object inputElement) { @@ -278,10 +319,6 @@ public class CriticalPathView extends AbstractTimeGraphView { throw new IllegalStateException("View requires an analysis module"); //$NON-NLS-1$ } - module.schedule(); - if (!module.waitForCompletion()) { - return null; - } final TmfGraph graph = module.getCriticalPath(); return graph; } @@ -339,11 +376,46 @@ public class CriticalPathView extends AbstractTimeGraphView { @Override public void dispose() { - + fSyncLock.lock(); + try { + BuildThread buildThread = fBuildThread; + if (buildThread != null) { + buildThread.cancel(); + } + } finally { + fSyncLock.unlock(); + } } @Override public void inputChanged(@Nullable Viewer viewer, @Nullable Object oldInput, @Nullable Object newInput) { + // The input has changed, the critical path will be re-computed, + // wait for the analysis to be finished, then call the refresh + // method of the view + if (!(newInput instanceof List)) { + return; + } + List list = (List) newInput; + if (list.isEmpty()) { + return; + } + final ITmfTrace trace = getTrace(); + if (trace == null) { + return; + } + + fSyncLock.lock(); + try { + BuildThread buildThread = fBuildThread; + if (buildThread != null) { + buildThread.cancel(); + } + buildThread = new BuildThread(trace); + buildThread.start(); + fBuildThread = buildThread; + } finally { + fSyncLock.unlock(); + } } @Override