1 /*******************************************************************************
2 * Copyright (c) 2014, 2015 École Polytechnique de Montréal
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 * Geneviève Bastien - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.kernelanalysis
;
15 import java
.util
.Collection
;
16 import java
.util
.Collections
;
17 import java
.util
.List
;
19 import java
.util
.TreeSet
;
21 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
22 import org
.eclipse
.jdt
.annotation
.Nullable
;
23 import org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
;
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
.exceptions
.StateSystemDisposedException
;
28 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.TimeRangeException
;
29 import org
.eclipse
.tracecompass
.statesystem
.core
.interval
.ITmfStateInterval
;
30 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
33 * Information provider utility class that retrieves thread-related information
34 * from a Linux Kernel Analysis
36 * @author Geneviève Bastien
38 public final class KernelThreadInformationProvider
{
40 private KernelThreadInformationProvider() {
44 * Get the ID of the thread running on the CPU at time ts
46 * TODO: This method may later be replaced by an aspect, when the aspect can
47 * resolve to something that is not an event
50 * The lttng kernel analysis instance to run this method on
52 * The CPU number the process is running on
54 * The timestamp at which we want the running process
55 * @return The TID of the thread running on CPU cpuId at time ts or
56 * {@code null} if either no thread is running or we do not know.
59 public static @Nullable Integer
getThreadOnCpu(KernelAnalysisModule module
, long cpuId
, long ts
) {
60 ITmfStateSystem ss
= module
.getStateSystem();
65 int cpuQuark
= ss
.getQuarkAbsolute(Attributes
.CPUS
, Long
.toString(cpuId
), Attributes
.CURRENT_THREAD
);
66 ITmfStateInterval interval
= ss
.querySingleState(ts
, cpuQuark
);
67 ITmfStateValue val
= interval
.getStateValue();
68 switch (val
.getType()) {
70 return val
.unboxInt();
78 } catch (AttributeNotFoundException
| StateSystemDisposedException
| TimeRangeException e
) {
84 * Get the TIDs of the threads from an analysis
87 * The lttng kernel analysis instance to run this method on
88 * @return The set of TIDs corresponding to the threads
91 public static Collection
<Integer
> getThreadIds(KernelAnalysisModule module
) {
92 ITmfStateSystem ss
= module
.getStateSystem();
94 return NonNullUtils
.checkNotNull(Collections
.EMPTY_SET
);
98 threadQuark
= ss
.getQuarkAbsolute(Attributes
.THREADS
);
99 Set
<Integer
> tids
= new TreeSet
<>();
100 for (Integer quark
: ss
.getSubAttributes(threadQuark
, false)) {
101 tids
.add(Integer
.parseInt(ss
.getAttributeName(quark
)));
104 } catch (AttributeNotFoundException e
) {
106 return NonNullUtils
.checkNotNull(Collections
.EMPTY_SET
);
110 * Get the parent process ID of a thread
113 * The lttng kernel analysis instance to run this method on
115 * The thread ID of the process for which to get the parent
117 * The timestamp at which to get the parent
118 * @return The parent PID or {@code null} if the PPID is not found.
121 public static @Nullable Integer
getParentPid(KernelAnalysisModule module
, Integer threadId
, long ts
) {
123 ITmfStateSystem ss
= module
.getStateSystem();
129 ppidNode
= ss
.getQuarkAbsolute(Attributes
.THREADS
, threadId
.toString(), Attributes
.PPID
);
130 ITmfStateInterval ppidInterval
= ss
.querySingleState(ts
, ppidNode
);
131 ITmfStateValue ppidValue
= ppidInterval
.getStateValue();
133 switch (ppidValue
.getType()) {
135 ppid
= NonNullUtils
.checkNotNull(Integer
.valueOf(ppidValue
.unboxInt()));
144 } catch (AttributeNotFoundException
| StateSystemDisposedException
| TimeRangeException e
) {
150 * Get the executable name of the thread ID. If the thread ID was used
151 * multiple time or the name changed in between, it will return the last
152 * name the thread has taken, or {@code null} if no name is found
155 * The lttng kernel analysis instance to run this method on
157 * The thread ID of the process for which to get the name
158 * @return The last executable name of this process, or {@code null} if not
162 public static @Nullable String
getExecutableName(KernelAnalysisModule module
, Integer threadId
) {
163 String execName
= null;
164 ITmfStateSystem ss
= module
.getStateSystem();
168 Integer execNameNode
;
170 execNameNode
= ss
.getQuarkAbsolute(Attributes
.THREADS
, threadId
.toString(), Attributes
.EXEC_NAME
);
171 List
<ITmfStateInterval
> execNameIntervals
= StateSystemUtils
.queryHistoryRange(ss
, execNameNode
, ss
.getStartTime(), ss
.getCurrentEndTime());
173 ITmfStateValue execNameValue
;
174 for (ITmfStateInterval interval
: execNameIntervals
) {
175 execNameValue
= interval
.getStateValue();
176 switch (execNameValue
.getType()) {
178 execName
= NonNullUtils
.checkNotNull(execNameValue
.unboxStr());
188 } catch (AttributeNotFoundException
| StateSystemDisposedException
| TimeRangeException e
) {
194 * Get the priority of a thread running at a time ts.
197 * The kernel analysis instance to run this method on
199 * The thread ID of the target thread
201 * The timestamp at which to get the priority
202 * @return The priority of this thread, or {@code null} if not found
205 public static @Nullable Integer
getThreadPrio(KernelAnalysisModule module
, Integer threadId
, long ts
) {
206 Integer execPrio
= null;
207 ITmfStateSystem ss
= module
.getStateSystem();
212 int execPrioQuark
= ss
.getQuarkAbsolute(Attributes
.THREADS
, threadId
.toString(), Attributes
.PRIO
);
213 ITmfStateInterval interval
= ss
.querySingleState(ts
, execPrioQuark
);
214 ITmfStateValue prioValue
= interval
.getStateValue();
215 /* We know the prio must be an Integer */
216 execPrio
= prioValue
.unboxInt();
217 } catch (AttributeNotFoundException
| StateSystemDisposedException
| TimeRangeException e
) {
223 * Get the status intervals for a given thread with a resolution
226 * The lttng kernel analysis instance to run this method on
228 * The ID of the thread to get the intervals for
230 * The start time of the requested range
232 * The end time of the requested range
234 * The resolution or the minimal time between the requested
235 * intervals. If interval times are smaller than resolution, only
236 * the first interval is returned, the others are ignored.
238 * A progress monitor for this task
239 * @return The list of status intervals for this thread, an empty list is
240 * returned if either the state system is {@code null} or the quark
244 public static List
<ITmfStateInterval
> getStatusIntervalsForThread(KernelAnalysisModule module
, Integer threadId
, long start
, long end
, long resolution
, IProgressMonitor monitor
) {
245 ITmfStateSystem ss
= module
.getStateSystem();
247 return NonNullUtils
.checkNotNull(Collections
.EMPTY_LIST
);
251 int threadQuark
= ss
.getQuarkAbsolute(Attributes
.THREADS
, threadId
.toString());
252 int statusQuark
= ss
.getQuarkRelative(threadQuark
, Attributes
.STATUS
);
253 List
<ITmfStateInterval
> statusIntervals
= StateSystemUtils
.queryHistoryRange(ss
, statusQuark
, Math
.max(start
, ss
.getStartTime()), Math
.min(end
- 1, ss
.getCurrentEndTime()), resolution
, monitor
);
254 return statusIntervals
;
255 } catch (AttributeNotFoundException
| StateSystemDisposedException
| TimeRangeException e
) {
257 return NonNullUtils
.checkNotNull(Collections
.EMPTY_LIST
);