blob: 4a20805c6f566abaac1325bb95dc713856f71e6f [file] [log] [blame]
/*******************************************************************************
* 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();
}
}