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 / handlers / internal / KernelEventHandlerUtils.java
1 /*******************************************************************************
2 * Copyright (c) 2015 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
9
10 package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
11
12 import java.util.List;
13
14 import org.eclipse.jdt.annotation.Nullable;
15 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
16 import org.eclipse.tracecompass.tmf.core.event.aspect.TmfCpuAspect;
17 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
18 import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
19 import org.lttng.scope.lttng.kernel.core.analysis.os.StateValues;
20
21 import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
22 import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
23 import ca.polymtl.dorsal.libdelorean.exceptions.StateValueTypeException;
24 import ca.polymtl.dorsal.libdelorean.exceptions.TimeRangeException;
25 import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
26 import ca.polymtl.dorsal.libdelorean.statevalue.TmfStateValue;
27
28 /**
29 * Kernel Event Handler Utils is a collection of static methods to be used in
30 * subclasses of IKernelEventHandler.
31 *
32 * @author Matthew Khouzam
33 * @author Francis Giraldeau
34 */
35 public final class KernelEventHandlerUtils {
36
37 private KernelEventHandlerUtils() {
38 }
39
40 /**
41 * Get CPU
42 *
43 * @param event
44 * The event containing the cpu
45 *
46 * @return the CPU number (null for not set)
47 */
48 public static @Nullable Integer getCpu(ITmfEvent event) {
49 Integer cpuObj = TmfTraceUtils.resolveIntEventAspectOfClassForEvent(event.getTrace(), TmfCpuAspect.class, event);
50 if (cpuObj == null) {
51 /* We couldn't find any CPU information, ignore this event */
52 return null;
53 }
54 return cpuObj;
55 }
56
57 /**
58 * Gets the current CPU quark
59 *
60 * @param cpuNumber
61 * The cpu number
62 * @param ss
63 * the state system
64 *
65 * @return the current CPU quark -1 for not set
66 */
67 public static int getCurrentCPUNode(Integer cpuNumber, ITmfStateSystemBuilder ss) {
68 return ss.getQuarkRelativeAndAdd(getNodeCPUs(ss), cpuNumber.toString());
69 }
70
71 /**
72 * Get the timestamp of the event
73 *
74 * @param event
75 * the event containing the timestamp
76 *
77 * @return the timestamp in long format
78 */
79 public static long getTimestamp(ITmfEvent event) {
80 return event.getTimestamp().toNanos();
81 }
82
83 /**
84 * Get the current thread node
85 *
86 * @param cpuNumber
87 * The cpu number
88 * @param ss
89 * the state system
90 *
91 * @return the current thread node quark
92 */
93 public static int getCurrentThreadNode(Integer cpuNumber, ITmfStateSystemBuilder ss) {
94 /*
95 * Shortcut for the "current thread" attribute node. It requires
96 * querying the current CPU's current thread.
97 */
98 int quark = ss.getQuarkRelativeAndAdd(getCurrentCPUNode(cpuNumber, ss), Attributes.CURRENT_THREAD);
99 ITmfStateValue value = ss.queryOngoingState(quark);
100 int thread = value.isNull() ? -1 : value.unboxInt();
101 return ss.getQuarkRelativeAndAdd(getNodeThreads(ss), Attributes.buildThreadAttributeName(thread, cpuNumber));
102 }
103
104 /**
105 * When we want to set a process back to a "running" state, first check its
106 * current System_call attribute. If there is a system call active, we put
107 * the process back in the syscall state. If not, we put it back in user
108 * mode state.
109 *
110 * @param timestamp
111 * the time in the state system of the change
112 * @param currentThreadNode
113 * The current thread node
114 * @param ssb
115 * the state system
116 * @throws TimeRangeException
117 * the time is out of range
118 * @throws StateValueTypeException
119 * the attribute was not set with int values
120 * @throws AttributeNotFoundException
121 * If the attribute is invalid
122 */
123 public static void setProcessToRunning(long timestamp, int currentThreadNode, ITmfStateSystemBuilder ssb)
124 throws TimeRangeException, StateValueTypeException, AttributeNotFoundException {
125 int quark;
126 ITmfStateValue value;
127
128 quark = ssb.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
129 if (ssb.queryOngoingState(quark).isNull()) {
130 /* We were in user mode before the interruption */
131 value = StateValues.PROCESS_STATUS_RUN_USERMODE_VALUE;
132 } else {
133 /* We were previously in kernel mode */
134 value = StateValues.PROCESS_STATUS_RUN_SYSCALL_VALUE;
135 }
136 ssb.modifyAttribute(timestamp, value, currentThreadNode);
137 }
138
139 /**
140 * Get the IRQs node
141 *
142 * @param cpuNumber
143 * the cpu core
144 * @param ss
145 * the state system
146 * @return the IRQ node quark
147 */
148 public static int getNodeIRQs(int cpuNumber, ITmfStateSystemBuilder ss) {
149 return ss.getQuarkAbsoluteAndAdd(Attributes.CPUS, Integer.toString(cpuNumber), Attributes.IRQS);
150 }
151
152 /**
153 * Get the CPUs node
154 *
155 * @param ss
156 * the state system
157 * @return the CPU node quark
158 */
159 public static int getNodeCPUs(ITmfStateSystemBuilder ss) {
160 return ss.getQuarkAbsoluteAndAdd(Attributes.CPUS);
161 }
162
163 /**
164 * Get the Soft IRQs node
165 *
166 * @param cpuNumber
167 * the cpu core
168 * @param ss
169 * the state system
170 * @return the Soft IRQ node quark
171 */
172 public static int getNodeSoftIRQs(int cpuNumber, ITmfStateSystemBuilder ss) {
173 return ss.getQuarkAbsoluteAndAdd(Attributes.CPUS, Integer.toString(cpuNumber), Attributes.SOFT_IRQS);
174 }
175
176 /**
177 * Get the threads node
178 *
179 * @param ss
180 * the state system
181 * @return the threads quark
182 */
183 public static int getNodeThreads(ITmfStateSystemBuilder ss) {
184 return ss.getQuarkAbsoluteAndAdd(Attributes.THREADS);
185 }
186
187 /**
188 * Reset the CPU's status when it's coming out of an interruption.
189 *
190 * @param timestamp
191 * the time when the status of the cpu is "leaving irq"
192 * @param cpuNumber
193 * the cpu returning to its previous state
194 *
195 * @param ssb
196 * State system
197 * @throws StateValueTypeException
198 * the attribute is not set as an int
199 * @throws TimeRangeException
200 * the time is out of range
201 * @throws AttributeNotFoundException
202 * If the attribute is invalid
203 */
204 public static void cpuExitInterrupt(long timestamp, Integer cpuNumber, ITmfStateSystemBuilder ssb)
205 throws StateValueTypeException, TimeRangeException, AttributeNotFoundException {
206 int currentCPUNode = getCurrentCPUNode(cpuNumber, ssb);
207
208 ITmfStateValue value = getCpuStatus(ssb, currentCPUNode);
209 ssb.modifyAttribute(timestamp, value, currentCPUNode);
210 }
211
212 /**
213 * Get the ongoing Status state of a CPU.
214 *
215 * This will look through the states of the
216 *
217 * <ul>
218 * <li>IRQ</li>
219 * <li>Soft IRQ</li>
220 * <li>Process</li>
221 * </ul>
222 *
223 * under the CPU, giving priority to states higher in the list. If the state
224 * is a null value, we continue looking down the list.
225 *
226 * @param ssb
227 * The state system
228 * @param cpuQuark
229 * The *quark* of the CPU we are looking for. Careful, this is
230 * NOT the CPU number (or attribute name)!
231 * @return The state value that represents the status of the given CPU
232 * @throws AttributeNotFoundException
233 */
234 private static ITmfStateValue getCpuStatus(ITmfStateSystemBuilder ssb, int cpuQuark)
235 throws AttributeNotFoundException {
236
237 /* Check if there is a IRQ running */
238 int irqQuarks = ssb.getQuarkRelativeAndAdd(cpuQuark, Attributes.IRQS);
239 List<Integer> irqs = ssb.getSubAttributes(irqQuarks, false);
240 for (Integer quark : irqs) {
241 final ITmfStateValue irqState = ssb.queryOngoingState(quark.intValue());
242 if (!irqState.isNull()) {
243 return irqState;
244 }
245 }
246
247 /* Check if there is a soft IRQ running */
248 int softIrqQuarks = ssb.getQuarkRelativeAndAdd(cpuQuark, Attributes.SOFT_IRQS);
249 List<Integer> softIrqs = ssb.getSubAttributes(softIrqQuarks, false);
250 for (Integer quark : softIrqs) {
251 final ITmfStateValue softIrqState = ssb.queryOngoingState(quark.intValue());
252 if (!softIrqState.isNull()) {
253 return softIrqState;
254 }
255 }
256
257 /*
258 * Check if there is a thread running. If not, report IDLE. If there is,
259 * report the running state of the thread (usermode or system call).
260 */
261 int currentThreadQuark = ssb.getQuarkRelativeAndAdd(cpuQuark, Attributes.CURRENT_THREAD);
262 ITmfStateValue currentThreadState = ssb.queryOngoingState(currentThreadQuark);
263 if (currentThreadState.isNull()) {
264 return TmfStateValue.nullValue();
265 }
266 int tid = currentThreadState.unboxInt();
267 if (tid == 0) {
268 return StateValues.CPU_STATUS_IDLE_VALUE;
269 }
270 int threadSystemCallQuark = ssb.getQuarkAbsoluteAndAdd(Attributes.THREADS, Integer.toString(tid), Attributes.SYSTEM_CALL);
271 return (ssb.queryOngoingState(threadSystemCallQuark).isNull() ? StateValues.CPU_STATUS_RUN_USERMODE_VALUE : StateValues.CPU_STATUS_RUN_SYSCALL_VALUE);
272 }
273 }
This page took 0.039234 seconds and 5 git commands to generate.