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