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
.timestamp
.ITmfTimestamp
;
23 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceUtils
;
26 * Kernel Event Handler Utils is a collection of static methods to be used in
27 * subclasses of IKernelEventHandler.
29 * @author Matthew Khouzam
30 * @author Francis Giraldeau
32 public final class KernelEventHandlerUtils
{
34 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());
69 * Get the timestamp of the event
72 * the event containing the timestamp
74 * @return the timestamp in long format
76 public static long getTimestamp(ITmfEvent event
) {
77 return event
.getTimestamp().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
81 * Get the current thread node
88 * @return the current thread node quark
89 * @throws AttributeNotFoundException
90 * current cpu node not found
92 public static int getCurrentThreadNode(Integer cpuNumber
, ITmfStateSystemBuilder ss
) throws AttributeNotFoundException
{
94 * Shortcut for the "current thread" attribute node. It requires
95 * querying the current CPU's current thread.
97 int quark
= ss
.getQuarkRelativeAndAdd(getCurrentCPUNode(cpuNumber
, ss
), Attributes
.CURRENT_THREAD
);
98 ITmfStateValue value
= ss
.queryOngoingState(quark
);
99 int thread
= value
.isNull() ?
-1 : value
.unboxInt();
100 return ss
.getQuarkRelativeAndAdd(getNodeThreads(ss
), String
.valueOf(thread
));
104 * When we want to set a process back to a "running" state, first check its
105 * current System_call attribute. If there is a system call active, we put
106 * the process back in the syscall state. If not, we put it back in user
110 * the time in the state system of the change
111 * @param currentThreadNode
112 * The current thread node
115 * @throws AttributeNotFoundException
116 * an attribute does not exists yet
117 * @throws TimeRangeException
118 * the time is out of range
119 * @throws StateValueTypeException
120 * the attribute was not set with int values
122 public static void setProcessToRunning(long timestamp
, int currentThreadNode
, ITmfStateSystemBuilder ssb
)
123 throws AttributeNotFoundException
, TimeRangeException
,
124 StateValueTypeException
{
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 quark
= ssb
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.STATUS
);
137 ssb
.modifyAttribute(timestamp
, value
, quark
);
145 * @return the IRQ node quark
147 public static int getNodeIRQs(ITmfStateSystemBuilder ss
) {
148 return ss
.getQuarkAbsoluteAndAdd(Attributes
.RESOURCES
, Attributes
.IRQS
);
156 * @return the CPU node quark
158 public static int getNodeCPUs(ITmfStateSystemBuilder ss
) {
159 return ss
.getQuarkAbsoluteAndAdd(Attributes
.CPUS
);
163 * Get the Soft IRQs node
167 * @return the Soft IRQ node quark
169 public static int getNodeSoftIRQs(ITmfStateSystemBuilder ss
) {
170 return ss
.getQuarkAbsoluteAndAdd(Attributes
.RESOURCES
, Attributes
.SOFT_IRQS
);
174 * Get the threads node
178 * @return the threads quark
180 public static int getNodeThreads(ITmfStateSystemBuilder ss
) {
181 return ss
.getQuarkAbsoluteAndAdd(Attributes
.THREADS
);
185 * Reset the CPU's status when it's coming out of an interruption.
188 * the time when the status of the cpu is "leaving irq"
190 * the cpu returning to its previous state
194 * @throws StateValueTypeException
195 * the attribute is not set as an int
196 * @throws AttributeNotFoundException
197 * the attribute was not created yet
198 * @throws TimeRangeException
199 * the time is out of range
201 public static void cpuExitInterrupt(long timestamp
, Integer cpuNumber
, ITmfStateSystemBuilder ssb
)
202 throws StateValueTypeException
, AttributeNotFoundException
,
205 ITmfStateValue value
;
206 int currentCPUNode
= getCurrentCPUNode(cpuNumber
, ssb
);
208 quark
= ssb
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.CURRENT_THREAD
);
209 if (ssb
.queryOngoingState(quark
).unboxInt() > 0) {
210 /* There was a process on the CPU */
211 quark
= ssb
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.SYSTEM_CALL
);
212 if (ssb
.queryOngoingState(quark
).isNull()) {
213 /* That process was in user mode */
214 value
= StateValues
.CPU_STATUS_RUN_USERMODE_VALUE
;
216 /* That process was in a system call */
217 value
= StateValues
.CPU_STATUS_RUN_SYSCALL_VALUE
;
220 /* There was no real process scheduled, CPU was idle */
221 value
= StateValues
.CPU_STATUS_IDLE_VALUE
;
223 quark
= ssb
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.STATUS
);
224 ssb
.modifyAttribute(timestamp
, value
, quark
);