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 org
.eclipse
.jdt
.annotation
.Nullable
;
13 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.kernelanalysis
.Attributes
;
14 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.kernelanalysis
.StateValues
;
15 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystemBuilder
;
16 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
17 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateValueTypeException
;
18 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.TimeRangeException
;
19 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
20 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
21 import org
.eclipse
.tracecompass
.tmf
.core
.event
.aspect
.TmfCpuAspect
;
22 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceUtils
;
25 * Kernel Event Handler Utils is a collection of static methods to be used in
26 * subclasses of IKernelEventHandler.
28 * @author Matthew Khouzam
29 * @author Francis Giraldeau
31 public final class KernelEventHandlerUtils
{
33 private KernelEventHandlerUtils() {
40 * The event containing the cpu
42 * @return the CPU number (null for not set)
44 public static @Nullable Integer
getCpu(ITmfEvent event
) {
45 Integer cpuObj
= TmfTraceUtils
.resolveIntEventAspectOfClassForEvent(event
.getTrace(), TmfCpuAspect
.class, event
);
47 /* We couldn't find any CPU information, ignore this event */
54 * Gets the current CPU quark
61 * @return the current CPU quark -1 for not set
63 public static int getCurrentCPUNode(Integer cpuNumber
, ITmfStateSystemBuilder ss
) {
64 return ss
.getQuarkRelativeAndAdd(getNodeCPUs(ss
), cpuNumber
.toString());
68 * Get the timestamp of the event
71 * the event containing the timestamp
73 * @return the timestamp in long format
75 public static long getTimestamp(ITmfEvent event
) {
76 return event
.getTimestamp().toNanos();
80 * Get the current thread node
87 * @return the current thread node quark
88 * @throws AttributeNotFoundException
89 * current cpu node not found
91 public static int getCurrentThreadNode(Integer cpuNumber
, ITmfStateSystemBuilder ss
) throws AttributeNotFoundException
{
93 * Shortcut for the "current thread" attribute node. It requires
94 * querying the current CPU's current thread.
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
), String
.valueOf(thread
));
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
109 * the time in the state system of the change
110 * @param currentThreadNode
111 * The current thread node
114 * @throws AttributeNotFoundException
115 * an attribute does not exists yet
116 * @throws TimeRangeException
117 * the time is out of range
118 * @throws StateValueTypeException
119 * the attribute was not set with int values
121 public static void setProcessToRunning(long timestamp
, int currentThreadNode
, ITmfStateSystemBuilder ssb
)
122 throws AttributeNotFoundException
, TimeRangeException
,
123 StateValueTypeException
{
125 ITmfStateValue value
;
127 quark
= ssb
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.SYSTEM_CALL
);
128 if (ssb
.queryOngoingState(quark
).isNull()) {
129 /* We were in user mode before the interruption */
130 value
= StateValues
.PROCESS_STATUS_RUN_USERMODE_VALUE
;
132 /* We were previously in kernel mode */
133 value
= StateValues
.PROCESS_STATUS_RUN_SYSCALL_VALUE
;
135 quark
= ssb
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.STATUS
);
136 ssb
.modifyAttribute(timestamp
, value
, quark
);
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 AttributeNotFoundException
200 * the attribute was not created yet
201 * @throws TimeRangeException
202 * the time is out of range
204 public static void cpuExitInterrupt(long timestamp
, Integer cpuNumber
, ITmfStateSystemBuilder ssb
)
205 throws StateValueTypeException
, AttributeNotFoundException
,
208 ITmfStateValue value
;
209 int currentCPUNode
= getCurrentCPUNode(cpuNumber
, ssb
);
211 quark
= ssb
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.CURRENT_THREAD
);
212 if (ssb
.queryOngoingState(quark
).unboxInt() > 0) {
213 /* There was a process on the CPU */
214 quark
= ssb
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.SYSTEM_CALL
);
215 if (ssb
.queryOngoingState(quark
).isNull()) {
216 /* That process was in user mode */
217 value
= StateValues
.CPU_STATUS_RUN_USERMODE_VALUE
;
219 /* That process was in a system call */
220 value
= StateValues
.CPU_STATUS_RUN_SYSCALL_VALUE
;
223 /* There was no real process scheduled, CPU was idle */
224 value
= StateValues
.CPU_STATUS_IDLE_VALUE
;
226 quark
= ssb
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.STATUS
);
227 ssb
.modifyAttribute(timestamp
, value
, quark
);