Commit | Line | Data |
---|---|---|
c8f45ad2 MK |
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 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; | |
c8f45ad2 MK |
22 | import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils; |
23 | ||
24 | /** | |
25 | * Kernel Event Handler Utils is a collection of static methods to be used in | |
26 | * subclasses of IKernelEventHandler. | |
27 | * | |
28 | * @author Matthew Khouzam | |
29 | * @author Francis Giraldeau | |
30 | */ | |
31 | public final class KernelEventHandlerUtils { | |
32 | ||
33 | private KernelEventHandlerUtils() {} | |
34 | ||
35 | /** | |
36 | * Get CPU | |
37 | * | |
38 | * @param event | |
39 | * The event containing the cpu | |
40 | * | |
41 | * @return the CPU number (null for not set) | |
42 | */ | |
43 | public static @Nullable Integer getCpu(ITmfEvent event) { | |
44 | Integer cpuObj = TmfTraceUtils.resolveIntEventAspectOfClassForEvent(event.getTrace(), TmfCpuAspect.class, event); | |
45 | if (cpuObj == null) { | |
46 | /* We couldn't find any CPU information, ignore this event */ | |
47 | return null; | |
48 | } | |
49 | return cpuObj; | |
50 | } | |
51 | ||
52 | /** | |
53 | * Gets the current CPU quark | |
54 | * | |
55 | * @param cpuNumber | |
56 | * The cpu number | |
57 | * @param ss | |
58 | * the state system | |
59 | * | |
60 | * @return the current CPU quark -1 for not set | |
61 | */ | |
62 | public static int getCurrentCPUNode(Integer cpuNumber, ITmfStateSystemBuilder ss) { | |
63 | return ss.getQuarkRelativeAndAdd(getNodeCPUs(ss), cpuNumber.toString()); | |
64 | } | |
65 | ||
66 | ||
67 | /** | |
68 | * Get the timestamp of the event | |
69 | * | |
70 | * @param event | |
71 | * the event containing the timestamp | |
72 | * | |
73 | * @return the timestamp in long format | |
74 | */ | |
75 | public static long getTimestamp(ITmfEvent event) { | |
16801c72 | 76 | return event.getTimestamp().toNanos(); |
c8f45ad2 MK |
77 | } |
78 | ||
79 | /** | |
80 | * Get the current thread node | |
81 | * | |
82 | * @param cpuNumber | |
83 | * The cpu number | |
84 | * @param ss | |
85 | * the state system | |
86 | * | |
87 | * @return the current thread node quark | |
88 | * @throws AttributeNotFoundException | |
89 | * current cpu node not found | |
90 | */ | |
91 | public static int getCurrentThreadNode(Integer cpuNumber, ITmfStateSystemBuilder ss) throws AttributeNotFoundException { | |
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), String.valueOf(thread)); | |
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 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 | |
120 | */ | |
121 | public static void setProcessToRunning(long timestamp, int currentThreadNode, ITmfStateSystemBuilder ssb) | |
122 | throws AttributeNotFoundException, TimeRangeException, | |
123 | StateValueTypeException { | |
124 | int quark; | |
125 | ITmfStateValue value; | |
126 | ||
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; | |
131 | } else { | |
132 | /* We were previously in kernel mode */ | |
133 | value = StateValues.PROCESS_STATUS_RUN_SYSCALL_VALUE; | |
134 | } | |
135 | quark = ssb.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS); | |
136 | ssb.modifyAttribute(timestamp, value, quark); | |
137 | } | |
138 | ||
139 | /** | |
140 | * Get the IRQs node | |
141 | * | |
142 | * @param ss | |
143 | * the state system | |
144 | * @return the IRQ node quark | |
145 | */ | |
146 | public static int getNodeIRQs(ITmfStateSystemBuilder ss) { | |
147 | return ss.getQuarkAbsoluteAndAdd(Attributes.RESOURCES, 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 ss | |
165 | * the state system | |
166 | * @return the Soft IRQ node quark | |
167 | */ | |
168 | public static int getNodeSoftIRQs(ITmfStateSystemBuilder ss) { | |
169 | return ss.getQuarkAbsoluteAndAdd(Attributes.RESOURCES, Attributes.SOFT_IRQS); | |
170 | } | |
171 | ||
172 | /** | |
173 | * Get the threads node | |
174 | * | |
175 | * @param ss | |
176 | * the state system | |
177 | * @return the threads quark | |
178 | */ | |
179 | public static int getNodeThreads(ITmfStateSystemBuilder ss) { | |
180 | return ss.getQuarkAbsoluteAndAdd(Attributes.THREADS); | |
181 | } | |
182 | ||
183 | /** | |
184 | * Reset the CPU's status when it's coming out of an interruption. | |
185 | * | |
186 | * @param timestamp | |
187 | * the time when the status of the cpu is "leaving irq" | |
188 | * @param cpuNumber | |
189 | * the cpu returning to its previous state | |
190 | * | |
191 | * @param ssb | |
192 | * State system | |
193 | * @throws StateValueTypeException | |
194 | * the attribute is not set as an int | |
195 | * @throws AttributeNotFoundException | |
196 | * the attribute was not created yet | |
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, AttributeNotFoundException, | |
202 | TimeRangeException { | |
203 | int quark; | |
204 | ITmfStateValue value; | |
205 | int currentCPUNode = getCurrentCPUNode(cpuNumber, ssb); | |
206 | ||
207 | quark = ssb.getQuarkRelativeAndAdd(currentCPUNode, Attributes.CURRENT_THREAD); | |
208 | if (ssb.queryOngoingState(quark).unboxInt() > 0) { | |
209 | /* There was a process on the CPU */ | |
210 | quark = ssb.getQuarkRelativeAndAdd(currentCPUNode, Attributes.SYSTEM_CALL); | |
211 | if (ssb.queryOngoingState(quark).isNull()) { | |
212 | /* That process was in user mode */ | |
213 | value = StateValues.CPU_STATUS_RUN_USERMODE_VALUE; | |
214 | } else { | |
215 | /* That process was in a system call */ | |
216 | value = StateValues.CPU_STATUS_RUN_SYSCALL_VALUE; | |
217 | } | |
218 | } else { | |
219 | /* There was no real process scheduled, CPU was idle */ | |
220 | value = StateValues.CPU_STATUS_IDLE_VALUE; | |
221 | } | |
222 | quark = ssb.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS); | |
223 | ssb.modifyAttribute(timestamp, value, quark); | |
224 | } | |
225 | ||
226 | } |