50650249887741ffa93d24c8e9f65dd9fce6bb75
[deliverable/tracecompass.git] / lttng / org.lttng.scope.lttng.kernel.core / src / org / lttng / scope / lttng / kernel / core / views / kernel / controlflow2 / ControlFlowModelArrowProviderCpus.java
1 /*
2 * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 */
9
10 package org.lttng.scope.lttng.kernel.core.views.kernel.controlflow2;
11
12 import static java.util.Objects.requireNonNull;
13
14 import java.util.LinkedList;
15 import java.util.List;
16 import java.util.concurrent.FutureTask;
17
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
20 import org.lttng.scope.lttng.kernel.core.analysis.os.KernelAnalysisModule;
21 import org.lttng.scope.tmf2.views.core.TimeRange;
22 import org.lttng.scope.tmf2.views.core.timegraph.model.provider.statesystem.StateSystemModelArrowProvider;
23 import org.lttng.scope.tmf2.views.core.timegraph.model.render.FlatUIColors;
24 import org.lttng.scope.tmf2.views.core.timegraph.model.render.TimeGraphEvent;
25 import org.lttng.scope.tmf2.views.core.timegraph.model.render.arrows.TimeGraphArrow;
26 import org.lttng.scope.tmf2.views.core.timegraph.model.render.arrows.TimeGraphArrowRender;
27 import org.lttng.scope.tmf2.views.core.timegraph.model.render.arrows.TimeGraphArrowSeries;
28 import org.lttng.scope.tmf2.views.core.timegraph.model.render.arrows.TimeGraphArrowSeries.LineStyle;
29 import org.lttng.scope.tmf2.views.core.timegraph.model.render.tree.TimeGraphTreeElement;
30 import org.lttng.scope.tmf2.views.core.timegraph.model.render.tree.TimeGraphTreeRender;
31
32 import com.google.common.collect.Iterables;
33 import com.google.common.primitives.Ints;
34
35 import ca.polymtl.dorsal.libdelorean.ITmfStateSystem;
36 import ca.polymtl.dorsal.libdelorean.StateSystemUtils;
37 import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
38 import ca.polymtl.dorsal.libdelorean.exceptions.StateSystemDisposedException;
39 import ca.polymtl.dorsal.libdelorean.interval.ITmfStateInterval;
40
41 public class ControlFlowModelArrowProviderCpus extends StateSystemModelArrowProvider {
42
43 private static final TimeGraphArrowSeries ARROW_SERIES = new TimeGraphArrowSeries(
44 requireNonNull(Messages.arrowSeriesCPUs),
45 FlatUIColors.RED,
46 LineStyle.FULL);
47
48 public ControlFlowModelArrowProviderCpus() {
49 super(ARROW_SERIES, KernelAnalysisModule.ID);
50 }
51
52 @Override
53 public TimeGraphArrowRender getArrowRender(TimeGraphTreeRender treeRender, TimeRange timeRange, @Nullable FutureTask<?> task) {
54 ITmfStateSystem ss = getStateSystem();
55 if (ss == null) {
56 return TimeGraphArrowRender.EMPTY_RENDER;
57 }
58
59 List<Integer> threadLineQuarks = ss.getQuarks(Attributes.CPUS, "*", Attributes.CURRENT_THREAD); //$NON-NLS-1$
60 List<List<TimeGraphArrow>> allArrows = new LinkedList<>();
61 try {
62 for (int threadLineQuark : threadLineQuarks) {
63 List<ITmfStateInterval> intervals = StateSystemUtils.queryHistoryRange(ss, threadLineQuark, timeRange.getStart(), timeRange.getEnd(), 1, task);
64 if (task != null && task.isCancelled()) {
65 return TimeGraphArrowRender.EMPTY_RENDER;
66 }
67 if (intervals.size() < 2) {
68 /* Not enough states to establish a timeline */
69 continue;
70 }
71
72 String cpuName = ss.getAttributeName(ss.getParentAttributeQuark(threadLineQuark));
73 Integer cpu = Ints.tryParse(cpuName);
74 List<TimeGraphArrow> arrows = getArrowsFromStates(treeRender, intervals, cpu);
75 allArrows.add(arrows);
76 }
77
78 } catch (AttributeNotFoundException | StateSystemDisposedException e) {
79 e.printStackTrace();
80 return TimeGraphArrowRender.EMPTY_RENDER;
81 }
82
83 Iterable<TimeGraphArrow> flattenedArrows = Iterables.concat(allArrows);
84 return new TimeGraphArrowRender(timeRange, flattenedArrows);
85 }
86
87 private List<TimeGraphArrow> getArrowsFromStates(TimeGraphTreeRender treeRender, List<ITmfStateInterval> threadTimeline, @Nullable Integer cpu) {
88 List<TimeGraphArrow> arrows = new LinkedList<>();
89 for (int i = 1; i < threadTimeline.size(); i++) {
90 ITmfStateInterval interval1 = threadTimeline.get(i - 1);
91 ITmfStateInterval interval2 = threadTimeline.get(i);
92 int thread1 = interval1.getStateValue().unboxInt();
93 int thread2 = interval2.getStateValue().unboxInt();
94
95 if (thread1 == -1 || thread2 == -1) {
96 /* No arrow to draw here */
97 continue;
98 }
99
100 TimeGraphTreeElement startTreeElem = getTreeElementFromThread(treeRender, thread1, cpu);
101 TimeGraphTreeElement endTreeElem = getTreeElementFromThread(treeRender, thread2, cpu);
102 TimeGraphEvent startEvent = new TimeGraphEvent(interval1.getEndTime(), startTreeElem);
103 TimeGraphEvent endEvent = new TimeGraphEvent(interval2.getStartTime(), endTreeElem);
104
105 TimeGraphArrow arrow = new TimeGraphArrow(startEvent, endEvent, getArrowSeries());
106 arrows.add(arrow);
107 }
108 return arrows;
109 }
110
111 private static TimeGraphTreeElement getTreeElementFromThread(TimeGraphTreeRender treeRender, int tid, @Nullable Integer cpu) {
112 if (tid != 0) {
113 // FIXME Could be improved via indexing, to avoid iterating the
114 // whole
115 // array for every single tid.
116 return Iterables.find(treeRender.getAllTreeElements(), treeElem -> {
117 ControlFlowTreeElement cfvTreeElem = (ControlFlowTreeElement) treeElem;
118 return (cfvTreeElem.getTid() == tid);
119 });
120 }
121 if (cpu == null) {
122 throw new IllegalStateException();
123 }
124 String prefix = "0/" + cpu.toString(); //$NON-NLS-1$
125 return Iterables.find(treeRender.getAllTreeElements(), treeElem -> {
126 ControlFlowTreeElement cfvTreeElem = (ControlFlowTreeElement) treeElem;
127 return cfvTreeElem.getName().startsWith(prefix);
128 });
129 }
130 }
This page took 0.038091 seconds and 5 git commands to generate.