Commit | Line | Data |
---|---|---|
efc403bb AM |
1 | /******************************************************************************* |
2 | * Copyright (c) 2012 Ericsson | |
3 | * Copyright (c) 2010, 2011 École Polytechnique de Montréal | |
4 | * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com> | |
d85d2a6d | 5 | * |
efc403bb AM |
6 | * All rights reserved. This program and the accompanying materials are |
7 | * made available under the terms of the Eclipse Public License v1.0 which | |
8 | * accompanies this distribution, and is available at | |
9 | * http://www.eclipse.org/legal/epl-v10.html | |
d85d2a6d | 10 | * |
efc403bb AM |
11 | *******************************************************************************/ |
12 | ||
13 | package org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider; | |
14 | ||
79e0a1df | 15 | import java.util.HashMap; |
efc403bb | 16 | |
79e0a1df AM |
17 | import org.eclipse.linuxtools.internal.lttng2.kernel.core.Attributes; |
18 | import org.eclipse.linuxtools.internal.lttng2.kernel.core.LttngStrings; | |
19 | import org.eclipse.linuxtools.internal.lttng2.kernel.core.StateValues; | |
efc403bb AM |
20 | import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEvent; |
21 | import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTrace; | |
2c2f900e | 22 | import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; |
79e0a1df AM |
23 | import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; |
24 | import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException; | |
25 | import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException; | |
26 | import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException; | |
27 | import org.eclipse.linuxtools.tmf.core.statesystem.AbstractStateChangeInput; | |
f1f86dfb | 28 | import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystemBuilder; |
79e0a1df AM |
29 | import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue; |
30 | import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue; | |
efc403bb AM |
31 | |
32 | /** | |
33 | * This is the state change input plugin for TMF's state system which handles | |
34 | * the LTTng 2.0 kernel traces in CTF format. | |
d85d2a6d | 35 | * |
efc403bb | 36 | * It uses the reference handler defined in CTFKernelHandler.java. |
d85d2a6d | 37 | * |
efc403bb | 38 | * @author alexmont |
d85d2a6d | 39 | * |
efc403bb | 40 | */ |
79e0a1df | 41 | public class CtfKernelStateInput extends AbstractStateChangeInput { |
efc403bb | 42 | |
79e0a1df AM |
43 | /* Event names HashMap. TODO: This can be discarded once we move to Java 7 */ |
44 | private final HashMap<String, Integer> knownEventNames; | |
efc403bb | 45 | |
79e0a1df AM |
46 | /* Common locations in the attribute tree */ |
47 | private int cpusNode = -1; | |
48 | private int threadsNode = -1; | |
49 | private int irqsNode = -1; | |
50 | private int softIrqsNode = -1; | |
efc403bb | 51 | |
efc403bb AM |
52 | |
53 | /** | |
54 | * Instantiate a new state provider plugin. | |
d85d2a6d AM |
55 | * |
56 | * @param trace | |
efc403bb | 57 | * The LTTng 2.0 kernel trace directory |
efc403bb | 58 | */ |
dc0f7bfe | 59 | public CtfKernelStateInput(CtfTmfTrace trace) { |
71f2da63 | 60 | super(trace, CtfTmfEvent.class, "LTTng Kernel"); //$NON-NLS-1$ |
79e0a1df | 61 | knownEventNames = fillEventNames(); |
2c2f900e | 62 | } |
efc403bb | 63 | |
2c2f900e | 64 | @Override |
f1f86dfb | 65 | public void assignTargetStateSystem(ITmfStateSystemBuilder ssb) { |
79e0a1df AM |
66 | /* We can only set up the locations once the state system is assigned */ |
67 | super.assignTargetStateSystem(ssb); | |
68 | setupCommonLocations(); | |
2c2f900e | 69 | } |
efc403bb | 70 | |
efc403bb | 71 | @Override |
79e0a1df | 72 | protected void eventHandle(ITmfEvent ev) { |
79044a66 AM |
73 | /* |
74 | * AbstractStateChangeInput should have already checked for the correct | |
75 | * class type | |
76 | */ | |
79e0a1df AM |
77 | CtfTmfEvent event = (CtfTmfEvent) ev; |
78 | ||
79 | int quark; | |
80 | ITmfStateValue value; | |
81 | ||
82 | final ITmfEventField content = event.getContent(); | |
83 | final String eventName = event.getEventName(); | |
84 | final long ts = event.getTimestamp().getValue(); | |
85 | ||
2c2f900e | 86 | try { |
79e0a1df AM |
87 | /* Shortcut for the "current CPU" attribute node */ |
88 | final Integer currentCPUNode = ss.getQuarkRelativeAndAdd(cpusNode, String.valueOf(event.getCPU())); | |
89 | ||
90 | /* | |
91 | * Shortcut for the "current thread" attribute node. It requires | |
92 | * querying the current CPU's current thread. | |
93 | */ | |
94 | quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.CURRENT_THREAD); | |
95 | value = ss.queryOngoingState(quark); | |
96 | int thread = value.unboxInt(); | |
97 | final Integer currentThreadNode = ss.getQuarkRelativeAndAdd(threadsNode, String.valueOf(thread)); | |
98 | ||
99 | /* | |
100 | * Feed event to the history system if it's known to cause a state | |
101 | * transition. | |
102 | */ | |
103 | switch (getEventIndex(eventName)) { | |
104 | ||
105 | case 1: // "exit_syscall": | |
106 | /* Fields: int64 ret */ | |
107 | { | |
108 | /* Clear the current system call on the process */ | |
109 | quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL); | |
110 | value = TmfStateValue.nullValue(); | |
111 | ss.modifyAttribute(ts, value, quark); | |
112 | ||
113 | /* Put the process' status back to user mode */ | |
114 | quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS); | |
115 | value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_RUN_USERMODE); | |
116 | ss.modifyAttribute(ts, value, quark); | |
117 | ||
118 | /* Put the CPU's status back to user mode */ | |
119 | quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS); | |
120 | value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_USERMODE); | |
121 | ss.modifyAttribute(ts, value, quark); | |
122 | } | |
123 | break; | |
124 | ||
125 | case 2: // "irq_handler_entry": | |
126 | /* Fields: int32 irq, string name */ | |
127 | { | |
128 | Integer irqId = ((Long) content.getField(LttngStrings.IRQ).getValue()).intValue(); | |
129 | ||
130 | /* Mark this IRQ as active in the resource tree. | |
131 | * The state value = the CPU on which this IRQ is sitting */ | |
132 | quark = ss.getQuarkRelativeAndAdd(irqsNode, irqId.toString()); | |
133 | value = TmfStateValue.newValueInt(event.getCPU()); | |
134 | ss.modifyAttribute(ts, value, quark); | |
135 | ||
136 | /* Change the status of the running process to interrupted */ | |
137 | quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS); | |
138 | value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_INTERRUPTED); | |
139 | ss.modifyAttribute(ts, value, quark); | |
140 | ||
141 | /* Change the status of the CPU to interrupted */ | |
142 | quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS); | |
143 | value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_IRQ); | |
144 | ss.modifyAttribute(ts, value, quark); | |
145 | } | |
146 | break; | |
147 | ||
148 | case 3: // "irq_handler_exit": | |
149 | /* Fields: int32 irq, int32 ret */ | |
150 | { | |
151 | Integer irqId = ((Long) content.getField(LttngStrings.IRQ).getValue()).intValue(); | |
152 | ||
153 | /* Put this IRQ back to inactive in the resource tree */ | |
154 | quark = ss.getQuarkRelativeAndAdd(irqsNode, irqId.toString()); | |
155 | value = TmfStateValue.nullValue(); | |
156 | ss.modifyAttribute(ts, value, quark); | |
157 | ||
158 | /* Set the previous process back to running */ | |
159 | setProcessToRunning(ts, currentThreadNode); | |
160 | ||
161 | /* Set the CPU status back to running or "idle" */ | |
162 | cpuExitInterrupt(ts, currentCPUNode, currentThreadNode); | |
163 | } | |
164 | break; | |
165 | ||
166 | case 4: // "softirq_entry": | |
167 | /* Fields: int32 vec */ | |
168 | { | |
169 | Integer softIrqId = ((Long) content.getField(LttngStrings.VEC).getValue()).intValue(); | |
170 | ||
171 | /* Mark this SoftIRQ as active in the resource tree. | |
172 | * The state value = the CPU on which this SoftIRQ is processed */ | |
173 | quark = ss.getQuarkRelativeAndAdd(softIrqsNode, softIrqId.toString()); | |
174 | value = TmfStateValue.newValueInt(event.getCPU()); | |
175 | ss.modifyAttribute(ts, value, quark); | |
176 | ||
177 | /* Change the status of the running process to interrupted */ | |
178 | quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS); | |
179 | value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_INTERRUPTED); | |
180 | ss.modifyAttribute(ts, value, quark); | |
181 | ||
182 | /* Change the status of the CPU to interrupted */ | |
183 | quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS); | |
184 | value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_SOFTIRQ); | |
185 | ss.modifyAttribute(ts, value, quark); | |
186 | } | |
187 | break; | |
188 | ||
189 | case 5: // "softirq_exit": | |
190 | /* Fields: int32 vec */ | |
191 | { | |
192 | Integer softIrqId = ((Long) content.getField(LttngStrings.VEC).getValue()).intValue(); | |
193 | ||
194 | /* Put this SoftIRQ back to inactive (= -1) in the resource tree */ | |
195 | quark = ss.getQuarkRelativeAndAdd(softIrqsNode, softIrqId.toString()); | |
196 | value = TmfStateValue.nullValue(); | |
197 | ss.modifyAttribute(ts, value, quark); | |
198 | ||
199 | /* Set the previous process back to running */ | |
200 | setProcessToRunning(ts, currentThreadNode); | |
201 | ||
202 | /* Set the CPU status back to "busy" or "idle" */ | |
203 | cpuExitInterrupt(ts, currentCPUNode, currentThreadNode); | |
204 | } | |
205 | break; | |
206 | ||
207 | case 6: // "softirq_raise": | |
208 | /* Fields: int32 vec */ | |
209 | { | |
210 | Integer softIrqId = ((Long) content.getField(LttngStrings.VEC).getValue()).intValue(); | |
211 | ||
212 | /* Mark this SoftIRQ as *raised* in the resource tree. | |
213 | * State value = -2 */ | |
214 | quark = ss.getQuarkRelativeAndAdd(softIrqsNode, softIrqId.toString()); | |
215 | value = TmfStateValue.newValueInt(StateValues.SOFT_IRQ_RAISED); | |
216 | ss.modifyAttribute(ts, value, quark); | |
217 | } | |
218 | break; | |
219 | ||
220 | case 7: // "sched_switch": | |
221 | /* | |
222 | * Fields: string prev_comm, int32 prev_tid, int32 prev_prio, int64 prev_state, | |
223 | * string next_comm, int32 next_tid, int32 next_prio | |
224 | */ | |
225 | { | |
226 | Integer prevTid = ((Long) content.getField(LttngStrings.PREV_TID).getValue()).intValue(); | |
227 | //Long prevState = (Long) content.getField(LttngStrings.PREV_STATE).getValue(); | |
228 | String nextProcessName = (String) content.getField(LttngStrings.NEXT_COMM).getValue(); | |
229 | Integer nextTid = ((Long) content.getField(LttngStrings.NEXT_TID).getValue()).intValue(); | |
230 | ||
231 | Integer formerThreadNode = ss.getQuarkRelativeAndAdd(threadsNode, prevTid.toString()); | |
232 | Integer newCurrentThreadNode = ss.getQuarkRelativeAndAdd(threadsNode, nextTid.toString()); | |
233 | ||
234 | /* Set the status of the process that got scheduled out. */ | |
235 | quark = ss.getQuarkRelativeAndAdd(formerThreadNode, Attributes.STATUS); | |
236 | value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_WAIT); | |
237 | ss.modifyAttribute(ts, value, quark); | |
238 | ||
239 | /* Set the status of the new scheduled process */ | |
240 | setProcessToRunning(ts, newCurrentThreadNode); | |
241 | ||
242 | /* Set the exec name of the new process */ | |
243 | quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.EXEC_NAME); | |
244 | value = TmfStateValue.newValueString(nextProcessName); | |
245 | ss.modifyAttribute(ts, value, quark); | |
246 | ||
247 | /* | |
248 | * Check if we need to set the syscall state and the PPID of | |
249 | * the new process (in case we haven't seen this process before) | |
250 | */ | |
251 | quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.SYSTEM_CALL); | |
252 | if (ss.isLastAttribute(quark)) { /* Did we just add this attribute? */ | |
253 | value = TmfStateValue.nullValue(); | |
254 | ss.modifyAttribute(ts, value, quark); | |
255 | } | |
256 | quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.PPID); | |
257 | if (ss.isLastAttribute(quark)) { | |
258 | value = TmfStateValue.nullValue(); | |
259 | ss.modifyAttribute(ts, value, quark); | |
260 | } | |
261 | ||
262 | /* Set the current scheduled process on the relevant CPU */ | |
263 | quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.CURRENT_THREAD); | |
264 | value = TmfStateValue.newValueInt(nextTid); | |
265 | ss.modifyAttribute(ts, value, quark); | |
266 | ||
267 | /* Set the status of the CPU itself */ | |
268 | if (nextTid > 0) { | |
269 | /* Check if the entering process is in kernel or user mode */ | |
270 | quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.SYSTEM_CALL); | |
271 | if (ss.queryOngoingState(quark).isNull()) { | |
272 | value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_USERMODE); | |
273 | } else { | |
274 | value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_SYSCALL); | |
275 | } | |
276 | } else { | |
277 | value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_IDLE); | |
278 | } | |
279 | quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS); | |
280 | ss.modifyAttribute(ts, value, quark); | |
281 | } | |
282 | break; | |
283 | ||
284 | case 8: // "sched_process_fork": | |
285 | /* Fields: string parent_comm, int32 parent_tid, | |
286 | * string child_comm, int32 child_tid */ | |
287 | { | |
288 | // String parentProcessName = (String) event.getFieldValue("parent_comm"); | |
289 | String childProcessName = (String) content.getField(LttngStrings.CHILD_COMM).getValue(); | |
290 | // assert ( parentProcessName.equals(childProcessName) ); | |
291 | ||
292 | Integer parentTid = ((Long) content.getField(LttngStrings.PARENT_TID).getValue()).intValue(); | |
293 | Integer childTid = ((Long) content.getField(LttngStrings.CHILD_TID).getValue()).intValue(); | |
294 | ||
295 | Integer parentTidNode = ss.getQuarkRelativeAndAdd(threadsNode, parentTid.toString()); | |
296 | Integer childTidNode = ss.getQuarkRelativeAndAdd(threadsNode, childTid.toString()); | |
297 | ||
298 | /* Assign the PPID to the new process */ | |
299 | quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.PPID); | |
300 | value = TmfStateValue.newValueInt(parentTid); | |
301 | ss.modifyAttribute(ts, value, quark); | |
302 | ||
303 | /* Set the new process' exec_name */ | |
304 | quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.EXEC_NAME); | |
305 | value = TmfStateValue.newValueString(childProcessName); | |
306 | ss.modifyAttribute(ts, value, quark); | |
307 | ||
308 | /* Set the new process' status */ | |
309 | quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.STATUS); | |
310 | value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_WAIT); | |
311 | ss.modifyAttribute(ts, value, quark); | |
312 | ||
313 | /* Set the process' syscall name, to be the same as the parent's */ | |
314 | quark = ss.getQuarkRelativeAndAdd(parentTidNode, Attributes.SYSTEM_CALL); | |
315 | value = ss.queryOngoingState(quark); | |
316 | quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.SYSTEM_CALL); | |
317 | ss.modifyAttribute(ts, value, quark); | |
318 | } | |
319 | break; | |
320 | ||
321 | case 9: // "sched_process_exit": | |
322 | /* Fields: string comm, int32 tid, int32 prio */ | |
323 | break; | |
324 | ||
325 | case 10: // "sched_process_free": | |
326 | /* Fields: string comm, int32 tid, int32 prio */ | |
327 | /* | |
328 | * A sched_process_free will always happen after the sched_switch | |
329 | * that will remove the process from the cpu for the last time. So | |
330 | * this is when we should delete everything wrt to the process. | |
331 | */ | |
332 | { | |
333 | Integer tid = ((Long) content.getField(LttngStrings.TID).getValue()).intValue(); | |
334 | /* | |
335 | * Remove the process and all its sub-attributes from the | |
336 | * current state | |
337 | */ | |
338 | quark = ss.getQuarkRelativeAndAdd(threadsNode, tid.toString()); | |
339 | ss.removeAttribute(ts, quark); | |
340 | } | |
341 | break; | |
342 | ||
343 | case 11: // "lttng_statedump_process_state": | |
344 | /* Fields: | |
345 | * int32 type, int32 mode, int32 pid, int32 submode, int32 vpid, | |
346 | * int32 ppid, int32 tid, string name, int32 status, int32 vtid */ | |
347 | { | |
348 | Integer tid = ((Long) content.getField(LttngStrings.TID).getValue()).intValue(); | |
349 | int ppid = ((Long) content.getField(LttngStrings.PPID).getValue()).intValue(); | |
350 | int status = ((Long) content.getField(LttngStrings.STATUS).getValue()).intValue(); | |
351 | String name = (String) content.getField(LttngStrings.NAME).getValue(); | |
352 | /* | |
353 | * "mode" could be interesting too, but it doesn't seem to be | |
354 | * populated with anything relevant for now. | |
355 | */ | |
356 | ||
357 | int curThreadNode = ss.getQuarkRelativeAndAdd(threadsNode, tid.toString()); | |
358 | ||
359 | /* Set the process' name */ | |
360 | quark = ss.getQuarkRelativeAndAdd(curThreadNode, Attributes.EXEC_NAME); | |
361 | if (ss.queryOngoingState(quark).isNull()) { | |
362 | /* If the value didn't exist previously, set it */ | |
363 | value = TmfStateValue.newValueString(name); | |
364 | ss.modifyAttribute(ts, value, quark); | |
365 | } | |
366 | ||
367 | /* Set the process' PPID */ | |
368 | quark = ss.getQuarkRelativeAndAdd(curThreadNode, Attributes.PPID); | |
369 | if (ss.queryOngoingState(quark).isNull()) { | |
370 | value = TmfStateValue.newValueInt(ppid); | |
371 | ss.modifyAttribute(ts, value, quark); | |
372 | } | |
373 | ||
374 | /* Set the process' status */ | |
375 | quark = ss.getQuarkRelativeAndAdd(curThreadNode, Attributes.STATUS); | |
376 | if (ss.queryOngoingState(quark).isNull()) { | |
377 | /*"5" here means "LTTNG_WAIT" in the LTTng kernel tracer */ | |
378 | if (status == 5) { | |
379 | value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_WAIT); | |
380 | } else { | |
381 | value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_UNKNOWN); | |
382 | } | |
383 | ss.modifyAttribute(ts, value, quark); | |
384 | } | |
385 | } | |
386 | break; | |
387 | ||
388 | default: | |
389 | /* Other event types not covered by the main switch */ | |
390 | { | |
391 | if (eventName.startsWith(LttngStrings.SYSCALL_PREFIX) | |
392 | || eventName.startsWith(LttngStrings.COMPAT_SYSCALL_PREFIX)) { | |
393 | /* | |
394 | * This is a replacement for the old sys_enter event. Now | |
395 | * syscall names are listed into the event type | |
396 | */ | |
397 | ||
398 | /* Assign the new system call to the process */ | |
399 | quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL); | |
400 | value = TmfStateValue.newValueString(eventName); | |
401 | ss.modifyAttribute(ts, value, quark); | |
402 | ||
403 | /* Put the process in system call mode */ | |
404 | quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS); | |
405 | value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_RUN_SYSCALL); | |
406 | ss.modifyAttribute(ts, value, quark); | |
407 | ||
408 | /* Put the CPU in system call (kernel) mode */ | |
409 | quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS); | |
410 | value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_SYSCALL); | |
411 | ss.modifyAttribute(ts, value, quark); | |
412 | } | |
413 | } | |
414 | break; | |
415 | } // End of big switch | |
416 | ||
417 | /* | |
418 | * Statistics | |
419 | */ | |
420 | ||
421 | /* Number of events of each type, globally */ | |
422 | // quark = ss.getQuarkAbsoluteAndAdd(Attributes.STATISTICS, | |
423 | // Attributes.EVENT_TYPES, eventName); | |
424 | // ss.incrementAttribute(ts, quark); | |
425 | ||
426 | /* Number of events per CPU */ | |
427 | // quark = ss.getQuarkRelativeAndAdd(currentCPUNode, | |
428 | // Attributes.STATISTICS, Attributes.EVENT_TYPES, eventName); | |
429 | // ss.incrementAttribute(ts, quark); | |
430 | ||
431 | /* Number of events per process */ | |
432 | // quark = ss.getQuarkRelativeAndAdd(currentThreadNode, | |
433 | // Attributes.STATISTICS, Attributes.EVENT_TYPES, eventName); | |
434 | // ss.incrementAttribute(ts, quark); | |
435 | ||
436 | } catch (AttributeNotFoundException ae) { | |
437 | /* | |
438 | * This would indicate a problem with the logic of the manager here, | |
439 | * so it shouldn't happen. | |
440 | */ | |
441 | ae.printStackTrace(); | |
442 | ||
443 | } catch (TimeRangeException tre) { | |
444 | /* | |
445 | * This would happen if the events in the trace aren't ordered | |
446 | * chronologically, which should never be the case ... | |
447 | */ | |
448 | System.err.println("TimeRangeExcpetion caught in the state system's event manager."); //$NON-NLS-1$ | |
449 | System.err.println("Are the events in the trace correctly ordered?"); //$NON-NLS-1$ | |
450 | tre.printStackTrace(); | |
451 | ||
452 | } catch (StateValueTypeException sve) { | |
453 | /* | |
454 | * This would happen if we were trying to push/pop attributes not of | |
455 | * type integer. Which, once again, should never happen. | |
456 | */ | |
457 | sve.printStackTrace(); | |
2c2f900e AM |
458 | } |
459 | } | |
460 | ||
79e0a1df AM |
461 | private void setupCommonLocations() { |
462 | cpusNode = ss.getQuarkAbsoluteAndAdd(Attributes.CPUS); | |
463 | threadsNode = ss.getQuarkAbsoluteAndAdd(Attributes.THREADS); | |
464 | irqsNode = ss.getQuarkAbsoluteAndAdd(Attributes.RESOURCES, Attributes.IRQS); | |
465 | softIrqsNode = ss.getQuarkAbsoluteAndAdd(Attributes.RESOURCES, Attributes.SOFT_IRQS); | |
466 | } | |
467 | ||
468 | private static HashMap<String, Integer> fillEventNames() { | |
469 | /* | |
470 | * TODO Replace with straight strings in the switch/case once we move to | |
471 | * Java 7 | |
472 | */ | |
473 | HashMap<String, Integer> map = new HashMap<String, Integer>(); | |
474 | ||
475 | map.put(LttngStrings.EXIT_SYSCALL, 1); | |
476 | map.put(LttngStrings.IRQ_HANDLER_ENTRY, 2); | |
477 | map.put(LttngStrings.IRQ_HANDLER_EXIT, 3); | |
478 | map.put(LttngStrings.SOFTIRQ_ENTRY, 4); | |
479 | map.put(LttngStrings.SOFTIRQ_EXIT, 5); | |
480 | map.put(LttngStrings.SOFTIRQ_RAISE, 6); | |
481 | map.put(LttngStrings.SCHED_SWITCH, 7); | |
482 | map.put(LttngStrings.SCHED_PROCESS_FORK, 8); | |
483 | map.put(LttngStrings.SCHED_PROCESS_EXIT, 9); | |
484 | map.put(LttngStrings.SCHED_PROCESS_FREE, 10); | |
485 | map.put(LttngStrings.STATEDUMP_PROCESS_STATE, 11); | |
486 | ||
487 | return map; | |
488 | } | |
489 | ||
490 | private int getEventIndex(String eventName) { | |
491 | Integer ret = knownEventNames.get(eventName); | |
492 | return (ret != null) ? ret : -1; | |
493 | } | |
494 | ||
495 | /** | |
496 | * When we want to set a process back to a "running" state, first check | |
497 | * its current System_call attribute. If there is a system call active, we | |
498 | * put the process back in the syscall state. If not, we put it back in | |
499 | * user mode state. | |
500 | */ | |
501 | private void setProcessToRunning(long ts, int currentThreadNode) | |
502 | throws AttributeNotFoundException, TimeRangeException, | |
503 | StateValueTypeException { | |
504 | int quark; | |
505 | ITmfStateValue value; | |
506 | ||
507 | quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL); | |
508 | if (ss.queryOngoingState(quark).isNull()) { | |
509 | /* We were in user mode before the interruption */ | |
510 | value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_RUN_USERMODE); | |
511 | } else { | |
512 | /* We were previously in kernel mode */ | |
513 | value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_RUN_SYSCALL); | |
514 | } | |
515 | quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS); | |
516 | ss.modifyAttribute(ts, value, quark); | |
517 | } | |
518 | ||
519 | /** | |
520 | * Similar logic as above, but to set the CPU's status when it's coming out | |
521 | * of an interruption. | |
522 | */ | |
523 | private void cpuExitInterrupt(long ts, int currentCpuNode, int currentThreadNode) | |
524 | throws StateValueTypeException, AttributeNotFoundException, | |
525 | TimeRangeException { | |
526 | int quark; | |
527 | ITmfStateValue value; | |
528 | ||
529 | quark = ss.getQuarkRelativeAndAdd(currentCpuNode, Attributes.CURRENT_THREAD); | |
530 | if (ss.queryOngoingState(quark).unboxInt() > 0) { | |
531 | /* There was a process on the CPU */ | |
532 | quark = ss.getQuarkRelative(currentThreadNode, Attributes.SYSTEM_CALL); | |
533 | if (ss.queryOngoingState(quark).isNull()) { | |
534 | /* That process was in user mode */ | |
535 | value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_USERMODE); | |
536 | } else { | |
537 | /* That process was in a system call */ | |
538 | value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_SYSCALL); | |
539 | } | |
540 | } else { | |
541 | /* There was no real process scheduled, CPU was idle */ | |
542 | value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_IDLE); | |
2c2f900e | 543 | } |
79e0a1df AM |
544 | quark = ss.getQuarkRelativeAndAdd(currentCpuNode, Attributes.STATUS); |
545 | ss.modifyAttribute(ts, value, quark); | |
efc403bb AM |
546 | } |
547 | } |