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
.Arrays
;
15 import java
.util
.Collection
;
16 import java
.util
.List
;
18 import java
.util
.function
.Function
;
20 import org
.eclipse
.jdt
.annotation
.Nullable
;
21 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.kernel
.KernelAnalysisModule
;
22 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.kernel
.StateValues
;
23 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.kernel
.Attributes
;
24 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
25 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateSystemDisposedException
;
26 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateValueTypeException
;
27 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
28 import org
.lttng
.scope
.lttng
.kernel
.core
.views
.timegraph
.KernelAnalysisStateDefinitions
;
29 import org
.lttng
.scope
.tmf2
.views
.core
.config
.ConfigOption
;
30 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.provider
.statesystem
.StateSystemModelStateProvider
;
31 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.render
.ColorDefinition
;
32 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.render
.LineThickness
;
33 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.render
.StateDefinition
;
35 import com
.google
.common
.annotations
.VisibleForTesting
;
36 import com
.google
.common
.collect
.ImmutableList
;
37 import com
.google
.common
.collect
.ImmutableMap
;
39 public class ThreadsModelStateProvider
extends StateSystemModelStateProvider
{
41 // ------------------------------------------------------------------------
43 // ------------------------------------------------------------------------
45 /** Prefixes to strip from syscall names in the labels */
46 // TODO This should be inferred from the kernel event layout
47 private static final Collection
<String
> SYSCALL_PREFIXES
= Arrays
.asList("sys_", "syscall_entry_"); //$NON-NLS-1$ //$NON-NLS-2$
49 private static final Function
<StateIntervalContext
, @Nullable String
> LABEL_MAPPING_FUNCTION
= ssCtx
-> {
50 int statusQuark
= ssCtx
.baseTreeElement
.getSourceQuark();
51 long startTime
= ssCtx
.sourceInterval
.getStartTime();
54 ITmfStateValue val
= ssCtx
.ss
.querySingleState(startTime
, statusQuark
).getStateValue();
56 /* If the status is "syscall", use the name of the syscall as label */
57 if (!val
.equals(StateValues
.PROCESS_STATUS_RUN_SYSCALL_VALUE
)) {
61 int syscallQuark
= ssCtx
.ss
.getQuarkRelative(statusQuark
, Attributes
.SYSTEM_CALL
);
62 syscallName
= ssCtx
.ss
.querySingleState(startTime
, syscallQuark
).getStateValue().unboxStr();
63 } catch (AttributeNotFoundException
| StateValueTypeException
| StateSystemDisposedException e
) {
68 * Strip the "syscall" prefix part if there is one, it's not useful in the
71 for (String sysPrefix
: SYSCALL_PREFIXES
) {
72 if (syscallName
.startsWith(sysPrefix
)) {
73 syscallName
= syscallName
.substring(sysPrefix
.length());
80 // ------------------------------------------------------------------------
81 // Color mapping, line thickness
82 // ------------------------------------------------------------------------
85 * State definitions used in this provider.
87 private static final List
<StateDefinition
> STATE_DEFINITIONS
= ImmutableList
.of(
88 KernelAnalysisStateDefinitions
.THREAD_STATE_UNKNOWN
,
89 KernelAnalysisStateDefinitions
.THREAD_STATE_WAIT_UNKNOWN
,
90 KernelAnalysisStateDefinitions
.THREAD_STATE_WAIT_BLOCKED
,
91 KernelAnalysisStateDefinitions
.THREAD_STATE_WAIT_FOR_CPU
,
92 KernelAnalysisStateDefinitions
.THREAD_STATE_USERMODE
,
93 KernelAnalysisStateDefinitions
.THREAD_STATE_SYSCALL
,
94 KernelAnalysisStateDefinitions
.THREAD_STATE_INTERRUPTED
);
96 private static final Function
<StateIntervalContext
, StateDefinition
> STATE_DEF_MAPPING_FUNCTION
= ssCtx
-> {
97 ITmfStateValue val
= ssCtx
.sourceInterval
.getStateValue();
98 return stateValueToStateDef(val
);
102 static final StateDefinition
stateValueToStateDef(ITmfStateValue val
) {
104 return KernelAnalysisStateDefinitions
.NO_STATE
;
108 int status
= val
.unboxInt();
110 case StateValues
.PROCESS_STATUS_WAIT_UNKNOWN
:
111 return KernelAnalysisStateDefinitions
.THREAD_STATE_WAIT_UNKNOWN
;
112 case StateValues
.PROCESS_STATUS_WAIT_BLOCKED
:
113 return KernelAnalysisStateDefinitions
.THREAD_STATE_WAIT_BLOCKED
;
114 case StateValues
.PROCESS_STATUS_WAIT_FOR_CPU
:
115 return KernelAnalysisStateDefinitions
.THREAD_STATE_WAIT_FOR_CPU
;
116 case StateValues
.PROCESS_STATUS_RUN_USERMODE
:
117 return KernelAnalysisStateDefinitions
.THREAD_STATE_USERMODE
;
118 case StateValues
.PROCESS_STATUS_RUN_SYSCALL
:
119 return KernelAnalysisStateDefinitions
.THREAD_STATE_SYSCALL
;
120 case StateValues
.PROCESS_STATUS_INTERRUPTED
:
121 return KernelAnalysisStateDefinitions
.THREAD_STATE_INTERRUPTED
;
123 return KernelAnalysisStateDefinitions
.THREAD_STATE_UNKNOWN
;
126 } catch (StateValueTypeException e
) {
127 return KernelAnalysisStateDefinitions
.THREAD_STATE_UNKNOWN
;
131 private static final Function
<StateIntervalContext
, String
> STATE_NAME_MAPPING_FUNCTION
= ssCtx
-> STATE_DEF_MAPPING_FUNCTION
.apply(ssCtx
).getName();
133 private static final Function
<StateIntervalContext
, ConfigOption
<ColorDefinition
>> COLOR_MAPPING_FUNCTION
= ssCtx
-> STATE_DEF_MAPPING_FUNCTION
.apply(ssCtx
).getColor();
135 private static final Function
<StateIntervalContext
, ConfigOption
<LineThickness
>> LINE_THICKNESS_MAPPING_FUNCTION
= ssCtx
-> STATE_DEF_MAPPING_FUNCTION
.apply(ssCtx
).getLineThickness();
137 // ------------------------------------------------------------------------
139 // ------------------------------------------------------------------------
141 private static final Function
<StateIntervalContext
, Map
<String
, String
>> PROPERTIES_MAPPING_FUNCTION
= ssCtx
-> {
142 /* Include properties for CPU and syscall name. */
143 int baseQuark
= ssCtx
.baseTreeElement
.getSourceQuark();
144 long startTime
= ssCtx
.sourceInterval
.getStartTime();
146 // FIXME The Kernel analysis in TraceCompass does not include the CPUs' run
148 String cpu
= requireNonNull(Messages
.propertyNotAvailable
);
150 // int cpuQuark = ssCtx.ss.getQuarkRelative(baseQuark, Attributes.CURRENT_CPU_RQ);
151 // ITmfStateValue sv = ssCtx.fullQueryAtIntervalStart.get(cpuQuark).getStateValue();
152 // cpu = (sv.isNull() ? requireNonNull(Messages.propertyNotAvailable) : String.valueOf(sv.unboxInt()));
153 // } catch (AttributeNotFoundException e) {
154 // cpu = requireNonNull(Messages.propertyNotAvailable);
159 int syscallNameQuark
= ssCtx
.ss
.getQuarkRelative(baseQuark
, Attributes
.SYSTEM_CALL
);
160 ITmfStateValue sv
= ssCtx
.ss
.querySingleState(startTime
, syscallNameQuark
).getStateValue();
161 syscall
= (sv
.isNull() ?
requireNonNull(Messages
.propertyNotAvailable
) : sv
.unboxStr());
162 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
163 syscall
= requireNonNull(Messages
.propertyNotAvailable
);
166 return ImmutableMap
.of(requireNonNull(Messages
.propertyNameCpu
), cpu
,
167 requireNonNull(Messages
.propertyNameSyscall
), syscall
);
173 public ThreadsModelStateProvider() {
174 super(STATE_DEFINITIONS
,
175 KernelAnalysisModule
.ID
,
176 STATE_NAME_MAPPING_FUNCTION
,
177 LABEL_MAPPING_FUNCTION
,
178 COLOR_MAPPING_FUNCTION
,
179 LINE_THICKNESS_MAPPING_FUNCTION
,
180 PROPERTIES_MAPPING_FUNCTION
);