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