Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeneviève Bastien2018-05-01 10:58:16 -0400
committerGenevieve Bastien2018-05-07 16:04:33 -0400
commite23c8beb0f1e0700ef1f69330e6081c9954caa46 (patch)
tree88770f2ba4a535e47055d42f7857db2185241a91
parentf8db6e55d77472c2da4733aa489867cffb3bb260 (diff)
downloadorg.eclipse.tracecompass.incubator-e23c8beb0f1e0700ef1f69330e6081c9954caa46.tar.gz
org.eclipse.tracecompass.incubator-e23c8beb0f1e0700ef1f69330e6081c9954caa46.tar.xz
org.eclipse.tracecompass.incubator-e23c8beb0f1e0700ef1f69330e6081c9954caa46.zip
callstack: Add arrows to flame chart data provider
When fetching arrows, the get arrows fetches arrows from all callstack analyses and tries to find a matching entry in the analysis's own data. Change-Id: Iad1baf85bbcae0ecac759c3212bc7e761007e4ce Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net> Reviewed-on: https://git.eclipse.org/r/121970 Tested-by: CI Bot Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com> Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
-rw-r--r--callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/callstack/core/flamechart/CallStack.java28
-rw-r--r--callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/callstack/core/instrumented/CallStackDepth.java9
-rw-r--r--callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/provider/FlameChartArrowProvider.java63
-rw-r--r--callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/provider/FlameChartDataProvider.java53
4 files changed, 151 insertions, 2 deletions
diff --git a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/callstack/core/flamechart/CallStack.java b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/callstack/core/flamechart/CallStack.java
index 4a171c83..d51ca350 100644
--- a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/callstack/core/flamechart/CallStack.java
+++ b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/callstack/core/flamechart/CallStack.java
@@ -260,6 +260,34 @@ public class CallStack {
}
/**
+ * Get the depth of this callstack, at the time of query.
+ *
+ * @param time
+ * The reference time from which to calculate the next depth
+ * @return The depth of the callstack at the time of query. If there is no
+ * value, it will return 0
+ */
+ public int getCurrentDepth(long time) {
+ // Check the time
+ if (time < fStateSystem.getStartTime() || time > fStateSystem.getCurrentEndTime()) {
+ return 0;
+ }
+ Integer oneQuark = fQuarks.get(0);
+ int parent = fStateSystem.getParentAttributeQuark(oneQuark);
+ try {
+ ITmfStateInterval currentDepth = fStateSystem.querySingleState(time, parent);
+ Object value = currentDepth.getValue();
+ if (!(value instanceof Integer)) {
+ return 0;
+ }
+ return (Integer) value;
+ } catch (StateSystemDisposedException e) {
+ // Do nothing
+ }
+ return 0;
+ }
+
+ /**
* Iterate over the callstack in a depth-first manner
*
* @param startTime
diff --git a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/callstack/core/instrumented/CallStackDepth.java b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/callstack/core/instrumented/CallStackDepth.java
index 2a408e0c..8667e3fc 100644
--- a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/callstack/core/instrumented/CallStackDepth.java
+++ b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/callstack/core/instrumented/CallStackDepth.java
@@ -57,6 +57,15 @@ public class CallStackDepth {
return fCallstack;
}
+ /**
+ * Get the depth in the callstack this object represents
+ *
+ * @return The depth in the callstack
+ */
+ public int getDepth() {
+ return fDepth;
+ }
+
@Override
public int hashCode() {
// Compare with the actual callstack object, as the callstack's own hash may
diff --git a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/provider/FlameChartArrowProvider.java b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/provider/FlameChartArrowProvider.java
new file mode 100644
index 00000000..fba0dc9c
--- /dev/null
+++ b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/provider/FlameChartArrowProvider.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2018 É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
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.incubator.internal.callstack.core.instrumented.provider;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+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.tracecompass.incubator.callstack.core.instrumented.statesystem.InstrumentedCallStackAnalysis;
+import org.eclipse.tracecompass.internal.provisional.tmf.core.model.filters.TimeQueryFilter;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
+
+/**
+ * Provide arrows for a flame chart. These arrows may come from any other flame
+ * chart analysis.
+ *
+ * @author Geneviève Bastien
+ */
+public class FlameChartArrowProvider {
+
+ private final ITmfTrace fTrace;
+
+ /**
+ * Constructor
+ *
+ * @param trace
+ * The trace for which this data provider applies
+ */
+ public FlameChartArrowProvider(ITmfTrace trace) {
+ fTrace = trace;
+ }
+
+ public List<ITmfStateInterval> fetchArrows(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+ long start = filter.getStart();
+ long end = filter.getEnd();
+
+ InstrumentedCallStackAnalysis csModule = null;
+ Iterable<InstrumentedCallStackAnalysis> modules = TmfTraceUtils.getAnalysisModulesOfClass(fTrace, InstrumentedCallStackAnalysis.class);
+ // TODO Support many analysis modules, here we take only the first one
+ Iterator<InstrumentedCallStackAnalysis> iterator = modules.iterator();
+ if (!iterator.hasNext()) {
+ return Collections.emptyList();
+ }
+ csModule = iterator.next();
+ csModule.schedule();
+ List<@NonNull ITmfStateInterval> edges = csModule.getLinks(start, end, monitor == null ? new NullProgressMonitor() : monitor);
+
+ return edges;
+ }
+}
diff --git a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/provider/FlameChartDataProvider.java b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/provider/FlameChartDataProvider.java
index 885efab8..2995f5fc 100644
--- a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/provider/FlameChartDataProvider.java
+++ b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/provider/FlameChartDataProvider.java
@@ -35,6 +35,7 @@ import org.eclipse.tracecompass.analysis.os.linux.core.model.HostThread;
import org.eclipse.tracecompass.common.core.log.TraceCompassLog;
import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.FlowScopeLog;
import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.FlowScopeLogBuilder;
+import org.eclipse.tracecompass.incubator.callstack.core.base.EdgeStateValue;
import org.eclipse.tracecompass.incubator.callstack.core.base.ICallStackElement;
import org.eclipse.tracecompass.incubator.callstack.core.flamechart.CallStack;
import org.eclipse.tracecompass.incubator.callstack.core.instrumented.CallStackDepth;
@@ -53,6 +54,7 @@ import org.eclipse.tracecompass.internal.provisional.tmf.core.model.timegraph.IT
import org.eclipse.tracecompass.internal.provisional.tmf.core.model.timegraph.ITimeGraphDataProvider;
import org.eclipse.tracecompass.internal.provisional.tmf.core.model.timegraph.ITimeGraphRowModel;
import org.eclipse.tracecompass.internal.provisional.tmf.core.model.timegraph.ITimeGraphState;
+import org.eclipse.tracecompass.internal.provisional.tmf.core.model.timegraph.TimeGraphArrow;
import org.eclipse.tracecompass.internal.provisional.tmf.core.model.timegraph.TimeGraphRowModel;
import org.eclipse.tracecompass.internal.provisional.tmf.core.model.timegraph.TimeGraphState;
import org.eclipse.tracecompass.internal.provisional.tmf.core.response.ITmfResponse;
@@ -206,6 +208,7 @@ public class FlameChartDataProvider extends AbstractTmfTraceDataProvider impleme
private final String fAnalysisId;
private final ReentrantReadWriteLock fLock = new ReentrantReadWriteLock(false);
+ private final FlameChartArrowProvider fArrowProvider;
private @Nullable TmfModelResponse<List<FlameChartEntryModel>> fCached;
private @Nullable ThreadData fThreadData = null;
@@ -223,13 +226,59 @@ public class FlameChartDataProvider extends AbstractTmfTraceDataProvider impleme
super(trace);
fFcProvider = module;
fAnalysisId = secondaryId;
+ fArrowProvider = new FlameChartArrowProvider(trace);
resetFunctionNames(new NullProgressMonitor());
}
@Override
public TmfModelResponse<List<ITimeGraphArrow>> fetchArrows(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
- // TODO Implement
- return new TmfModelResponse<>(null, Status.COMPLETED, CommonStatusMessage.COMPLETED);
+ List<ITmfStateInterval> arrows = fArrowProvider.fetchArrows(filter, monitor);
+ List<ITimeGraphArrow> tgArrows = new ArrayList<>();
+ // First, get the distinct callstacks
+ Set<CallStack> callstacks = fIdToCallstack.values().stream()
+ .map(CallStackDepth::getCallStack)
+ .distinct()
+ .collect(Collectors.toSet());
+ // Find the source and destination entry for each arrow
+ for (ITmfStateInterval interval : arrows) {
+ if (monitor != null && monitor.isCanceled()) {
+ return new TmfModelResponse<>(null, Status.CANCELLED, CommonStatusMessage.TASK_CANCELLED);
+ }
+ EdgeStateValue edge = (EdgeStateValue) interval.getValue();
+ if (edge == null) {
+ /*
+ * by contract all the intervals should have EdgeStateValues but need to check
+ * to avoid NPE
+ */
+ continue;
+ }
+ Long src = findEntry(callstacks, edge.getSource(), interval.getStartTime());
+ Long dst = findEntry(callstacks, edge.getDestination(), interval.getEndTime() + 1);
+ if (src != null && dst != null) {
+ long duration = interval.getEndTime() - interval.getStartTime() + 1;
+ tgArrows.add(new TimeGraphArrow(src, dst, interval.getStartTime(), duration, edge.getId()));
+ }
+ }
+ return new TmfModelResponse<>(tgArrows, Status.COMPLETED, CommonStatusMessage.COMPLETED);
+ }
+
+ private @Nullable Long findEntry(Set<CallStack> callstacks, @NonNull HostThread hostThread, long ts) {
+ // Get the
+ for (CallStack callstack : callstacks) {
+ HostThread csHt = callstack.getHostThread(ts);
+ if (csHt == null || !csHt.equals(hostThread)) {
+ continue;
+ }
+ // We found the callstack, find the right depth and its entry id
+ int currentDepth = callstack.getCurrentDepth(ts);
+ for (Entry<Long, CallStackDepth> csdEntry : fIdToCallstack.entrySet()) {
+ CallStackDepth csd = csdEntry.getValue();
+ if (csd.getDepth() == currentDepth && csd.getCallStack().equals(callstack)) {
+ return csdEntry.getKey();
+ }
+ }
+ }
+ return null;
}
@Override

Back to the top