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
.lttng
.scope
.lttng
.kernel
.core
.analysis
.os
.handlers
.internal
;
12 import java
.util
.List
;
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
;
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
;
29 * Kernel Event Handler Utils is a collection of static methods to be used in
30 * subclasses of IKernelEventHandler.
32 * @author Matthew Khouzam
33 * @author Francis Giraldeau
35 public final class KernelEventHandlerUtils
{
37 private KernelEventHandlerUtils() {
44 * The event containing the cpu
46 * @return the CPU number (null for not set)
48 public static @Nullable Integer
getCpu(ITmfEvent event
) {
49 Integer cpuObj
= TmfTraceUtils
.resolveIntEventAspectOfClassForEvent(event
.getTrace(), TmfCpuAspect
.class, event
);
51 /* We couldn't find any CPU information, ignore this event */
58 * Gets the current CPU quark
65 * @return the current CPU quark -1 for not set
67 public static int getCurrentCPUNode(Integer cpuNumber
, ITmfStateSystemBuilder ss
) {
68 return ss
.getQuarkRelativeAndAdd(getNodeCPUs(ss
), cpuNumber
.toString());
72 * Get the timestamp of the event
75 * the event containing the timestamp
77 * @return the timestamp in long format
79 public static long getTimestamp(ITmfEvent event
) {
80 return event
.getTimestamp().toNanos();
84 * Get the current thread node
91 * @return the current thread node quark
93 public static int getCurrentThreadNode(Integer cpuNumber
, ITmfStateSystemBuilder ss
) {
95 * Shortcut for the "current thread" attribute node. It requires
96 * querying the current CPU's current thread.
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
));
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
111 * the time in the state system of the change
112 * @param currentThreadNode
113 * The current thread node
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
123 public static void setProcessToRunning(long timestamp
, int currentThreadNode
, ITmfStateSystemBuilder ssb
)
124 throws TimeRangeException
, StateValueTypeException
, AttributeNotFoundException
{
126 ITmfStateValue value
;
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
;
133 /* We were previously in kernel mode */
134 value
= StateValues
.PROCESS_STATUS_RUN_SYSCALL_VALUE
;
136 ssb
.modifyAttribute(timestamp
, value
, currentThreadNode
);
146 * @return the IRQ node quark
148 public static int getNodeIRQs(int cpuNumber
, ITmfStateSystemBuilder ss
) {
149 return ss
.getQuarkAbsoluteAndAdd(Attributes
.CPUS
, Integer
.toString(cpuNumber
), Attributes
.IRQS
);
157 * @return the CPU node quark
159 public static int getNodeCPUs(ITmfStateSystemBuilder ss
) {
160 return ss
.getQuarkAbsoluteAndAdd(Attributes
.CPUS
);
164 * Get the Soft IRQs node
170 * @return the Soft IRQ node quark
172 public static int getNodeSoftIRQs(int cpuNumber
, ITmfStateSystemBuilder ss
) {
173 return ss
.getQuarkAbsoluteAndAdd(Attributes
.CPUS
, Integer
.toString(cpuNumber
), Attributes
.SOFT_IRQS
);
177 * Get the threads node
181 * @return the threads quark
183 public static int getNodeThreads(ITmfStateSystemBuilder ss
) {
184 return ss
.getQuarkAbsoluteAndAdd(Attributes
.THREADS
);
188 * Reset the CPU's status when it's coming out of an interruption.
191 * the time when the status of the cpu is "leaving irq"
193 * the cpu returning to its previous state
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
204 public static void cpuExitInterrupt(long timestamp
, Integer cpuNumber
, ITmfStateSystemBuilder ssb
)
205 throws StateValueTypeException
, TimeRangeException
, AttributeNotFoundException
{
206 int currentCPUNode
= getCurrentCPUNode(cpuNumber
, ssb
);
208 ITmfStateValue value
= getCpuStatus(ssb
, currentCPUNode
);
209 ssb
.modifyAttribute(timestamp
, value
, currentCPUNode
);
213 * Get the ongoing Status state of a CPU.
215 * This will look through the states of the
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.
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
234 private static ITmfStateValue
getCpuStatus(ITmfStateSystemBuilder ssb
, int cpuQuark
)
235 throws AttributeNotFoundException
{
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()) {
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()) {
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).
261 int currentThreadQuark
= ssb
.getQuarkRelativeAndAdd(cpuQuark
, Attributes
.CURRENT_THREAD
);
262 ITmfStateValue currentThreadState
= ssb
.queryOngoingState(currentThreadQuark
);
263 if (currentThreadState
.isNull()) {
264 return TmfStateValue
.nullValue();
266 int tid
= currentThreadState
.unboxInt();
268 return StateValues
.CPU_STATUS_IDLE_VALUE
;
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
);