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