1 /*******************************************************************************
2 * Copyright (c) 2015 Ericsson
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 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.kernel
.handlers
;
12 import java
.util
.List
;
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
;
28 * Kernel Event Handler Utils is a collection of static methods to be used in
29 * subclasses of IKernelEventHandler.
31 * @author Matthew Khouzam
32 * @author Francis Giraldeau
34 public final class KernelEventHandlerUtils
{
36 private KernelEventHandlerUtils() {
43 * The event containing the cpu
45 * @return the CPU number (null for not set)
47 public static @Nullable Integer
getCpu(ITmfEvent event
) {
48 Integer cpuObj
= TmfTraceUtils
.resolveIntEventAspectOfClassForEvent(event
.getTrace(), TmfCpuAspect
.class, event
);
50 /* We couldn't find any CPU information, ignore this event */
57 * Gets the current CPU quark
64 * @return the current CPU quark -1 for not set
66 public static int getCurrentCPUNode(Integer cpuNumber
, ITmfStateSystemBuilder ss
) {
67 return ss
.getQuarkRelativeAndAdd(getNodeCPUs(ss
), cpuNumber
.toString());
71 * Get the timestamp of the event
74 * the event containing the timestamp
76 * @return the timestamp in long format
78 public static long getTimestamp(ITmfEvent event
) {
79 return event
.getTimestamp().toNanos();
83 * Get the current thread node
90 * @return the current thread node quark
91 * @throws AttributeNotFoundException
92 * current cpu node not found
94 public static int getCurrentThreadNode(Integer cpuNumber
, ITmfStateSystemBuilder ss
) throws AttributeNotFoundException
{
96 * Shortcut for the "current thread" attribute node. It requires
97 * querying the current CPU's current thread.
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
));
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
112 * the time in the state system of the change
113 * @param currentThreadNode
114 * The current thread node
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
124 public static void setProcessToRunning(long timestamp
, int currentThreadNode
, ITmfStateSystemBuilder ssb
)
125 throws AttributeNotFoundException
, TimeRangeException
,
126 StateValueTypeException
{
128 ITmfStateValue value
;
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
;
135 /* We were previously in kernel mode */
136 value
= StateValues
.PROCESS_STATUS_RUN_SYSCALL_VALUE
;
138 quark
= ssb
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.STATUS
);
139 ssb
.modifyAttribute(timestamp
, value
, quark
);
149 * @return the IRQ node quark
151 public static int getNodeIRQs(int cpuNumber
, ITmfStateSystemBuilder ss
) {
152 return ss
.getQuarkAbsoluteAndAdd(Attributes
.CPUS
, Integer
.toString(cpuNumber
), Attributes
.IRQS
);
160 * @return the CPU node quark
162 public static int getNodeCPUs(ITmfStateSystemBuilder ss
) {
163 return ss
.getQuarkAbsoluteAndAdd(Attributes
.CPUS
);
167 * Get the Soft IRQs node
173 * @return the Soft IRQ node quark
175 public static int getNodeSoftIRQs(int cpuNumber
, ITmfStateSystemBuilder ss
) {
176 return ss
.getQuarkAbsoluteAndAdd(Attributes
.CPUS
, Integer
.toString(cpuNumber
), Attributes
.SOFT_IRQS
);
180 * Get the threads node
184 * @return the threads quark
186 public static int getNodeThreads(ITmfStateSystemBuilder ss
) {
187 return ss
.getQuarkAbsoluteAndAdd(Attributes
.THREADS
);
191 * Reset the CPU's status when it's coming out of an interruption.
194 * the time when the status of the cpu is "leaving irq"
196 * the cpu returning to its previous state
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
207 public static void cpuExitInterrupt(long timestamp
, Integer cpuNumber
, ITmfStateSystemBuilder ssb
)
208 throws StateValueTypeException
, AttributeNotFoundException
,
211 int currentCPUNode
= getCurrentCPUNode(cpuNumber
, ssb
);
213 quark
= ssb
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.STATUS
);
214 ITmfStateValue value
= getCpuStatus(ssb
, currentCPUNode
);
215 ssb
.modifyAttribute(timestamp
, value
, quark
);
219 * Get the ongoing Status state of a CPU.
221 * This will look through the states of the
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.
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
240 private static ITmfStateValue
getCpuStatus(ITmfStateSystemBuilder ssb
, int cpuQuark
)
241 throws AttributeNotFoundException
{
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()) {
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()) {
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).
267 int currentThreadQuark
= ssb
.getQuarkRelativeAndAdd(cpuQuark
, Attributes
.CURRENT_THREAD
);
268 ITmfStateValue currentThreadState
= ssb
.queryOngoingState(currentThreadQuark
);
269 if (currentThreadState
.isNull()) {
270 return TmfStateValue
.nullValue();
272 int tid
= currentThreadState
.unboxInt();
274 return StateValues
.CPU_STATUS_IDLE_VALUE
;
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
);