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; | |
22 | import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; | |
23 | import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils; | |
24 | ||
25 | /** | |
26 | * Kernel Event Handler Utils is a collection of static methods to be used in | |
27 | * subclasses of IKernelEventHandler. | |
28 | * | |
29 | * @author Matthew Khouzam | |
30 | * @author Francis Giraldeau | |
31 | */ | |
32 | public final class KernelEventHandlerUtils { | |
33 | ||
34 | private KernelEventHandlerUtils() {} | |
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 | ||
67 | ||
68 | /** | |
69 | * Get the timestamp of the event | |
70 | * | |
71 | * @param event | |
72 | * the event containing the timestamp | |
73 | * | |
74 | * @return the timestamp in long format | |
75 | */ | |
76 | public static long getTimestamp(ITmfEvent event) { | |
77 | return event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); | |
78 | } | |
79 | ||
80 | /** | |
81 | * Get the current thread node | |
82 | * | |
83 | * @param cpuNumber | |
84 | * The cpu number | |
85 | * @param ss | |
86 | * the state system | |
87 | * | |
88 | * @return the current thread node quark | |
89 | * @throws AttributeNotFoundException | |
90 | * current cpu node not found | |
91 | */ | |
92 | public static int getCurrentThreadNode(Integer cpuNumber, ITmfStateSystemBuilder ss) throws AttributeNotFoundException { | |
93 | /* | |
94 | * Shortcut for the "current thread" attribute node. It requires | |
95 | * querying the current CPU's current thread. | |
96 | */ | |
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)); | |
101 | } | |
102 | ||
103 | /** | |
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 | |
107 | * mode state. | |
108 | * | |
109 | * @param timestamp | |
110 | * the time in the state system of the change | |
111 | * @param currentThreadNode | |
112 | * The current thread node | |
113 | * @param ssb | |
114 | * the state system | |
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 | |
121 | */ | |
122 | public static void setProcessToRunning(long timestamp, int currentThreadNode, ITmfStateSystemBuilder ssb) | |
123 | throws AttributeNotFoundException, TimeRangeException, | |
124 | StateValueTypeException { | |
125 | int quark; | |
126 | ITmfStateValue value; | |
127 | ||
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; | |
132 | } else { | |
133 | /* We were previously in kernel mode */ | |
134 | value = StateValues.PROCESS_STATUS_RUN_SYSCALL_VALUE; | |
135 | } | |
136 | quark = ssb.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS); | |
137 | ssb.modifyAttribute(timestamp, value, quark); | |
138 | } | |
139 | ||
140 | /** | |
141 | * Get the IRQs node | |
142 | * | |
143 | * @param ss | |
144 | * the state system | |
145 | * @return the IRQ node quark | |
146 | */ | |
147 | public static int getNodeIRQs(ITmfStateSystemBuilder ss) { | |
148 | return ss.getQuarkAbsoluteAndAdd(Attributes.RESOURCES, Attributes.IRQS); | |
149 | } | |
150 | ||
151 | /** | |
152 | * Get the CPUs node | |
153 | * | |
154 | * @param ss | |
155 | * the state system | |
156 | * @return the CPU node quark | |
157 | */ | |
158 | public static int getNodeCPUs(ITmfStateSystemBuilder ss) { | |
159 | return ss.getQuarkAbsoluteAndAdd(Attributes.CPUS); | |
160 | } | |
161 | ||
162 | /** | |
163 | * Get the Soft IRQs node | |
164 | * | |
165 | * @param ss | |
166 | * the state system | |
167 | * @return the Soft IRQ node quark | |
168 | */ | |
169 | public static int getNodeSoftIRQs(ITmfStateSystemBuilder ss) { | |
170 | return ss.getQuarkAbsoluteAndAdd(Attributes.RESOURCES, Attributes.SOFT_IRQS); | |
171 | } | |
172 | ||
173 | /** | |
174 | * Get the threads node | |
175 | * | |
176 | * @param ss | |
177 | * the state system | |
178 | * @return the threads quark | |
179 | */ | |
180 | public static int getNodeThreads(ITmfStateSystemBuilder ss) { | |
181 | return ss.getQuarkAbsoluteAndAdd(Attributes.THREADS); | |
182 | } | |
183 | ||
184 | /** | |
185 | * Reset the CPU's status when it's coming out of an interruption. | |
186 | * | |
187 | * @param timestamp | |
188 | * the time when the status of the cpu is "leaving irq" | |
189 | * @param cpuNumber | |
190 | * the cpu returning to its previous state | |
191 | * | |
192 | * @param ssb | |
193 | * State system | |
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 | |
200 | */ | |
201 | public static void cpuExitInterrupt(long timestamp, Integer cpuNumber, ITmfStateSystemBuilder ssb) | |
202 | throws StateValueTypeException, AttributeNotFoundException, | |
203 | TimeRangeException { | |
204 | int quark; | |
205 | ITmfStateValue value; | |
206 | int currentCPUNode = getCurrentCPUNode(cpuNumber, ssb); | |
207 | ||
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; | |
215 | } else { | |
216 | /* That process was in a system call */ | |
217 | value = StateValues.CPU_STATUS_RUN_SYSCALL_VALUE; | |
218 | } | |
219 | } else { | |
220 | /* There was no real process scheduled, CPU was idle */ | |
221 | value = StateValues.CPU_STATUS_IDLE_VALUE; | |
222 | } | |
223 | quark = ssb.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS); | |
224 | ssb.modifyAttribute(timestamp, value, quark); | |
225 | } | |
226 | ||
227 | } |