2 * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
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
10 package org
.lttng
.scope
.lttng
.kernel
.core
.views
.kernel
.controlflow2
;
12 import static java
.util
.Objects
.requireNonNull
;
14 import java
.util
.LinkedList
;
15 import java
.util
.List
;
16 import java
.util
.concurrent
.FutureTask
;
18 import org
.eclipse
.jdt
.annotation
.Nullable
;
19 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.kernel
.KernelAnalysisModule
;
20 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.kernel
.Attributes
;
21 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystem
;
22 import org
.eclipse
.tracecompass
.statesystem
.core
.StateSystemUtils
;
23 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
24 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateSystemDisposedException
;
25 import org
.eclipse
.tracecompass
.statesystem
.core
.interval
.ITmfStateInterval
;
26 import org
.lttng
.scope
.tmf2
.views
.core
.TimeRange
;
27 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.provider
.statesystem
.StateSystemModelArrowProvider
;
28 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.render
.FlatUIColors
;
29 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.render
.TimeGraphEvent
;
30 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.render
.arrows
.TimeGraphArrow
;
31 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.render
.arrows
.TimeGraphArrowRender
;
32 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.render
.arrows
.TimeGraphArrowSeries
;
33 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.render
.arrows
.TimeGraphArrowSeries
.LineStyle
;
34 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.render
.tree
.TimeGraphTreeElement
;
35 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.render
.tree
.TimeGraphTreeRender
;
37 import com
.google
.common
.collect
.Iterables
;
38 import com
.google
.common
.primitives
.Ints
;
40 public class ControlFlowModelArrowProviderCpus
extends StateSystemModelArrowProvider
{
42 private static final TimeGraphArrowSeries ARROW_SERIES
= new TimeGraphArrowSeries(
43 requireNonNull(Messages
.arrowSeriesCPUs
),
47 public ControlFlowModelArrowProviderCpus() {
48 super(ARROW_SERIES
, KernelAnalysisModule
.ID
);
52 public TimeGraphArrowRender
getArrowRender(TimeGraphTreeRender treeRender
, TimeRange timeRange
, @Nullable FutureTask
<?
> task
) {
53 ITmfStateSystem ss
= getStateSystem();
55 return TimeGraphArrowRender
.EMPTY_RENDER
;
58 List
<Integer
> threadLineQuarks
= ss
.getQuarks(Attributes
.CPUS
, "*", Attributes
.CURRENT_THREAD
); //$NON-NLS-1$
59 List
<List
<TimeGraphArrow
>> allArrows
= new LinkedList
<>();
61 for (int threadLineQuark
: threadLineQuarks
) {
62 List
<ITmfStateInterval
> intervals
= StateSystemUtils
.queryHistoryRange(ss
, threadLineQuark
, timeRange
.getStart(), timeRange
.getEnd(), 1, null);
63 if (task
!= null && task
.isCancelled()) {
64 return TimeGraphArrowRender
.EMPTY_RENDER
;
66 if (intervals
.size() < 2) {
67 /* Not enough states to establish a timeline */
71 String cpuName
= ss
.getAttributeName(ss
.getParentAttributeQuark(threadLineQuark
));
72 Integer cpu
= Ints
.tryParse(cpuName
);
73 List
<TimeGraphArrow
> arrows
= getArrowsFromStates(treeRender
, intervals
, cpu
);
74 allArrows
.add(arrows
);
77 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
79 return TimeGraphArrowRender
.EMPTY_RENDER
;
82 Iterable
<TimeGraphArrow
> flattenedArrows
= Iterables
.concat(allArrows
);
83 return new TimeGraphArrowRender(timeRange
, flattenedArrows
);
86 private List
<TimeGraphArrow
> getArrowsFromStates(TimeGraphTreeRender treeRender
, List
<ITmfStateInterval
> threadTimeline
, @Nullable Integer cpu
) {
87 List
<TimeGraphArrow
> arrows
= new LinkedList
<>();
88 for (int i
= 1; i
< threadTimeline
.size(); i
++) {
89 ITmfStateInterval interval1
= threadTimeline
.get(i
- 1);
90 ITmfStateInterval interval2
= threadTimeline
.get(i
);
91 int thread1
= interval1
.getStateValue().unboxInt();
92 int thread2
= interval2
.getStateValue().unboxInt();
94 if (thread1
== -1 || thread2
== -1) {
95 /* No arrow to draw here */
99 TimeGraphTreeElement startTreeElem
= getTreeElementFromThread(treeRender
, thread1
, cpu
);
100 TimeGraphTreeElement endTreeElem
= getTreeElementFromThread(treeRender
, thread2
, cpu
);
101 TimeGraphEvent startEvent
= new TimeGraphEvent(interval1
.getEndTime(), startTreeElem
);
102 TimeGraphEvent endEvent
= new TimeGraphEvent(interval2
.getStartTime(), endTreeElem
);
104 TimeGraphArrow arrow
= new TimeGraphArrow(startEvent
, endEvent
, getArrowSeries());
110 private static TimeGraphTreeElement
getTreeElementFromThread(TimeGraphTreeRender treeRender
, int tid
, @Nullable Integer cpu
) {
112 // FIXME Could be improved via indexing, to avoid iterating the
114 // array for every single tid.
115 return Iterables
.find(treeRender
.getAllTreeElements(), treeElem
-> {
116 ControlFlowTreeElement cfvTreeElem
= (ControlFlowTreeElement
) treeElem
;
117 return (cfvTreeElem
.getTid() == tid
);
121 throw new IllegalStateException();
123 String prefix
= "0/" + cpu
.toString(); //$NON-NLS-1$
124 return Iterables
.find(treeRender
.getAllTreeElements(), treeElem
-> {
125 ControlFlowTreeElement cfvTreeElem
= (ControlFlowTreeElement
) treeElem
;
126 return cfvTreeElem
.getName().startsWith(prefix
);