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