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
.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
;
32 import com
.google
.common
.collect
.Iterables
;
33 import com
.google
.common
.primitives
.Ints
;
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
;
41 public class ControlFlowModelArrowProviderCpus
extends StateSystemModelArrowProvider
{
43 private static final TimeGraphArrowSeries ARROW_SERIES
= new TimeGraphArrowSeries(
44 requireNonNull(Messages
.arrowSeriesCPUs
),
48 public ControlFlowModelArrowProviderCpus() {
49 super(ARROW_SERIES
, KernelAnalysisModule
.ID
);
53 public TimeGraphArrowRender
getArrowRender(TimeGraphTreeRender treeRender
, TimeRange timeRange
, @Nullable FutureTask
<?
> task
) {
54 ITmfStateSystem ss
= getStateSystem();
56 return TimeGraphArrowRender
.EMPTY_RENDER
;
59 List
<Integer
> threadLineQuarks
= ss
.getQuarks(Attributes
.CPUS
, "*", Attributes
.CURRENT_THREAD
); //$NON-NLS-1$
60 List
<List
<TimeGraphArrow
>> allArrows
= new LinkedList
<>();
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
;
67 if (intervals
.size() < 2) {
68 /* Not enough states to establish a timeline */
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
);
78 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
80 return TimeGraphArrowRender
.EMPTY_RENDER
;
83 Iterable
<TimeGraphArrow
> flattenedArrows
= Iterables
.concat(allArrows
);
84 return new TimeGraphArrowRender(timeRange
, flattenedArrows
);
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();
95 if (thread1
== -1 || thread2
== -1) {
96 /* No arrow to draw here */
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
);
105 TimeGraphArrow arrow
= new TimeGraphArrow(startEvent
, endEvent
, getArrowSeries());
111 private static TimeGraphTreeElement
getTreeElementFromThread(TimeGraphTreeRender treeRender
, int tid
, @Nullable Integer cpu
) {
113 // FIXME Could be improved via indexing, to avoid iterating the
115 // array for every single tid.
116 return Iterables
.find(treeRender
.getAllTreeElements(), treeElem
-> {
117 ControlFlowTreeElement cfvTreeElem
= (ControlFlowTreeElement
) treeElem
;
118 return (cfvTreeElem
.getTid() == tid
);
122 throw new IllegalStateException();
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
);