1 /*******************************************************************************
2 * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
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 *******************************************************************************/
10 package org
.lttng
.scope
.lttng
.kernel
.core
.views
.timegraph
.threads
;
12 import static java
.util
.Objects
.requireNonNull
;
14 import java
.util
.Collections
;
15 import java
.util
.Comparator
;
16 import java
.util
.List
;
17 import java
.util
.function
.Function
;
18 import java
.util
.function
.Supplier
;
19 import java
.util
.stream
.Collectors
;
20 import java
.util
.stream
.Stream
;
22 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.kernel
.KernelAnalysisModule
;
23 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.kernel
.Attributes
;
24 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystem
;
25 import org
.eclipse
.tracecompass
.statesystem
.core
.StateSystemUtils
;
26 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
27 import org
.eclipse
.tracecompass
.statesystem
.core
.interval
.ITmfStateInterval
;
28 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.provider
.arrows
.ITimeGraphModelArrowProvider
;
29 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.provider
.states
.ITimeGraphModelStateProvider
;
30 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.provider
.statesystem
.StateSystemModelProvider
;
31 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.render
.tree
.TimeGraphTreeElement
;
32 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.render
.tree
.TimeGraphTreeRender
;
34 import com
.google
.common
.annotations
.VisibleForTesting
;
35 import com
.google
.common
.collect
.ImmutableList
;
37 public class ThreadsModelProvider
extends StateSystemModelProvider
{
39 private static final Supplier
<ITimeGraphModelStateProvider
> STATE_PROVIDER
= () -> {
40 return new ThreadsModelStateProvider();
43 private static final Supplier
<List
<ITimeGraphModelArrowProvider
>> ARROW_PROVIDERS
= () -> {
44 return ImmutableList
.of(
45 new ThreadsModelArrowProviderCpus()
49 private static final List
<SortingMode
> SORTING_MODES
= ImmutableList
.of(
50 ThreadsConfigModes
.SORTING_BY_TID
,
51 ThreadsConfigModes
.SORTING_BY_THREAD_NAME
);
53 private static final List
<FilterMode
> FILTER_MODES
= ImmutableList
.of(
54 ThreadsConfigModes
.FILTERING_INACTIVE_ENTRIES
);
56 // ------------------------------------------------------------------------
58 // ------------------------------------------------------------------------
61 * State values that are considered inactive, for purposes of filtering out
62 * when the "filter inactive entries" mode is enabled.
64 // private static final Set<ITmfStateValue> INACTIVE_STATE_VALUES = ImmutableSet.of(
65 // TmfStateValue.nullValue(),
66 // StateValues.PROCESS_STATUS_UNKNOWN_VALUE,
67 // StateValues.PROCESS_STATUS_WAIT_UNKNOWN_VALUE,
68 // StateValues.PROCESS_STATUS_WAIT_BLOCKED_VALUE
72 * Each "Thread" attribute has the following children:
76 * <li>System_call</li>
81 * The "Thread" is considered the base quark.
83 private static final String
[] BASE_QUARK_PATTERN
= { Attributes
.THREADS
, "*" }; //$NON-NLS-1$
86 * Get the tree element name for every thread. It consists of the TID
87 * followed by the first available exec_name for this thread.
89 * FIXME This implies a static tree definition for every TID, which does not
90 * handle TID re-use correctly. The state system structure should be updated
94 public static final Function
<TreeRenderContext
, TimeGraphTreeRender
> SS_TO_TREE_RENDER_FUNCTION
= (treeContext
) -> {
95 ITmfStateSystem ss
= treeContext
.ss
;
96 // List<ITmfStateInterval> fullState = treeContext.fullQueryAtRangeStart;
98 Stream
<ThreadsTreeElement
> treeElems
= ss
.getQuarks(BASE_QUARK_PATTERN
).stream()
100 String tid
= ss
.getAttributeName(baseQuark
);
104 int execNameQuark
= ss
.getQuarkRelative(baseQuark
, Attributes
.EXEC_NAME
);
105 // TODO We should look starting at
106 // treeContext.renderTimeRangeStart first, and if we
107 // don't find anything use ss.getStartTime(), so that we
108 // catch subsequent process name changes
109 ITmfStateInterval firstInterval
= StateSystemUtils
.queryUntilNonNullValue(ss
,
110 execNameQuark
, ss
.getStartTime(), Long
.MAX_VALUE
);
111 if (firstInterval
== null) {
114 threadName
= firstInterval
.getStateValue().unboxStr();
116 } catch (AttributeNotFoundException e
) {
120 return new ThreadsTreeElement(tid
, threadName
, Collections
.emptyList(), baseQuark
);
123 /* Run the entries through the active filter modes */
124 // Set<FilterMode> filterModes = treeContext.filterModes;
125 // if (filterModes.contains(ControlFlowConfigModes.FILTERING_INACTIVE_ENTRIES)) {
127 // * Filter out the tree elements whose state is considered inactive
128 // * for the whole duration of the configured time range.
130 // treeElems = treeElems.filter(elem -> {
131 // ITmfStateInterval interval = fullState.get(elem.getSourceQuark());
132 // if (interval.getEndTime() > treeContext.renderTimeRangeEnd &&
133 // INACTIVE_STATE_VALUES.contains(interval.getStateValue())) {
140 /* Sort entries according to the active sorting mode */
141 SortingMode sortingMode
= treeContext
.sortingMode
;
142 if (sortingMode
== ThreadsConfigModes
.SORTING_BY_TID
) {
143 treeElems
= treeElems
.sorted(Comparator
.comparingInt(ThreadsTreeElement
::getTid
));
144 } else if (sortingMode
== ThreadsConfigModes
.SORTING_BY_THREAD_NAME
) {
145 treeElems
= treeElems
.sorted((elem1
, elem2
) -> {
146 return elem1
.getThreadName().compareToIgnoreCase(elem2
.getThreadName());
150 List
<TimeGraphTreeElement
> treeElemsList
= treeElems
.collect(Collectors
.toList());
151 TimeGraphTreeElement rootElement
= new TimeGraphTreeElement(treeContext
.traceName
, treeElemsList
);
152 return new TimeGraphTreeRender(rootElement
);
158 public ThreadsModelProvider() {
159 super(requireNonNull(Messages
.threadsProviderName
),
162 STATE_PROVIDER
.get(),
163 ARROW_PROVIDERS
.get(),
164 /* Parameters specific to state system render providers */
165 KernelAnalysisModule
.ID
,
166 SS_TO_TREE_RENDER_FUNCTION
);