310c99f198af1a510d8b4e8ea570ad9d35c29a42
[deliverable/tracecompass.git] / lttng / org.lttng.scope.lttng.kernel.core / src / org / lttng / scope / lttng / kernel / core / views / timegraph / threads / ThreadsModelProvider.java
1 /*******************************************************************************
2 * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
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.timegraph.threads;
11
12 import static java.util.Objects.requireNonNull;
13
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;
21
22 import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
23 import org.lttng.scope.lttng.kernel.core.analysis.os.KernelAnalysisModule;
24 import org.lttng.scope.tmf2.views.core.timegraph.model.provider.arrows.ITimeGraphModelArrowProvider;
25 import org.lttng.scope.tmf2.views.core.timegraph.model.provider.states.ITimeGraphModelStateProvider;
26 import org.lttng.scope.tmf2.views.core.timegraph.model.provider.statesystem.StateSystemModelProvider;
27 import org.lttng.scope.tmf2.views.core.timegraph.model.render.tree.TimeGraphTreeElement;
28 import org.lttng.scope.tmf2.views.core.timegraph.model.render.tree.TimeGraphTreeRender;
29
30 import com.google.common.annotations.VisibleForTesting;
31 import com.google.common.collect.ImmutableList;
32
33 import ca.polymtl.dorsal.libdelorean.ITmfStateSystem;
34 import ca.polymtl.dorsal.libdelorean.StateSystemUtils;
35 import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
36 import ca.polymtl.dorsal.libdelorean.interval.ITmfStateInterval;
37
38 public class ThreadsModelProvider extends StateSystemModelProvider {
39
40 private static final Supplier<ITimeGraphModelStateProvider> STATE_PROVIDER = () -> {
41 return new ThreadsModelStateProvider();
42 };
43
44 private static final Supplier<List<ITimeGraphModelArrowProvider>> ARROW_PROVIDERS = () -> {
45 return ImmutableList.of(
46 new ThreadsModelArrowProviderCpus()
47 );
48 };
49
50 private static final List<SortingMode> SORTING_MODES = ImmutableList.of(
51 ThreadsConfigModes.SORTING_BY_TID,
52 ThreadsConfigModes.SORTING_BY_THREAD_NAME);
53
54 private static final List<FilterMode> FILTER_MODES = ImmutableList.of(
55 ThreadsConfigModes.FILTERING_INACTIVE_ENTRIES);
56
57 // ------------------------------------------------------------------------
58 // Tree render
59 // ------------------------------------------------------------------------
60
61 /**
62 * State values that are considered inactive, for purposes of filtering out
63 * when the "filter inactive entries" mode is enabled.
64 */
65 // private static final Set<ITmfStateValue> INACTIVE_STATE_VALUES = ImmutableSet.of(
66 // TmfStateValue.nullValue(),
67 // StateValues.PROCESS_STATUS_UNKNOWN_VALUE,
68 // StateValues.PROCESS_STATUS_WAIT_UNKNOWN_VALUE,
69 // StateValues.PROCESS_STATUS_WAIT_BLOCKED_VALUE
70 // );
71
72 /**
73 * Each "Thread" attribute has the following children:
74 *
75 * <ul>
76 * <li>Prio</li>
77 * <li>System_call</li>
78 * <li>Exec_name</li>
79 * <li>PPID</li>
80 * </ul>
81 *
82 * The "Thread" is considered the base quark.
83 */
84 private static final String[] BASE_QUARK_PATTERN = { Attributes.THREADS, "*" }; //$NON-NLS-1$
85
86 /**
87 * Get the tree element name for every thread. It consists of the TID
88 * followed by the first available exec_name for this thread.
89 *
90 * FIXME This implies a static tree definition for every TID, which does not
91 * handle TID re-use correctly. The state system structure should be updated
92 * accordingly.
93 */
94 @VisibleForTesting
95 public static final Function<TreeRenderContext, TimeGraphTreeRender> SS_TO_TREE_RENDER_FUNCTION = (treeContext) -> {
96 ITmfStateSystem ss = treeContext.ss;
97 // List<ITmfStateInterval> fullState = treeContext.fullQueryAtRangeStart;
98
99 Stream<ThreadsTreeElement> treeElems = ss.getQuarks(BASE_QUARK_PATTERN).stream()
100 .map(baseQuark -> {
101 String tid = ss.getAttributeName(baseQuark);
102
103 String threadName;
104 try {
105 int execNameQuark = ss.getQuarkRelative(baseQuark, Attributes.EXEC_NAME);
106 // TODO We should look starting at
107 // treeContext.renderTimeRangeStart first, and if we
108 // don't find anything use ss.getStartTime(), so that we
109 // catch subsequent process name changes
110 ITmfStateInterval firstInterval = StateSystemUtils.queryUntilNonNullValue(ss,
111 execNameQuark, ss.getStartTime(), Long.MAX_VALUE);
112 if (firstInterval == null) {
113 threadName = null;
114 } else {
115 threadName = firstInterval.getStateValue().unboxStr();
116 }
117 } catch (AttributeNotFoundException e) {
118 threadName = null;
119 }
120
121 return new ThreadsTreeElement(tid, threadName, Collections.emptyList(), baseQuark);
122 });
123
124 /* Run the entries through the active filter modes */
125 // Set<FilterMode> filterModes = treeContext.filterModes;
126 // if (filterModes.contains(ControlFlowConfigModes.FILTERING_INACTIVE_ENTRIES)) {
127 // /*
128 // * Filter out the tree elements whose state is considered inactive
129 // * for the whole duration of the configured time range.
130 // */
131 // treeElems = treeElems.filter(elem -> {
132 // ITmfStateInterval interval = fullState.get(elem.getSourceQuark());
133 // if (interval.getEndTime() > treeContext.renderTimeRangeEnd &&
134 // INACTIVE_STATE_VALUES.contains(interval.getStateValue())) {
135 // return false;
136 // }
137 // return true;
138 // });
139 // }
140
141 /* Sort entries according to the active sorting mode */
142 SortingMode sortingMode = treeContext.sortingMode;
143 if (sortingMode == ThreadsConfigModes.SORTING_BY_TID) {
144 treeElems = treeElems.sorted(Comparator.comparingInt(ThreadsTreeElement::getTid));
145 } else if (sortingMode == ThreadsConfigModes.SORTING_BY_THREAD_NAME) {
146 treeElems = treeElems.sorted((elem1, elem2) -> {
147 return elem1.getThreadName().compareToIgnoreCase(elem2.getThreadName());
148 });
149 }
150
151 List<TimeGraphTreeElement> treeElemsList = treeElems.collect(Collectors.toList());
152 TimeGraphTreeElement rootElement = new TimeGraphTreeElement(treeContext.traceName, treeElemsList);
153 return new TimeGraphTreeRender(rootElement);
154 };
155
156 /**
157 * Constructor
158 */
159 public ThreadsModelProvider() {
160 super(requireNonNull(Messages.threadsProviderName),
161 SORTING_MODES,
162 FILTER_MODES,
163 STATE_PROVIDER.get(),
164 ARROW_PROVIDERS.get(),
165 /* Parameters specific to state system render providers */
166 KernelAnalysisModule.ID,
167 SS_TO_TREE_RENDER_FUNCTION);
168
169 enableFilterMode(0);
170 }
171
172 }
This page took 0.034782 seconds and 4 git commands to generate.