ab9692608f7c4b25051104d3a7875df109f926d1
[deliverable/tracecompass.git] / org.eclipse.tracecompass.analysis.os.linux.core / src / org / eclipse / tracecompass / analysis / os / linux / core / kernelanalysis / 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.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis;
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.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;
31
32 /**
33 * Information provider utility class that retrieves thread-related information
34 * from a Linux Kernel Analysis
35 *
36 * @author Geneviève Bastien
37 */
38 public final class KernelThreadInformationProvider {
39
40 private KernelThreadInformationProvider() {
41 }
42
43 /**
44 * Get the ID of the thread running on the CPU at time ts
45 *
46 * TODO: This method may later be replaced by an aspect, when the aspect can
47 * resolve to something that is not an event
48 *
49 * @param module
50 * The lttng kernel analysis instance to run this method on
51 * @param cpuId
52 * The CPU number the process is running on
53 * @param ts
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.
57 * @since 1.0
58 */
59 public static @Nullable Integer getThreadOnCpu(KernelAnalysisModule module, long cpuId, long ts) {
60 ITmfStateSystem ss = module.getStateSystem();
61 if (ss == null) {
62 return null;
63 }
64 try {
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()) {
69 case INTEGER:
70 return val.unboxInt();
71 case LONG:
72 case DOUBLE:
73 case NULL:
74 case STRING:
75 default:
76 break;
77 }
78 } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
79 }
80 return null;
81 }
82
83 /**
84 * Get the TIDs of the threads from an analysis
85 *
86 * @param module
87 * The lttng kernel analysis instance to run this method on
88 * @return The set of TIDs corresponding to the threads
89 * @since 1.0
90 */
91 public static Collection<Integer> getThreadIds(KernelAnalysisModule module) {
92 ITmfStateSystem ss = module.getStateSystem();
93 if (ss == null) {
94 return NonNullUtils.checkNotNull(Collections.EMPTY_SET);
95 }
96 int threadQuark;
97 try {
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)));
102 }
103 return tids;
104 } catch (AttributeNotFoundException e) {
105 }
106 return NonNullUtils.checkNotNull(Collections.EMPTY_SET);
107 }
108
109 /**
110 * Get the parent process ID of a thread
111 *
112 * @param module
113 * The lttng kernel analysis instance to run this method on
114 * @param threadId
115 * The thread ID of the process for which to get the parent
116 * @param ts
117 * The timestamp at which to get the parent
118 * @return The parent PID or {@code null} if the PPID is not found.
119 * @since 1.0
120 */
121 public static @Nullable Integer getParentPid(KernelAnalysisModule module, Integer threadId, long ts) {
122 Integer ppid = null;
123 ITmfStateSystem ss = module.getStateSystem();
124 if (ss == null) {
125 return ppid;
126 }
127 Integer ppidNode;
128 try {
129 ppidNode = ss.getQuarkAbsolute(Attributes.THREADS, threadId.toString(), Attributes.PPID);
130 ITmfStateInterval ppidInterval = ss.querySingleState(ts, ppidNode);
131 ITmfStateValue ppidValue = ppidInterval.getStateValue();
132
133 switch (ppidValue.getType()) {
134 case INTEGER:
135 ppid = NonNullUtils.checkNotNull(Integer.valueOf(ppidValue.unboxInt()));
136 break;
137 case DOUBLE:
138 case LONG:
139 case NULL:
140 case STRING:
141 default:
142 break;
143 }
144 } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
145 }
146 return ppid;
147 }
148
149 /**
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
153 *
154 * @param module
155 * The lttng kernel analysis instance to run this method on
156 * @param threadId
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
159 * found
160 * @since 1.0
161 */
162 public static @Nullable String getExecutableName(KernelAnalysisModule module, Integer threadId) {
163 String execName = null;
164 ITmfStateSystem ss = module.getStateSystem();
165 if (ss == null) {
166 return execName;
167 }
168 Integer execNameNode;
169 try {
170 execNameNode = ss.getQuarkAbsolute(Attributes.THREADS, threadId.toString(), Attributes.EXEC_NAME);
171 List<ITmfStateInterval> execNameIntervals = StateSystemUtils.queryHistoryRange(ss, execNameNode, ss.getStartTime(), ss.getCurrentEndTime());
172
173 ITmfStateValue execNameValue;
174 for (ITmfStateInterval interval : execNameIntervals) {
175 execNameValue = interval.getStateValue();
176 switch (execNameValue.getType()) {
177 case STRING:
178 execName = NonNullUtils.checkNotNull(execNameValue.unboxStr());
179 break;
180 case DOUBLE:
181 case LONG:
182 case NULL:
183 case INTEGER:
184 default:
185 break;
186 }
187 }
188 } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
189 }
190 return execName;
191 }
192
193 /**
194 * Get the priority of a thread running at a time ts.
195 *
196 * @param module
197 * The kernel analysis instance to run this method on
198 * @param threadId
199 * The thread ID of the target thread
200 * @param ts
201 * The timestamp at which to get the priority
202 * @return The priority of this thread, or {@code null} if not found
203 * @since 1.0
204 */
205 public static @Nullable Integer getThreadPrio(KernelAnalysisModule module, Integer threadId, long ts) {
206 Integer execPrio = null;
207 ITmfStateSystem ss = module.getStateSystem();
208 if (ss == null) {
209 return execPrio;
210 }
211 try {
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) {
218 }
219 return execPrio;
220 }
221
222 /**
223 * Get the status intervals for a given thread with a resolution
224 *
225 * @param module
226 * The lttng kernel analysis instance to run this method on
227 * @param threadId
228 * The ID of the thread to get the intervals for
229 * @param start
230 * The start time of the requested range
231 * @param end
232 * The end time of the requested range
233 * @param resolution
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.
237 * @param monitor
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
241 * is not found
242 * @since 1.0
243 */
244 public static List<ITmfStateInterval> getStatusIntervalsForThread(KernelAnalysisModule module, Integer threadId, long start, long end, long resolution, IProgressMonitor monitor) {
245 ITmfStateSystem ss = module.getStateSystem();
246 if (ss == null) {
247 return NonNullUtils.checkNotNull(Collections.EMPTY_LIST);
248 }
249
250 try {
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) {
256 }
257 return NonNullUtils.checkNotNull(Collections.EMPTY_LIST);
258 }
259
260 }
This page took 0.039417 seconds and 4 git commands to generate.