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 | ||
19ed6598 MK |
33 | private KernelEventHandlerUtils() { |
34 | } | |
c8f45ad2 MK |
35 | |
36 | /** | |
37 | * Get CPU | |
38 | * | |
39 | * @param event | |
40 | * The event containing the cpu | |
41 | * | |
42 | * @return the CPU number (null for not set) | |
43 | */ | |
44 | public static @Nullable Integer getCpu(ITmfEvent event) { | |
45 | Integer cpuObj = TmfTraceUtils.resolveIntEventAspectOfClassForEvent(event.getTrace(), TmfCpuAspect.class, event); | |
46 | if (cpuObj == null) { | |
47 | /* We couldn't find any CPU information, ignore this event */ | |
48 | return null; | |
49 | } | |
50 | return cpuObj; | |
51 | } | |
52 | ||
53 | /** | |
54 | * Gets the current CPU quark | |
55 | * | |
56 | * @param cpuNumber | |
57 | * The cpu number | |
58 | * @param ss | |
59 | * the state system | |
60 | * | |
61 | * @return the current CPU quark -1 for not set | |
62 | */ | |
63 | public static int getCurrentCPUNode(Integer cpuNumber, ITmfStateSystemBuilder ss) { | |
64 | return ss.getQuarkRelativeAndAdd(getNodeCPUs(ss), cpuNumber.toString()); | |
65 | } | |
66 | ||
c8f45ad2 MK |
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 | * | |
19ed6598 MK |
142 | * @param cpuNumber |
143 | * the cpu core | |
c8f45ad2 MK |
144 | * @param ss |
145 | * the state system | |
146 | * @return the IRQ node quark | |
147 | */ | |
19ed6598 MK |
148 | public static int getNodeIRQs(int cpuNumber, ITmfStateSystemBuilder ss) { |
149 | return ss.getQuarkAbsoluteAndAdd(Attributes.CPUS, Integer.toString(cpuNumber), Attributes.IRQS); | |
c8f45ad2 MK |
150 | } |
151 | ||
152 | /** | |
153 | * Get the CPUs node | |
154 | * | |
155 | * @param ss | |
156 | * the state system | |
157 | * @return the CPU node quark | |
158 | */ | |
159 | public static int getNodeCPUs(ITmfStateSystemBuilder ss) { | |
160 | return ss.getQuarkAbsoluteAndAdd(Attributes.CPUS); | |
161 | } | |
162 | ||
163 | /** | |
164 | * Get the Soft IRQs node | |
165 | * | |
19ed6598 MK |
166 | * @param cpuNumber |
167 | * the cpu core | |
c8f45ad2 MK |
168 | * @param ss |
169 | * the state system | |
170 | * @return the Soft IRQ node quark | |
171 | */ | |
19ed6598 MK |
172 | public static int getNodeSoftIRQs(int cpuNumber, ITmfStateSystemBuilder ss) { |
173 | return ss.getQuarkAbsoluteAndAdd(Attributes.CPUS, Integer.toString(cpuNumber), Attributes.SOFT_IRQS); | |
c8f45ad2 MK |
174 | } |
175 | ||
176 | /** | |
177 | * Get the threads node | |
178 | * | |
179 | * @param ss | |
180 | * the state system | |
181 | * @return the threads quark | |
182 | */ | |
183 | public static int getNodeThreads(ITmfStateSystemBuilder ss) { | |
184 | return ss.getQuarkAbsoluteAndAdd(Attributes.THREADS); | |
185 | } | |
186 | ||
187 | /** | |
188 | * Reset the CPU's status when it's coming out of an interruption. | |
189 | * | |
190 | * @param timestamp | |
191 | * the time when the status of the cpu is "leaving irq" | |
192 | * @param cpuNumber | |
193 | * the cpu returning to its previous state | |
194 | * | |
195 | * @param ssb | |
196 | * State system | |
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 | |
203 | */ | |
204 | public static void cpuExitInterrupt(long timestamp, Integer cpuNumber, ITmfStateSystemBuilder ssb) | |
205 | throws StateValueTypeException, AttributeNotFoundException, | |
206 | TimeRangeException { | |
207 | int quark; | |
208 | ITmfStateValue value; | |
209 | int currentCPUNode = getCurrentCPUNode(cpuNumber, ssb); | |
210 | ||
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; | |
218 | } else { | |
219 | /* That process was in a system call */ | |
220 | value = StateValues.CPU_STATUS_RUN_SYSCALL_VALUE; | |
221 | } | |
222 | } else { | |
223 | /* There was no real process scheduled, CPU was idle */ | |
224 | value = StateValues.CPU_STATUS_IDLE_VALUE; | |
225 | } | |
226 | quark = ssb.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS); | |
227 | ssb.modifyAttribute(timestamp, value, quark); | |
228 | } | |
229 | ||
230 | } |