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