| /******************************************************************************* |
| * Copyright (c) 2015 É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 2.0 which |
| * accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| *******************************************************************************/ |
| |
| package org.eclipse.tracecompass.analysis.graph.core.building; |
| |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.jdt.annotation.NonNull; |
| import org.eclipse.jdt.annotation.Nullable; |
| import org.eclipse.tracecompass.analysis.graph.core.base.TmfGraph; |
| import org.eclipse.tracecompass.analysis.graph.core.criticalpath.CriticalPathModule; |
| import org.eclipse.tracecompass.analysis.graph.core.criticalpath.ICriticalPathProvider; |
| import org.eclipse.tracecompass.internal.analysis.graph.core.Activator; |
| import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule; |
| import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; |
| import org.eclipse.tracecompass.tmf.core.event.TmfEvent; |
| import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; |
| import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; |
| import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; |
| import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; |
| import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; |
| |
| /** |
| * Base class for all modules building graphs |
| * |
| * @author Francis Giraldeau |
| * @author Geneviève Bastien |
| */ |
| public abstract class TmfGraphBuilderModule extends TmfAbstractAnalysisModule implements ICriticalPathProvider { |
| |
| private @Nullable TmfGraph fGraph; |
| private @Nullable ITmfEventRequest fRequest; |
| private final CriticalPathModule fCriticalPathModule; |
| |
| /** |
| * Constructor |
| */ |
| public TmfGraphBuilderModule() { |
| fCriticalPathModule = new CriticalPathModule(this); |
| } |
| |
| /** |
| * Gets the graph provider to build this graph |
| * |
| * @return The graph provider |
| */ |
| protected abstract ITmfGraphProvider getGraphProvider(); |
| |
| /** |
| * Gets the graph generated by the analysis |
| * |
| * @return The generated graph |
| */ |
| public @Nullable TmfGraph getGraph() { |
| return fGraph; |
| } |
| |
| // ------------------------------------------------------------------------ |
| // TmfAbstractAnalysisModule |
| // ------------------------------------------------------------------------ |
| |
| @Override |
| protected boolean executeAnalysis(final IProgressMonitor monitor) { |
| if (fGraph == null) { |
| final ITmfGraphProvider provider = getGraphProvider(); |
| |
| /* |
| * TODO: This will eventually support multiple backends so we can |
| * save the graph on disk, like the state system, but for now, it is |
| * just in memory |
| */ |
| |
| createGraph(provider); |
| |
| } |
| return !monitor.isCanceled(); |
| } |
| |
| @Override |
| public boolean setTrace(@NonNull ITmfTrace trace) throws TmfAnalysisException { |
| boolean ret = super.setTrace(trace); |
| if (!ret) { |
| return ret; |
| } |
| ret = fCriticalPathModule.setTrace(trace); |
| return ret; |
| } |
| |
| @Override |
| protected void canceling() { |
| ITmfEventRequest req = fRequest; |
| if ((req != null) && (!req.isCompleted())) { |
| req.cancel(); |
| } |
| } |
| |
| @Override |
| public void dispose() { |
| fCriticalPathModule.dispose(); |
| super.dispose(); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // Graph creation methods |
| // ------------------------------------------------------------------------ |
| |
| private void createGraph(ITmfGraphProvider provider) { |
| |
| fGraph = new TmfGraph(); |
| provider.assignTargetGraph(fGraph); |
| |
| build(provider); |
| |
| } |
| |
| private void build(ITmfGraphProvider provider) { |
| /* Cancel any previous request */ |
| ITmfEventRequest request = fRequest; |
| if ((request != null) && (!request.isCompleted())) { |
| request.cancel(); |
| } |
| |
| try { |
| request = new TmfGraphBuildRequest(provider); |
| fRequest = request; |
| provider.getTrace().sendRequest(request); |
| |
| request.waitForCompletion(); |
| } catch (InterruptedException e) { |
| Activator.getInstance().logError("Request interrupted", e); //$NON-NLS-1$ |
| Thread.currentThread().interrupt(); |
| } |
| } |
| |
| private static class TmfGraphBuildRequest extends TmfEventRequest { |
| |
| private final ITmfGraphProvider fProvider; |
| |
| /** |
| * Constructor |
| * |
| * @param provider |
| * The graph provider |
| */ |
| public TmfGraphBuildRequest(ITmfGraphProvider provider) { |
| super(TmfEvent.class, |
| TmfTimeRange.ETERNITY, |
| 0, |
| ITmfEventRequest.ALL_DATA, |
| ITmfEventRequest.ExecutionType.BACKGROUND); |
| |
| fProvider = provider; |
| } |
| |
| @Override |
| public void handleData(final ITmfEvent event) { |
| super.handleData(event); |
| fProvider.processEvent(event); |
| } |
| |
| @Override |
| public synchronized void done() { |
| super.done(); |
| fProvider.done(); |
| } |
| |
| @Override |
| public void handleCancel() { |
| fProvider.handleCancel(); |
| super.handleCancel(); |
| } |
| |
| } |
| |
| /** |
| * @since 1.1 |
| */ |
| @Override |
| public @Nullable TmfGraph getCriticalPath() { |
| return fCriticalPathModule.getCriticalPath(); |
| } |
| |
| } |