/*******************************************************************************
- * Copyright (c) 2015 École Polytechnique de Montréal
+ * Copyright (c) 2015, 2016 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
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;
import org.eclipse.tracecompass.analysis.graph.core.base.TmfEdge.EdgeType;
import org.eclipse.tracecompass.analysis.graph.core.base.TmfGraph;
import org.eclipse.tracecompass.analysis.graph.core.base.TmfVertex;
+import org.eclipse.tracecompass.analysis.graph.core.building.TmfGraphBuilderModule;
import org.eclipse.tracecompass.analysis.graph.core.criticalpath.CriticalPathModule;
import org.eclipse.tracecompass.common.core.NonNullUtils;
import org.eclipse.tracecompass.internal.analysis.graph.core.base.TmfGraphStatistics;
fRootList.put(owner, entry);
}
- @Override
- public void visit(TmfVertex node) {
- setStartTime(Math.min(getStartTime(), node.getTs()));
- setEndTime(Math.max(getEndTime(), node.getTs()));
- }
-
@Override
public void visit(TmfEdge link, boolean horizontal) {
if (horizontal) {
}
}
- private Map<Object, Map<Object, CriticalPathEntry>> workerMaps = new HashMap<>();
- private Map<Object, List<TimeGraphEntry>> workerEntries = new HashMap<>();
- private Map<Object, List<ILinkEvent>> 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)) {
+ // Module is completed, set the start and end time of
+ // this view
+ setStartEndTime(module);
+ refresh();
+ }
+
+ } finally {
+ fSyncLock.lock();
+ fBuildThread = null;
+ fSyncLock.unlock();
+ }
+ }
+
+ public void cancel() {
+ fMonitor.setCanceled(true);
+ }
+ }
+
+ private final Lock fSyncLock = new ReentrantLock();
+ private final Map<Object, Map<Object, CriticalPathEntry>> workerMaps = new HashMap<>();
+ private final Map<Object, List<TimeGraphEntry>> workerEntries = new HashMap<>();
+ private final Map<Object, List<ILinkEvent>> linkMap = new HashMap<>();
private @Nullable Object fCurrentObject;
+ private @Nullable BuildThread fBuildThread = null;
@Override
public ITimeGraphEntry[] getElements(@Nullable Object inputElement) {
private ITimeGraphEntry[] getWorkerEntries(IGraphWorker worker) {
fCurrentObject = worker;
List<TimeGraphEntry> entries = workerEntries.get(worker);
+ ITmfTrace trace = getTrace();
if (entries == null) {
buildEntryList(worker);
entries = workerEntries.get(worker);
+ } else if (trace != null) {
+ // Get the statistics object for this worker
+ TmfGraphStatistics stats = fObjectStatistics.get(trace, worker);
+ if (stats == null) {
+ stats = new TmfGraphStatistics();
+ final TmfGraph graph = getGraph(trace);
+ if (graph != null) {
+ stats.computeGraphStatistics(graph, worker);
+ }
+ }
+ fStats = stats;
}
return (entries == null) ?
if (graph == null) {
return;
}
- setStartTime(Long.MAX_VALUE);
- setEndTime(Long.MIN_VALUE);
final HashMap<Object, CriticalPathEntry> rootList = new HashMap<>();
fLinks.remove(trace, worker);
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;
}
@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
}
@Override
- protected void buildEventList(@NonNull ITmfTrace trace, @NonNull ITmfTrace parentTrace, @NonNull IProgressMonitor monitor) {
+ protected void buildEntryList(@NonNull ITmfTrace trace, @NonNull ITmfTrace parentTrace, @NonNull IProgressMonitor monitor) {
/* This class uses a content provider instead */
}
throw new IllegalStateException("Trace is null"); //$NON-NLS-1$
}
IGraphWorker worker = (IGraphWorker) obj;
- TmfGraphStatistics stats = fObjectStatistics.get(trace, worker);
- if (stats == null) {
- stats = new TmfGraphStatistics();
- fObjectStatistics.put(trace, worker, stats);
- }
- fStats = stats;
TimeGraphEntry tge = new CriticalPathBaseEntry(worker);
List<TimeGraphEntry> list = Collections.singletonList(tge);
refresh();
}
+ private void setStartEndTime(CriticalPathModule module) {
+ // Initialize the start/end time of the view to trace's times
+ ITmfTrace trace = getTrace();
+ if (trace == null) {
+ throw new IllegalStateException("The trace should not be null when we have a critical path to display"); //$NON-NLS-1$
+ }
+ long start = trace.getStartTime().toNanos();
+ long end = trace.getEndTime().toNanos();
+
+ // Set the start/end time of the view
+ Object paramGraph = module.getParameter(CriticalPathModule.PARAM_GRAPH);
+ if (paramGraph instanceof TmfGraphBuilderModule) {
+ TmfGraphBuilderModule graphModule = (TmfGraphBuilderModule) paramGraph;
+ TmfGraph graph = graphModule.getGraph();
+ if (graph == null) {
+ return;
+ }
+ TmfVertex head = graph.getHead();
+ if (head != null) {
+ start = Math.min(start, head.getTs());
+ for (IGraphWorker w : graph.getWorkers()) {
+ TmfVertex tail = graph.getTail(w);
+ if (tail != null) {
+ end = Math.max(end, tail.getTs());
+ }
+ }
+ }
+ }
+ setStartTime(start);
+ setEndTime(end);
+ }
+
}