tmf.core: move AbstractTmfStateProvider to new BufferedBlockingQueue
[deliverable/tracecompass.git] / org.eclipse.tracecompass.analysis.os.linux.core / src / org / eclipse / tracecompass / analysis / os / linux / core / kernelanalysis / KernelThreadInformationProvider.java
CommitLineData
50a47aa6 1/*******************************************************************************
ed902a2b 2 * Copyright (c) 2014, 2015 École Polytechnique de Montréal
50a47aa6
GB
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
e363eae1 13package org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis;
50a47aa6
GB
14
15import java.util.Collection;
16import java.util.Collections;
17import java.util.List;
18import java.util.Set;
19import java.util.TreeSet;
20
21import org.eclipse.core.runtime.IProgressMonitor;
50a47aa6
GB
22import org.eclipse.jdt.annotation.Nullable;
23import org.eclipse.tracecompass.common.core.NonNullUtils;
50a47aa6
GB
24import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
25import org.eclipse.tracecompass.statesystem.core.StateSystemUtils;
26import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
27import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
28import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
29import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
30import 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 */
e363eae1 38public final class KernelThreadInformationProvider {
50a47aa6 39
e363eae1 40 private KernelThreadInformationProvider() {
50a47aa6
GB
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 */
e363eae1 58 public static @Nullable Integer getThreadOnCpu(KernelAnalysis module, long cpuId, long ts) {
50a47aa6
GB
59 ITmfStateSystem ss = module.getStateSystem();
60 if (ss == null) {
61 return null;
62 }
63 try {
64 int cpuQuark = ss.getQuarkAbsolute(Attributes.CPUS, Long.toString(cpuId), Attributes.CURRENT_THREAD);
65 ITmfStateInterval interval = ss.querySingleState(ts, cpuQuark);
66 ITmfStateValue val = interval.getStateValue();
67 switch (val.getType()) {
68 case INTEGER:
69 return val.unboxInt();
70 case LONG:
71 case DOUBLE:
72 case NULL:
73 case STRING:
74 default:
75 break;
76 }
77 } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
78 }
79 return null;
80 }
81
82 /**
83 * Get the TIDs of the threads from an analysis
84 *
85 * @param module
86 * The lttng kernel analysis instance to run this method on
87 * @return The set of TIDs corresponding to the threads
88 */
e363eae1 89 public static Collection<Integer> getThreadIds(KernelAnalysis module) {
50a47aa6
GB
90 ITmfStateSystem ss = module.getStateSystem();
91 if (ss == null) {
92 return NonNullUtils.checkNotNull(Collections.EMPTY_SET);
93 }
94 int threadQuark;
95 try {
96 threadQuark = ss.getQuarkAbsolute(Attributes.THREADS);
97 Set<Integer> tids = new TreeSet<>();
98 for (Integer quark : ss.getSubAttributes(threadQuark, false)) {
99 tids.add(Integer.parseInt(ss.getAttributeName(quark)));
100 }
101 return tids;
102 } catch (AttributeNotFoundException e) {
103 }
104 return NonNullUtils.checkNotNull(Collections.EMPTY_SET);
105 }
106
107 /**
108 * Get the parent process ID of a thread
109 *
110 * @param module
111 * The lttng kernel analysis instance to run this method on
112 * @param threadId
113 * The thread ID of the process for which to get the parent
114 * @param ts
115 * The timestamp at which to get the parent
116 * @return The parent PID or {@code null} if the PPID is not found.
117 */
e363eae1 118 public static @Nullable Integer getParentPid(KernelAnalysis module, Integer threadId, long ts) {
50a47aa6
GB
119 Integer ppid = null;
120 ITmfStateSystem ss = module.getStateSystem();
121 if (ss == null) {
122 return ppid;
123 }
124 Integer ppidNode;
125 try {
126 ppidNode = ss.getQuarkAbsolute(Attributes.THREADS, threadId.toString(), Attributes.PPID);
127 ITmfStateInterval ppidInterval = ss.querySingleState(ts, ppidNode);
128 ITmfStateValue ppidValue = ppidInterval.getStateValue();
129
130 switch (ppidValue.getType()) {
131 case INTEGER:
132 ppid = NonNullUtils.checkNotNull(Integer.valueOf(ppidValue.unboxInt()));
133 break;
134 case DOUBLE:
135 case LONG:
136 case NULL:
137 case STRING:
138 default:
139 break;
140 }
141 } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
142 }
143 return ppid;
144 }
145
146 /**
147 * Get the executable name of the thread ID. If the thread ID was used
148 * multiple time or the name changed in between, it will return the last
149 * name the thread has taken, or {@code null} if no name is found
150 *
151 * @param module
152 * The lttng kernel analysis instance to run this method on
153 * @param threadId
154 * The thread ID of the process for which to get the name
155 * @return The last executable name of this process, or {@code null} if not
156 * found
157 */
e363eae1 158 public static @Nullable String getExecutableName(KernelAnalysis module, Integer threadId) {
50a47aa6
GB
159 String execName = null;
160 ITmfStateSystem ss = module.getStateSystem();
161 if (ss == null) {
162 return execName;
163 }
164 Integer execNameNode;
165 try {
166 execNameNode = ss.getQuarkAbsolute(Attributes.THREADS, threadId.toString(), Attributes.EXEC_NAME);
167 List<ITmfStateInterval> execNameIntervals = StateSystemUtils.queryHistoryRange(ss, execNameNode, ss.getStartTime(), ss.getCurrentEndTime());
168
169 ITmfStateValue execNameValue;
170 for (ITmfStateInterval interval : execNameIntervals) {
171 execNameValue = interval.getStateValue();
172 switch (execNameValue.getType()) {
173 case STRING:
174 execName = NonNullUtils.checkNotNull(execNameValue.unboxStr());
175 break;
176 case DOUBLE:
177 case LONG:
178 case NULL:
179 case INTEGER:
180 default:
181 break;
182 }
183 }
184 } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
185 }
186 return execName;
187 }
188
3bf563da
CM
189 /**
190 * Get the priority of a thread running at a time ts.
191 *
192 * @param module
193 * The kernel analysis instance to run this method on
194 * @param threadId
195 * The thread ID of the target thread
196 * @param ts
197 * The timestamp at which to get the priority
198 * @return The priority of this thread, or {@code null} if not found
dbc7991d 199 * @since 1.0
3bf563da
CM
200 */
201 public static @Nullable Integer getThreadPrio(KernelAnalysis module, Integer threadId, long ts) {
202 Integer execPrio = null;
203 ITmfStateSystem ss = module.getStateSystem();
204 if (ss == null) {
205 return execPrio;
206 }
207 try {
208 int execPrioQuark = ss.getQuarkAbsolute(Attributes.THREADS, threadId.toString(), Attributes.PRIO);
209 ITmfStateInterval interval = ss.querySingleState(ts, execPrioQuark);
210 ITmfStateValue prioValue = interval.getStateValue();
211 /* We know the prio must be an Integer */
212 execPrio = prioValue.unboxInt();
213 } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
214 }
215 return execPrio;
216 }
217
50a47aa6
GB
218 /**
219 * Get the status intervals for a given thread with a resolution
220 *
221 * @param module
222 * The lttng kernel analysis instance to run this method on
223 * @param threadId
224 * The ID of the thread to get the intervals for
225 * @param start
226 * The start time of the requested range
227 * @param end
228 * The end time of the requested range
229 * @param resolution
230 * The resolution or the minimal time between the requested
231 * intervals. If interval times are smaller than resolution, only
232 * the first interval is returned, the others are ignored.
233 * @param monitor
234 * A progress monitor for this task
235 * @return The list of status intervals for this thread, an empty list is
236 * returned if either the state system is {@code null} or the quark
237 * is not found
238 */
e363eae1 239 public static List<ITmfStateInterval> getStatusIntervalsForThread(KernelAnalysis module, Integer threadId, long start, long end, long resolution, IProgressMonitor monitor) {
50a47aa6
GB
240 ITmfStateSystem ss = module.getStateSystem();
241 if (ss == null) {
242 return NonNullUtils.checkNotNull(Collections.EMPTY_LIST);
243 }
244
245 try {
246 int threadQuark = ss.getQuarkAbsolute(Attributes.THREADS, threadId.toString());
247 int statusQuark = ss.getQuarkRelative(threadQuark, Attributes.STATUS);
248 List<ITmfStateInterval> statusIntervals = StateSystemUtils.queryHistoryRange(ss, statusQuark, Math.max(start, ss.getStartTime()), Math.min(end - 1, ss.getCurrentEndTime()), resolution, monitor);
249 return statusIntervals;
250 } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
251 }
252 return NonNullUtils.checkNotNull(Collections.EMPTY_LIST);
253 }
254
255}
This page took 0.043431 seconds and 5 git commands to generate.