Commit | Line | Data |
---|---|---|
efc403bb | 1 | /******************************************************************************* |
60ae41e1 | 2 | * Copyright (c) 2012, 2014 Ericsson |
efc403bb AM |
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 AM |
15 | import org.eclipse.linuxtools.internal.lttng2.kernel.core.Attributes; |
16 | import org.eclipse.linuxtools.internal.lttng2.kernel.core.LttngStrings; | |
17 | import org.eclipse.linuxtools.internal.lttng2.kernel.core.StateValues; | |
2c2f900e | 18 | import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; |
79e0a1df AM |
19 | import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; |
20 | import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException; | |
21 | import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException; | |
22 | import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException; | |
0fe46f2a | 23 | import org.eclipse.linuxtools.tmf.core.statesystem.AbstractTmfStateProvider; |
f1f86dfb | 24 | import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystemBuilder; |
79e0a1df AM |
25 | import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue; |
26 | import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue; | |
91e7f946 AM |
27 | import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfEvent; |
28 | import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; | |
efc403bb AM |
29 | |
30 | /** | |
31 | * This is the state change input plugin for TMF's state system which handles | |
32 | * the LTTng 2.0 kernel traces in CTF format. | |
d85d2a6d | 33 | * |
efc403bb | 34 | * It uses the reference handler defined in CTFKernelHandler.java. |
d85d2a6d | 35 | * |
efc403bb | 36 | * @author alexmont |
d85d2a6d | 37 | * |
efc403bb | 38 | */ |
d3ba47d4 | 39 | public class LttngKernelStateProvider extends AbstractTmfStateProvider { |
efc403bb | 40 | |
a96cc6be AM |
41 | /** |
42 | * Version number of this state provider. Please bump this if you modify the | |
43 | * contents of the generated state history in some way. | |
44 | */ | |
bc19bff3 | 45 | private static final int VERSION = 4; |
a96cc6be | 46 | |
6383e95d AM |
47 | // ------------------------------------------------------------------------ |
48 | // Constructor | |
49 | // ------------------------------------------------------------------------ | |
efc403bb AM |
50 | |
51 | /** | |
52 | * Instantiate a new state provider plugin. | |
d85d2a6d AM |
53 | * |
54 | * @param trace | |
efc403bb | 55 | * The LTTng 2.0 kernel trace directory |
efc403bb | 56 | */ |
d3ba47d4 | 57 | public LttngKernelStateProvider(CtfTmfTrace trace) { |
71f2da63 | 58 | super(trace, CtfTmfEvent.class, "LTTng Kernel"); //$NON-NLS-1$ |
2c2f900e | 59 | } |
efc403bb | 60 | |
6383e95d AM |
61 | // ------------------------------------------------------------------------ |
62 | // IStateChangeInput | |
63 | // ------------------------------------------------------------------------ | |
64 | ||
a96cc6be AM |
65 | @Override |
66 | public int getVersion() { | |
67 | return VERSION; | |
68 | } | |
69 | ||
2c2f900e | 70 | @Override |
f1f86dfb | 71 | public void assignTargetStateSystem(ITmfStateSystemBuilder ssb) { |
79e0a1df AM |
72 | /* We can only set up the locations once the state system is assigned */ |
73 | super.assignTargetStateSystem(ssb); | |
2c2f900e | 74 | } |
efc403bb | 75 | |
e96ab5c4 | 76 | @Override |
d3ba47d4 AM |
77 | public LttngKernelStateProvider getNewInstance() { |
78 | return new LttngKernelStateProvider((CtfTmfTrace) this.getTrace()); | |
e96ab5c4 AM |
79 | } |
80 | ||
efc403bb | 81 | @Override |
79e0a1df | 82 | protected void eventHandle(ITmfEvent ev) { |
79044a66 AM |
83 | /* |
84 | * AbstractStateChangeInput should have already checked for the correct | |
85 | * class type | |
86 | */ | |
3ae73cfa | 87 | final CtfTmfEvent event = (CtfTmfEvent) ev; |
79e0a1df | 88 | |
33803b9b | 89 | final String eventName = event.getType().getName(); |
79e0a1df AM |
90 | final long ts = event.getTimestamp().getValue(); |
91 | ||
2c2f900e | 92 | try { |
79e0a1df | 93 | /* Shortcut for the "current CPU" attribute node */ |
6383e95d | 94 | final Integer currentCPUNode = ss.getQuarkRelativeAndAdd(getNodeCPUs(), String.valueOf(event.getCPU())); |
79e0a1df AM |
95 | |
96 | /* | |
97 | * Shortcut for the "current thread" attribute node. It requires | |
98 | * querying the current CPU's current thread. | |
99 | */ | |
3ae73cfa AM |
100 | int quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.CURRENT_THREAD); |
101 | ITmfStateValue value = ss.queryOngoingState(quark); | |
359eeba0 | 102 | int thread = value.isNull() ? -1 : value.unboxInt(); |
6383e95d | 103 | final Integer currentThreadNode = ss.getQuarkRelativeAndAdd(getNodeThreads(), String.valueOf(thread)); |
79e0a1df AM |
104 | |
105 | /* | |
106 | * Feed event to the history system if it's known to cause a state | |
107 | * transition. | |
108 | */ | |
3ae73cfa | 109 | switch (eventName) { |
79e0a1df | 110 | |
3ae73cfa | 111 | case LttngStrings.EXIT_SYSCALL: |
79e0a1df AM |
112 | /* Fields: int64 ret */ |
113 | { | |
114 | /* Clear the current system call on the process */ | |
115 | quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL); | |
116 | value = TmfStateValue.nullValue(); | |
117 | ss.modifyAttribute(ts, value, quark); | |
118 | ||
119 | /* Put the process' status back to user mode */ | |
120 | quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS); | |
dfb27cee | 121 | value = StateValues.PROCESS_STATUS_RUN_USERMODE_VALUE; |
79e0a1df AM |
122 | ss.modifyAttribute(ts, value, quark); |
123 | ||
124 | /* Put the CPU's status back to user mode */ | |
125 | quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS); | |
dfb27cee | 126 | value = StateValues.CPU_STATUS_RUN_USERMODE_VALUE; |
79e0a1df AM |
127 | ss.modifyAttribute(ts, value, quark); |
128 | } | |
129 | break; | |
130 | ||
3ae73cfa | 131 | case LttngStrings.IRQ_HANDLER_ENTRY: |
79e0a1df AM |
132 | /* Fields: int32 irq, string name */ |
133 | { | |
7a2f04a6 | 134 | Integer irqId = ((Long) event.getContent().getField(LttngStrings.IRQ).getValue()).intValue(); |
79e0a1df AM |
135 | |
136 | /* Mark this IRQ as active in the resource tree. | |
137 | * The state value = the CPU on which this IRQ is sitting */ | |
6383e95d | 138 | quark = ss.getQuarkRelativeAndAdd(getNodeIRQs(), irqId.toString()); |
79e0a1df AM |
139 | value = TmfStateValue.newValueInt(event.getCPU()); |
140 | ss.modifyAttribute(ts, value, quark); | |
141 | ||
142 | /* Change the status of the running process to interrupted */ | |
143 | quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS); | |
dfb27cee | 144 | value = StateValues.PROCESS_STATUS_INTERRUPTED_VALUE; |
79e0a1df AM |
145 | ss.modifyAttribute(ts, value, quark); |
146 | ||
147 | /* Change the status of the CPU to interrupted */ | |
148 | quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS); | |
dfb27cee | 149 | value = StateValues.CPU_STATUS_IRQ_VALUE; |
79e0a1df AM |
150 | ss.modifyAttribute(ts, value, quark); |
151 | } | |
152 | break; | |
153 | ||
3ae73cfa | 154 | case LttngStrings.IRQ_HANDLER_EXIT: |
79e0a1df AM |
155 | /* Fields: int32 irq, int32 ret */ |
156 | { | |
7a2f04a6 | 157 | Integer irqId = ((Long) event.getContent().getField(LttngStrings.IRQ).getValue()).intValue(); |
79e0a1df AM |
158 | |
159 | /* Put this IRQ back to inactive in the resource tree */ | |
6383e95d | 160 | quark = ss.getQuarkRelativeAndAdd(getNodeIRQs(), irqId.toString()); |
79e0a1df AM |
161 | value = TmfStateValue.nullValue(); |
162 | ss.modifyAttribute(ts, value, quark); | |
163 | ||
164 | /* Set the previous process back to running */ | |
165 | setProcessToRunning(ts, currentThreadNode); | |
166 | ||
167 | /* Set the CPU status back to running or "idle" */ | |
168 | cpuExitInterrupt(ts, currentCPUNode, currentThreadNode); | |
169 | } | |
170 | break; | |
171 | ||
3ae73cfa | 172 | case LttngStrings.SOFTIRQ_ENTRY: |
79e0a1df AM |
173 | /* Fields: int32 vec */ |
174 | { | |
7a2f04a6 | 175 | Integer softIrqId = ((Long) event.getContent().getField(LttngStrings.VEC).getValue()).intValue(); |
79e0a1df AM |
176 | |
177 | /* Mark this SoftIRQ as active in the resource tree. | |
178 | * The state value = the CPU on which this SoftIRQ is processed */ | |
6383e95d | 179 | quark = ss.getQuarkRelativeAndAdd(getNodeSoftIRQs(), softIrqId.toString()); |
79e0a1df AM |
180 | value = TmfStateValue.newValueInt(event.getCPU()); |
181 | ss.modifyAttribute(ts, value, quark); | |
182 | ||
183 | /* Change the status of the running process to interrupted */ | |
184 | quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS); | |
dfb27cee | 185 | value = StateValues.PROCESS_STATUS_INTERRUPTED_VALUE; |
79e0a1df AM |
186 | ss.modifyAttribute(ts, value, quark); |
187 | ||
188 | /* Change the status of the CPU to interrupted */ | |
189 | quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS); | |
dfb27cee | 190 | value = StateValues.CPU_STATUS_SOFTIRQ_VALUE; |
79e0a1df AM |
191 | ss.modifyAttribute(ts, value, quark); |
192 | } | |
193 | break; | |
194 | ||
3ae73cfa | 195 | case LttngStrings.SOFTIRQ_EXIT: |
79e0a1df AM |
196 | /* Fields: int32 vec */ |
197 | { | |
7a2f04a6 | 198 | Integer softIrqId = ((Long) event.getContent().getField(LttngStrings.VEC).getValue()).intValue(); |
79e0a1df AM |
199 | |
200 | /* Put this SoftIRQ back to inactive (= -1) in the resource tree */ | |
6383e95d | 201 | quark = ss.getQuarkRelativeAndAdd(getNodeSoftIRQs(), softIrqId.toString()); |
79e0a1df AM |
202 | value = TmfStateValue.nullValue(); |
203 | ss.modifyAttribute(ts, value, quark); | |
204 | ||
205 | /* Set the previous process back to running */ | |
206 | setProcessToRunning(ts, currentThreadNode); | |
207 | ||
208 | /* Set the CPU status back to "busy" or "idle" */ | |
209 | cpuExitInterrupt(ts, currentCPUNode, currentThreadNode); | |
210 | } | |
211 | break; | |
212 | ||
3ae73cfa | 213 | case LttngStrings.SOFTIRQ_RAISE: |
79e0a1df AM |
214 | /* Fields: int32 vec */ |
215 | { | |
7a2f04a6 | 216 | Integer softIrqId = ((Long) event.getContent().getField(LttngStrings.VEC).getValue()).intValue(); |
79e0a1df AM |
217 | |
218 | /* Mark this SoftIRQ as *raised* in the resource tree. | |
219 | * State value = -2 */ | |
6383e95d | 220 | quark = ss.getQuarkRelativeAndAdd(getNodeSoftIRQs(), softIrqId.toString()); |
dfb27cee | 221 | value = StateValues.SOFT_IRQ_RAISED_VALUE; |
79e0a1df AM |
222 | ss.modifyAttribute(ts, value, quark); |
223 | } | |
224 | break; | |
225 | ||
3ae73cfa | 226 | case LttngStrings.SCHED_SWITCH: |
79e0a1df AM |
227 | /* |
228 | * Fields: string prev_comm, int32 prev_tid, int32 prev_prio, int64 prev_state, | |
229 | * string next_comm, int32 next_tid, int32 next_prio | |
230 | */ | |
231 | { | |
7a2f04a6 | 232 | ITmfEventField content = event.getContent(); |
79e0a1df | 233 | Integer prevTid = ((Long) content.getField(LttngStrings.PREV_TID).getValue()).intValue(); |
f2338178 | 234 | Long prevState = (Long) content.getField(LttngStrings.PREV_STATE).getValue(); |
79e0a1df AM |
235 | String nextProcessName = (String) content.getField(LttngStrings.NEXT_COMM).getValue(); |
236 | Integer nextTid = ((Long) content.getField(LttngStrings.NEXT_TID).getValue()).intValue(); | |
237 | ||
6383e95d AM |
238 | Integer formerThreadNode = ss.getQuarkRelativeAndAdd(getNodeThreads(), prevTid.toString()); |
239 | Integer newCurrentThreadNode = ss.getQuarkRelativeAndAdd(getNodeThreads(), nextTid.toString()); | |
79e0a1df AM |
240 | |
241 | /* Set the status of the process that got scheduled out. */ | |
242 | quark = ss.getQuarkRelativeAndAdd(formerThreadNode, Attributes.STATUS); | |
f2338178 | 243 | if (prevState != 0) { |
dfb27cee | 244 | value = StateValues.PROCESS_STATUS_WAIT_BLOCKED_VALUE; |
f2338178 | 245 | } else { |
dfb27cee | 246 | value = StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE; |
f2338178 | 247 | } |
79e0a1df AM |
248 | ss.modifyAttribute(ts, value, quark); |
249 | ||
250 | /* Set the status of the new scheduled process */ | |
251 | setProcessToRunning(ts, newCurrentThreadNode); | |
252 | ||
253 | /* Set the exec name of the new process */ | |
254 | quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.EXEC_NAME); | |
255 | value = TmfStateValue.newValueString(nextProcessName); | |
256 | ss.modifyAttribute(ts, value, quark); | |
257 | ||
25e43749 AM |
258 | /* Make sure the PPID and system_call sub-attributes exist */ |
259 | ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.SYSTEM_CALL); | |
260 | ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.PPID); | |
79e0a1df AM |
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()) { | |
dfb27cee | 272 | value = StateValues.CPU_STATUS_RUN_USERMODE_VALUE; |
79e0a1df | 273 | } else { |
dfb27cee | 274 | value = StateValues.CPU_STATUS_RUN_SYSCALL_VALUE; |
79e0a1df AM |
275 | } |
276 | } else { | |
dfb27cee | 277 | value = StateValues.CPU_STATUS_IDLE_VALUE; |
79e0a1df AM |
278 | } |
279 | quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS); | |
280 | ss.modifyAttribute(ts, value, quark); | |
281 | } | |
282 | break; | |
283 | ||
3ae73cfa | 284 | case LttngStrings.SCHED_PROCESS_FORK: |
79e0a1df AM |
285 | /* Fields: string parent_comm, int32 parent_tid, |
286 | * string child_comm, int32 child_tid */ | |
287 | { | |
7a2f04a6 | 288 | ITmfEventField content = event.getContent(); |
79e0a1df AM |
289 | // String parentProcessName = (String) event.getFieldValue("parent_comm"); |
290 | String childProcessName = (String) content.getField(LttngStrings.CHILD_COMM).getValue(); | |
291 | // assert ( parentProcessName.equals(childProcessName) ); | |
292 | ||
293 | Integer parentTid = ((Long) content.getField(LttngStrings.PARENT_TID).getValue()).intValue(); | |
294 | Integer childTid = ((Long) content.getField(LttngStrings.CHILD_TID).getValue()).intValue(); | |
295 | ||
6383e95d AM |
296 | Integer parentTidNode = ss.getQuarkRelativeAndAdd(getNodeThreads(), parentTid.toString()); |
297 | Integer childTidNode = ss.getQuarkRelativeAndAdd(getNodeThreads(), childTid.toString()); | |
79e0a1df AM |
298 | |
299 | /* Assign the PPID to the new process */ | |
300 | quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.PPID); | |
301 | value = TmfStateValue.newValueInt(parentTid); | |
302 | ss.modifyAttribute(ts, value, quark); | |
303 | ||
304 | /* Set the new process' exec_name */ | |
305 | quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.EXEC_NAME); | |
306 | value = TmfStateValue.newValueString(childProcessName); | |
307 | ss.modifyAttribute(ts, value, quark); | |
308 | ||
309 | /* Set the new process' status */ | |
310 | quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.STATUS); | |
dfb27cee | 311 | value = StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE; |
79e0a1df AM |
312 | ss.modifyAttribute(ts, value, quark); |
313 | ||
314 | /* Set the process' syscall name, to be the same as the parent's */ | |
315 | quark = ss.getQuarkRelativeAndAdd(parentTidNode, Attributes.SYSTEM_CALL); | |
316 | value = ss.queryOngoingState(quark); | |
b46ea93c AM |
317 | if (value.isNull()) { |
318 | /* | |
319 | * Maybe we were missing info about the parent? At least we | |
320 | * will set the child right. Let's suppose "sys_clone". | |
321 | */ | |
322 | value = TmfStateValue.newValueString(LttngStrings.SYS_CLONE); | |
323 | } | |
79e0a1df AM |
324 | quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.SYSTEM_CALL); |
325 | ss.modifyAttribute(ts, value, quark); | |
326 | } | |
327 | break; | |
328 | ||
3ae73cfa | 329 | case LttngStrings.SCHED_PROCESS_EXIT: |
79e0a1df AM |
330 | /* Fields: string comm, int32 tid, int32 prio */ |
331 | break; | |
332 | ||
3ae73cfa | 333 | case LttngStrings.SCHED_PROCESS_FREE: |
79e0a1df AM |
334 | /* Fields: string comm, int32 tid, int32 prio */ |
335 | /* | |
336 | * A sched_process_free will always happen after the sched_switch | |
337 | * that will remove the process from the cpu for the last time. So | |
338 | * this is when we should delete everything wrt to the process. | |
339 | */ | |
340 | { | |
7a2f04a6 | 341 | Integer tid = ((Long) event.getContent().getField(LttngStrings.TID).getValue()).intValue(); |
79e0a1df AM |
342 | /* |
343 | * Remove the process and all its sub-attributes from the | |
344 | * current state | |
345 | */ | |
6383e95d | 346 | quark = ss.getQuarkRelativeAndAdd(getNodeThreads(), tid.toString()); |
79e0a1df AM |
347 | ss.removeAttribute(ts, quark); |
348 | } | |
349 | break; | |
350 | ||
3ae73cfa | 351 | case LttngStrings.STATEDUMP_PROCESS_STATE: |
79e0a1df AM |
352 | /* Fields: |
353 | * int32 type, int32 mode, int32 pid, int32 submode, int32 vpid, | |
354 | * int32 ppid, int32 tid, string name, int32 status, int32 vtid */ | |
355 | { | |
7a2f04a6 | 356 | ITmfEventField content = event.getContent(); |
bc19bff3 AM |
357 | int tid = ((Long) content.getField(LttngStrings.TID).getValue()).intValue(); |
358 | int pid = ((Long) content.getField(LttngStrings.PID).getValue()).intValue(); | |
79e0a1df AM |
359 | int ppid = ((Long) content.getField(LttngStrings.PPID).getValue()).intValue(); |
360 | int status = ((Long) content.getField(LttngStrings.STATUS).getValue()).intValue(); | |
361 | String name = (String) content.getField(LttngStrings.NAME).getValue(); | |
362 | /* | |
363 | * "mode" could be interesting too, but it doesn't seem to be | |
364 | * populated with anything relevant for now. | |
365 | */ | |
366 | ||
bc19bff3 | 367 | int curThreadNode = ss.getQuarkRelativeAndAdd(getNodeThreads(), String.valueOf(tid)); |
79e0a1df AM |
368 | |
369 | /* Set the process' name */ | |
370 | quark = ss.getQuarkRelativeAndAdd(curThreadNode, Attributes.EXEC_NAME); | |
371 | if (ss.queryOngoingState(quark).isNull()) { | |
372 | /* If the value didn't exist previously, set it */ | |
373 | value = TmfStateValue.newValueString(name); | |
374 | ss.modifyAttribute(ts, value, quark); | |
375 | } | |
376 | ||
377 | /* Set the process' PPID */ | |
378 | quark = ss.getQuarkRelativeAndAdd(curThreadNode, Attributes.PPID); | |
379 | if (ss.queryOngoingState(quark).isNull()) { | |
bc19bff3 AM |
380 | if (pid == tid) { |
381 | /* We have a process. Use the 'PPID' field. */ | |
382 | value = TmfStateValue.newValueInt(ppid); | |
383 | } else { | |
384 | /* We have a thread, use the 'PID' field for the parent. */ | |
385 | value = TmfStateValue.newValueInt(pid); | |
386 | } | |
79e0a1df AM |
387 | ss.modifyAttribute(ts, value, quark); |
388 | } | |
389 | ||
390 | /* Set the process' status */ | |
391 | quark = ss.getQuarkRelativeAndAdd(curThreadNode, Attributes.STATUS); | |
392 | if (ss.queryOngoingState(quark).isNull()) { | |
f2338178 MD |
393 | /* "2" here means "WAIT_FOR_CPU", and "5" "WAIT_BLOCKED" in the LTTng kernel. */ |
394 | if (status == 2) { | |
dfb27cee | 395 | value = StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE; |
f2338178 | 396 | } else if (status == 5) { |
dfb27cee | 397 | value = StateValues.PROCESS_STATUS_WAIT_BLOCKED_VALUE; |
79e0a1df | 398 | } else { |
dfb27cee | 399 | value = StateValues.PROCESS_STATUS_UNKNOWN_VALUE; |
79e0a1df AM |
400 | } |
401 | ss.modifyAttribute(ts, value, quark); | |
402 | } | |
403 | } | |
404 | break; | |
405 | ||
3ae73cfa AM |
406 | case LttngStrings.SCHED_WAKEUP: |
407 | case LttngStrings.SCHED_WAKEUP_NEW: | |
d1b933e7 AM |
408 | /* Fields (same fields for both types): |
409 | * string comm, int32 pid, int32 prio, int32 success, | |
410 | * int32 target_cpu */ | |
411 | { | |
7a2f04a6 | 412 | final int tid = ((Long) event.getContent().getField(LttngStrings.TID).getValue()).intValue(); |
d1b933e7 AM |
413 | final int threadNode = ss.getQuarkRelativeAndAdd(getNodeThreads(), String.valueOf(tid)); |
414 | ||
415 | /* | |
416 | * The process indicated in the event's payload is now ready to | |
3d6e6112 FR |
417 | * run. Assign it to the "wait for cpu" state, but only if it |
418 | * was not already running. | |
d1b933e7 AM |
419 | */ |
420 | quark = ss.getQuarkRelativeAndAdd(threadNode, Attributes.STATUS); | |
3d6e6112 FR |
421 | int status = ss.queryOngoingState(quark).unboxInt(); |
422 | ||
423 | if (status != StateValues.PROCESS_STATUS_RUN_SYSCALL && | |
424 | status != StateValues.PROCESS_STATUS_RUN_USERMODE) { | |
425 | value = StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE; | |
426 | ss.modifyAttribute(ts, value, quark); | |
427 | } | |
d1b933e7 AM |
428 | } |
429 | break; | |
430 | ||
79e0a1df AM |
431 | default: |
432 | /* Other event types not covered by the main switch */ | |
433 | { | |
434 | if (eventName.startsWith(LttngStrings.SYSCALL_PREFIX) | |
435 | || eventName.startsWith(LttngStrings.COMPAT_SYSCALL_PREFIX)) { | |
436 | /* | |
437 | * This is a replacement for the old sys_enter event. Now | |
438 | * syscall names are listed into the event type | |
439 | */ | |
440 | ||
441 | /* Assign the new system call to the process */ | |
442 | quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL); | |
443 | value = TmfStateValue.newValueString(eventName); | |
444 | ss.modifyAttribute(ts, value, quark); | |
445 | ||
446 | /* Put the process in system call mode */ | |
447 | quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS); | |
dfb27cee | 448 | value = StateValues.PROCESS_STATUS_RUN_SYSCALL_VALUE; |
79e0a1df AM |
449 | ss.modifyAttribute(ts, value, quark); |
450 | ||
451 | /* Put the CPU in system call (kernel) mode */ | |
452 | quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS); | |
dfb27cee | 453 | value = StateValues.CPU_STATUS_RUN_SYSCALL_VALUE; |
79e0a1df AM |
454 | ss.modifyAttribute(ts, value, quark); |
455 | } | |
456 | } | |
457 | break; | |
458 | } // End of big switch | |
459 | ||
79e0a1df AM |
460 | } catch (AttributeNotFoundException ae) { |
461 | /* | |
462 | * This would indicate a problem with the logic of the manager here, | |
463 | * so it shouldn't happen. | |
464 | */ | |
465 | ae.printStackTrace(); | |
466 | ||
467 | } catch (TimeRangeException tre) { | |
468 | /* | |
469 | * This would happen if the events in the trace aren't ordered | |
470 | * chronologically, which should never be the case ... | |
471 | */ | |
472 | System.err.println("TimeRangeExcpetion caught in the state system's event manager."); //$NON-NLS-1$ | |
473 | System.err.println("Are the events in the trace correctly ordered?"); //$NON-NLS-1$ | |
474 | tre.printStackTrace(); | |
475 | ||
476 | } catch (StateValueTypeException sve) { | |
477 | /* | |
478 | * This would happen if we were trying to push/pop attributes not of | |
479 | * type integer. Which, once again, should never happen. | |
480 | */ | |
481 | sve.printStackTrace(); | |
2c2f900e AM |
482 | } |
483 | } | |
484 | ||
6383e95d AM |
485 | // ------------------------------------------------------------------------ |
486 | // Convenience methods for commonly-used attribute tree locations | |
487 | // ------------------------------------------------------------------------ | |
488 | ||
489 | private int getNodeCPUs() { | |
490 | return ss.getQuarkAbsoluteAndAdd(Attributes.CPUS); | |
79e0a1df AM |
491 | } |
492 | ||
6383e95d AM |
493 | private int getNodeThreads() { |
494 | return ss.getQuarkAbsoluteAndAdd(Attributes.THREADS); | |
495 | } | |
496 | ||
497 | private int getNodeIRQs() { | |
498 | return ss.getQuarkAbsoluteAndAdd(Attributes.RESOURCES, Attributes.IRQS); | |
499 | } | |
500 | ||
501 | private int getNodeSoftIRQs() { | |
502 | return ss.getQuarkAbsoluteAndAdd(Attributes.RESOURCES, Attributes.SOFT_IRQS); | |
503 | } | |
504 | ||
6383e95d AM |
505 | // ------------------------------------------------------------------------ |
506 | // Advanced state-setting methods | |
507 | // ------------------------------------------------------------------------ | |
508 | ||
79e0a1df AM |
509 | /** |
510 | * When we want to set a process back to a "running" state, first check | |
511 | * its current System_call attribute. If there is a system call active, we | |
512 | * put the process back in the syscall state. If not, we put it back in | |
513 | * user mode state. | |
514 | */ | |
515 | private void setProcessToRunning(long ts, int currentThreadNode) | |
516 | throws AttributeNotFoundException, TimeRangeException, | |
517 | StateValueTypeException { | |
518 | int quark; | |
519 | ITmfStateValue value; | |
520 | ||
521 | quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL); | |
522 | if (ss.queryOngoingState(quark).isNull()) { | |
523 | /* We were in user mode before the interruption */ | |
dfb27cee | 524 | value = StateValues.PROCESS_STATUS_RUN_USERMODE_VALUE; |
79e0a1df AM |
525 | } else { |
526 | /* We were previously in kernel mode */ | |
dfb27cee | 527 | value = StateValues.PROCESS_STATUS_RUN_SYSCALL_VALUE; |
79e0a1df AM |
528 | } |
529 | quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS); | |
530 | ss.modifyAttribute(ts, value, quark); | |
531 | } | |
532 | ||
533 | /** | |
534 | * Similar logic as above, but to set the CPU's status when it's coming out | |
535 | * of an interruption. | |
536 | */ | |
537 | private void cpuExitInterrupt(long ts, int currentCpuNode, int currentThreadNode) | |
538 | throws StateValueTypeException, AttributeNotFoundException, | |
539 | TimeRangeException { | |
540 | int quark; | |
541 | ITmfStateValue value; | |
542 | ||
543 | quark = ss.getQuarkRelativeAndAdd(currentCpuNode, Attributes.CURRENT_THREAD); | |
544 | if (ss.queryOngoingState(quark).unboxInt() > 0) { | |
545 | /* There was a process on the CPU */ | |
546 | quark = ss.getQuarkRelative(currentThreadNode, Attributes.SYSTEM_CALL); | |
547 | if (ss.queryOngoingState(quark).isNull()) { | |
548 | /* That process was in user mode */ | |
dfb27cee | 549 | value = StateValues.CPU_STATUS_RUN_USERMODE_VALUE; |
79e0a1df AM |
550 | } else { |
551 | /* That process was in a system call */ | |
dfb27cee | 552 | value = StateValues.CPU_STATUS_RUN_SYSCALL_VALUE; |
79e0a1df AM |
553 | } |
554 | } else { | |
555 | /* There was no real process scheduled, CPU was idle */ | |
dfb27cee | 556 | value = StateValues.CPU_STATUS_IDLE_VALUE; |
2c2f900e | 557 | } |
79e0a1df AM |
558 | quark = ss.getQuarkRelativeAndAdd(currentCpuNode, Attributes.STATUS); |
559 | ss.modifyAttribute(ts, value, quark); | |
efc403bb AM |
560 | } |
561 | } |