Import lttng.kernel.core plugins from Scope
[deliverable/tracecompass.git] / lttng / org.lttng.scope.lttng.kernel.core / src / org / lttng / scope / lttng / kernel / core / analysis / os / KernelThreadInformationProvider.java
1 /*******************************************************************************
2 * Copyright (c) 2014, 2015 École Polytechnique de Montréal
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 * Contributors:
10 * Geneviève Bastien - Initial API and implementation
11 *******************************************************************************/
12
13 package org.lttng.scope.lttng.kernel.core.analysis.os;
14
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.List;
18 import java.util.Set;
19 import java.util.TreeSet;
20
21 import org.eclipse.core.runtime.IProgressMonitor;
22 import org.eclipse.jdt.annotation.NonNull;
23 import org.eclipse.jdt.annotation.Nullable;
24
25 import ca.polymtl.dorsal.libdelorean.ITmfStateSystem;
26 import ca.polymtl.dorsal.libdelorean.StateSystemUtils;
27 import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
28 import ca.polymtl.dorsal.libdelorean.exceptions.StateSystemDisposedException;
29 import ca.polymtl.dorsal.libdelorean.exceptions.TimeRangeException;
30 import ca.polymtl.dorsal.libdelorean.interval.ITmfStateInterval;
31 import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
32 import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue.Type;
33
34 /**
35 * Information provider utility class that retrieves thread-related information
36 * from a Linux Kernel Analysis
37 *
38 * @author Geneviève Bastien
39 */
40 public final class KernelThreadInformationProvider {
41
42 private KernelThreadInformationProvider() {
43 }
44
45 /**
46 * Get the ID of the thread running on the CPU at time ts
47 *
48 * TODO: This method may later be replaced by an aspect, when the aspect can
49 * resolve to something that is not an event
50 *
51 * @param module
52 * The kernel analysis instance to run this method on
53 * @param cpuId
54 * The CPU number the process is running on
55 * @param ts
56 * The timestamp at which we want the running process
57 * @return The TID of the thread running on CPU cpuId at time ts or
58 * {@code null} if either no thread is running or we do not know.
59 */
60 public static @Nullable Integer getThreadOnCpu(KernelAnalysisModule module, long cpuId, long ts) {
61 ITmfStateSystem ss = module.getStateSystem();
62 if (ss == null) {
63 return null;
64 }
65 try {
66 int cpuQuark = ss.getQuarkAbsolute(Attributes.CPUS, Long.toString(cpuId), Attributes.CURRENT_THREAD);
67 ITmfStateInterval interval = ss.querySingleState(ts, cpuQuark);
68 ITmfStateValue val = interval.getStateValue();
69 if (val.getType().equals(Type.INTEGER)) {
70 return val.unboxInt();
71 }
72 } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
73 }
74 return null;
75 }
76
77 /**
78 * Get the TIDs of the threads from an analysis
79 *
80 * @param module
81 * The kernel analysis instance to run this method on
82 * @return The set of TIDs corresponding to the threads
83 */
84 public static Collection<Integer> getThreadIds(KernelAnalysisModule module) {
85 ITmfStateSystem ss = module.getStateSystem();
86 if (ss == null) {
87 return Collections.EMPTY_SET;
88 }
89 int threadQuark;
90 try {
91 threadQuark = ss.getQuarkAbsolute(Attributes.THREADS);
92 Set<@NonNull Integer> tids = new TreeSet<>();
93 for (Integer quark : ss.getSubAttributes(threadQuark, false)) {
94 final @NonNull String attributeName = ss.getAttributeName(quark);
95 tids.add(attributeName.startsWith(Attributes.THREAD_0_PREFIX) ? 0 : Integer.parseInt(attributeName));
96 }
97 return tids;
98 } catch (AttributeNotFoundException e) {
99 }
100 return Collections.EMPTY_SET;
101 }
102
103 /**
104 * Get the parent process ID of a thread
105 *
106 * @param module
107 * The kernel analysis instance to run this method on
108 * @param threadId
109 * The thread ID of the process for which to get the parent
110 * @param ts
111 * The timestamp at which to get the parent
112 * @return The parent PID or {@code null} if the PPID is not found.
113 */
114 public static @Nullable Integer getParentPid(KernelAnalysisModule module, Integer threadId, long ts) {
115 ITmfStateSystem ss = module.getStateSystem();
116 if (ss == null) {
117 return null;
118 }
119 Integer ppidNode;
120 try {
121 ppidNode = ss.getQuarkAbsolute(Attributes.THREADS, threadId.toString(), Attributes.PPID);
122 ITmfStateInterval ppidInterval = ss.querySingleState(ts, ppidNode);
123 ITmfStateValue ppidValue = ppidInterval.getStateValue();
124
125 if (ppidValue.getType().equals(Type.INTEGER)) {
126 return Integer.valueOf(ppidValue.unboxInt());
127 }
128 } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
129 }
130 return null;
131 }
132
133 /**
134 * Get the executable name of the thread ID. If the thread ID was used
135 * multiple time or the name changed in between, it will return the last
136 * name the thread has taken, or {@code null} if no name is found
137 *
138 * @param module
139 * The kernel analysis instance to run this method on
140 * @param threadId
141 * The thread ID of the process for which to get the name
142 * @return The last executable name of this process, or {@code null} if not
143 * found
144 */
145 public static @Nullable String getExecutableName(KernelAnalysisModule module, Integer threadId) {
146 ITmfStateSystem ss = module.getStateSystem();
147 if (ss == null) {
148 return null;
149 }
150 try {
151 Integer execNameNode = ss.getQuarkAbsolute(Attributes.THREADS, threadId.toString(), Attributes.EXEC_NAME);
152 List<ITmfStateInterval> execNameIntervals = StateSystemUtils.queryHistoryRange(ss, execNameNode, ss.getStartTime(), ss.getCurrentEndTime());
153
154 ITmfStateValue execNameValue;
155 String execName = null;
156 for (ITmfStateInterval interval : execNameIntervals) {
157 execNameValue = interval.getStateValue();
158 if (execNameValue.getType().equals(Type.STRING)) {
159 execName = execNameValue.unboxStr();
160 }
161 }
162 return execName;
163 } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
164 }
165 return null;
166 }
167
168 /**
169 * Get the priority of this thread at time ts
170 *
171 * @param module
172 * The kernel analysis instance to run this method on
173 * @param threadId
174 * The ID of the thread to query
175 * @param ts
176 * The timestamp at which to query
177 * @return The priority of the thread or <code>-1</code> if not available
178 */
179 public static int getThreadPriority(KernelAnalysisModule module, int threadId, long ts) {
180 ITmfStateSystem ss = module.getStateSystem();
181 if (ss == null) {
182 return -1;
183 }
184 try {
185 int prioQuark = ss.getQuarkAbsolute(Attributes.THREADS, String.valueOf(threadId), Attributes.PRIO);
186 return ss.querySingleState(ts, prioQuark).getStateValue().unboxInt();
187 } catch (AttributeNotFoundException | StateSystemDisposedException e) {
188 return -1;
189 }
190 }
191 /**
192 * Get the status intervals for a given thread with a resolution
193 *
194 * @param module
195 * The kernel analysis instance to run this method on
196 * @param threadId
197 * The ID of the thread to get the intervals for
198 * @param start
199 * The start time of the requested range
200 * @param end
201 * The end time of the requested range
202 * @param resolution
203 * The resolution or the minimal time between the requested
204 * intervals. If interval times are smaller than resolution, only
205 * the first interval is returned, the others are ignored.
206 * @param monitor
207 * A progress monitor for this task
208 * @return The list of status intervals for this thread, an empty list is
209 * returned if either the state system is {@code null} or the quark
210 * is not found
211 */
212 public static List<ITmfStateInterval> getStatusIntervalsForThread(KernelAnalysisModule module, Integer threadId, long start, long end, long resolution, IProgressMonitor monitor) {
213 ITmfStateSystem ss = module.getStateSystem();
214 if (ss == null) {
215 return Collections.EMPTY_LIST;
216 }
217
218 try {
219 int threadQuark = ss.getQuarkAbsolute(Attributes.THREADS, threadId.toString());
220 List<ITmfStateInterval> statusIntervals = StateSystemUtils.queryHistoryRange(ss, threadQuark,
221 Math.max(start, ss.getStartTime()), Math.min(end - 1, ss.getCurrentEndTime()), resolution, null);
222 return statusIntervals;
223 } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
224 }
225 return Collections.EMPTY_LIST;
226 }
227
228 }
This page took 0.034486 seconds and 5 git commands to generate.