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>
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
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.internal
.lttng2
.kernel
.core
.stateprovider
;
15 import java
.util
.HashMap
;
17 import org
.eclipse
.linuxtools
.internal
.lttng2
.kernel
.core
.Attributes
;
18 import org
.eclipse
.linuxtools
.internal
.lttng2
.kernel
.core
.LttngStrings
;
19 import org
.eclipse
.linuxtools
.internal
.lttng2
.kernel
.core
.StateValues
;
20 import org
.eclipse
.linuxtools
.tmf
.core
.ctfadaptor
.CtfTmfEvent
;
21 import org
.eclipse
.linuxtools
.tmf
.core
.ctfadaptor
.CtfTmfTrace
;
22 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
23 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEventField
;
24 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.AttributeNotFoundException
;
25 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.StateValueTypeException
;
26 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.TimeRangeException
;
27 import org
.eclipse
.linuxtools
.tmf
.core
.statesystem
.AbstractStateChangeInput
;
28 import org
.eclipse
.linuxtools
.tmf
.core
.statesystem
.ITmfStateSystemBuilder
;
29 import org
.eclipse
.linuxtools
.tmf
.core
.statevalue
.ITmfStateValue
;
30 import org
.eclipse
.linuxtools
.tmf
.core
.statevalue
.TmfStateValue
;
33 * This is the state change input plugin for TMF's state system which handles
34 * the LTTng 2.0 kernel traces in CTF format.
36 * It uses the reference handler defined in CTFKernelHandler.java.
41 public class CtfKernelStateInput
extends AbstractStateChangeInput
{
44 * Version number of this state provider. Please bump this if you modify the
45 * contents of the generated state history in some way.
47 private static final int VERSION
= 0;
49 /* Event names HashMap. TODO: This can be discarded once we move to Java 7 */
50 private final HashMap
<String
, Integer
> knownEventNames
;
52 /* Common locations in the attribute tree */
53 private int cpusNode
= -1;
54 private int threadsNode
= -1;
55 private int irqsNode
= -1;
56 private int softIrqsNode
= -1;
60 * Instantiate a new state provider plugin.
63 * The LTTng 2.0 kernel trace directory
65 public CtfKernelStateInput(CtfTmfTrace trace
) {
66 super(trace
, CtfTmfEvent
.class, "LTTng Kernel"); //$NON-NLS-1$
67 knownEventNames
= fillEventNames();
71 public int getVersion() {
76 public void assignTargetStateSystem(ITmfStateSystemBuilder ssb
) {
77 /* We can only set up the locations once the state system is assigned */
78 super.assignTargetStateSystem(ssb
);
79 setupCommonLocations();
83 protected void eventHandle(ITmfEvent ev
) {
85 * AbstractStateChangeInput should have already checked for the correct
88 CtfTmfEvent event
= (CtfTmfEvent
) ev
;
93 final ITmfEventField content
= event
.getContent();
94 final String eventName
= event
.getEventName();
95 final long ts
= event
.getTimestamp().getValue();
98 /* Shortcut for the "current CPU" attribute node */
99 final Integer currentCPUNode
= ss
.getQuarkRelativeAndAdd(cpusNode
, String
.valueOf(event
.getCPU()));
102 * Shortcut for the "current thread" attribute node. It requires
103 * querying the current CPU's current thread.
105 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.CURRENT_THREAD
);
106 value
= ss
.queryOngoingState(quark
);
107 int thread
= value
.unboxInt();
108 final Integer currentThreadNode
= ss
.getQuarkRelativeAndAdd(threadsNode
, String
.valueOf(thread
));
111 * Feed event to the history system if it's known to cause a state
114 switch (getEventIndex(eventName
)) {
116 case 1: // "exit_syscall":
117 /* Fields: int64 ret */
119 /* Clear the current system call on the process */
120 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.SYSTEM_CALL
);
121 value
= TmfStateValue
.nullValue();
122 ss
.modifyAttribute(ts
, value
, quark
);
124 /* Put the process' status back to user mode */
125 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.STATUS
);
126 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_RUN_USERMODE
);
127 ss
.modifyAttribute(ts
, value
, quark
);
129 /* Put the CPU's status back to user mode */
130 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.STATUS
);
131 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_RUN_USERMODE
);
132 ss
.modifyAttribute(ts
, value
, quark
);
136 case 2: // "irq_handler_entry":
137 /* Fields: int32 irq, string name */
139 Integer irqId
= ((Long
) content
.getField(LttngStrings
.IRQ
).getValue()).intValue();
141 /* Mark this IRQ as active in the resource tree.
142 * The state value = the CPU on which this IRQ is sitting */
143 quark
= ss
.getQuarkRelativeAndAdd(irqsNode
, irqId
.toString());
144 value
= TmfStateValue
.newValueInt(event
.getCPU());
145 ss
.modifyAttribute(ts
, value
, quark
);
147 /* Change the status of the running process to interrupted */
148 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.STATUS
);
149 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_INTERRUPTED
);
150 ss
.modifyAttribute(ts
, value
, quark
);
152 /* Change the status of the CPU to interrupted */
153 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.STATUS
);
154 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_IRQ
);
155 ss
.modifyAttribute(ts
, value
, quark
);
159 case 3: // "irq_handler_exit":
160 /* Fields: int32 irq, int32 ret */
162 Integer irqId
= ((Long
) content
.getField(LttngStrings
.IRQ
).getValue()).intValue();
164 /* Put this IRQ back to inactive in the resource tree */
165 quark
= ss
.getQuarkRelativeAndAdd(irqsNode
, irqId
.toString());
166 value
= TmfStateValue
.nullValue();
167 ss
.modifyAttribute(ts
, value
, quark
);
169 /* Set the previous process back to running */
170 setProcessToRunning(ts
, currentThreadNode
);
172 /* Set the CPU status back to running or "idle" */
173 cpuExitInterrupt(ts
, currentCPUNode
, currentThreadNode
);
177 case 4: // "softirq_entry":
178 /* Fields: int32 vec */
180 Integer softIrqId
= ((Long
) content
.getField(LttngStrings
.VEC
).getValue()).intValue();
182 /* Mark this SoftIRQ as active in the resource tree.
183 * The state value = the CPU on which this SoftIRQ is processed */
184 quark
= ss
.getQuarkRelativeAndAdd(softIrqsNode
, softIrqId
.toString());
185 value
= TmfStateValue
.newValueInt(event
.getCPU());
186 ss
.modifyAttribute(ts
, value
, quark
);
188 /* Change the status of the running process to interrupted */
189 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.STATUS
);
190 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_INTERRUPTED
);
191 ss
.modifyAttribute(ts
, value
, quark
);
193 /* Change the status of the CPU to interrupted */
194 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.STATUS
);
195 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_SOFTIRQ
);
196 ss
.modifyAttribute(ts
, value
, quark
);
200 case 5: // "softirq_exit":
201 /* Fields: int32 vec */
203 Integer softIrqId
= ((Long
) content
.getField(LttngStrings
.VEC
).getValue()).intValue();
205 /* Put this SoftIRQ back to inactive (= -1) in the resource tree */
206 quark
= ss
.getQuarkRelativeAndAdd(softIrqsNode
, softIrqId
.toString());
207 value
= TmfStateValue
.nullValue();
208 ss
.modifyAttribute(ts
, value
, quark
);
210 /* Set the previous process back to running */
211 setProcessToRunning(ts
, currentThreadNode
);
213 /* Set the CPU status back to "busy" or "idle" */
214 cpuExitInterrupt(ts
, currentCPUNode
, currentThreadNode
);
218 case 6: // "softirq_raise":
219 /* Fields: int32 vec */
221 Integer softIrqId
= ((Long
) content
.getField(LttngStrings
.VEC
).getValue()).intValue();
223 /* Mark this SoftIRQ as *raised* in the resource tree.
224 * State value = -2 */
225 quark
= ss
.getQuarkRelativeAndAdd(softIrqsNode
, softIrqId
.toString());
226 value
= TmfStateValue
.newValueInt(StateValues
.SOFT_IRQ_RAISED
);
227 ss
.modifyAttribute(ts
, value
, quark
);
231 case 7: // "sched_switch":
233 * Fields: string prev_comm, int32 prev_tid, int32 prev_prio, int64 prev_state,
234 * string next_comm, int32 next_tid, int32 next_prio
237 Integer prevTid
= ((Long
) content
.getField(LttngStrings
.PREV_TID
).getValue()).intValue();
238 Long prevState
= (Long
) content
.getField(LttngStrings
.PREV_STATE
).getValue();
239 String nextProcessName
= (String
) content
.getField(LttngStrings
.NEXT_COMM
).getValue();
240 Integer nextTid
= ((Long
) content
.getField(LttngStrings
.NEXT_TID
).getValue()).intValue();
242 Integer formerThreadNode
= ss
.getQuarkRelativeAndAdd(threadsNode
, prevTid
.toString());
243 Integer newCurrentThreadNode
= ss
.getQuarkRelativeAndAdd(threadsNode
, nextTid
.toString());
245 /* Set the status of the process that got scheduled out. */
246 quark
= ss
.getQuarkRelativeAndAdd(formerThreadNode
, Attributes
.STATUS
);
247 if (prevState
!= 0) {
248 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_WAIT_BLOCKED
);
250 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_WAIT_FOR_CPU
);
252 ss
.modifyAttribute(ts
, value
, quark
);
254 /* Set the status of the new scheduled process */
255 setProcessToRunning(ts
, newCurrentThreadNode
);
257 /* Set the exec name of the new process */
258 quark
= ss
.getQuarkRelativeAndAdd(newCurrentThreadNode
, Attributes
.EXEC_NAME
);
259 value
= TmfStateValue
.newValueString(nextProcessName
);
260 ss
.modifyAttribute(ts
, value
, quark
);
263 * Check if we need to set the syscall state and the PPID of
264 * the new process (in case we haven't seen this process before)
266 quark
= ss
.getQuarkRelativeAndAdd(newCurrentThreadNode
, Attributes
.SYSTEM_CALL
);
267 if (ss
.isLastAttribute(quark
)) { /* Did we just add this attribute? */
268 value
= TmfStateValue
.nullValue();
269 ss
.modifyAttribute(ts
, value
, quark
);
271 quark
= ss
.getQuarkRelativeAndAdd(newCurrentThreadNode
, Attributes
.PPID
);
272 if (ss
.isLastAttribute(quark
)) {
273 value
= TmfStateValue
.nullValue();
274 ss
.modifyAttribute(ts
, value
, quark
);
277 /* Set the current scheduled process on the relevant CPU */
278 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.CURRENT_THREAD
);
279 value
= TmfStateValue
.newValueInt(nextTid
);
280 ss
.modifyAttribute(ts
, value
, quark
);
282 /* Set the status of the CPU itself */
284 /* Check if the entering process is in kernel or user mode */
285 quark
= ss
.getQuarkRelativeAndAdd(newCurrentThreadNode
, Attributes
.SYSTEM_CALL
);
286 if (ss
.queryOngoingState(quark
).isNull()) {
287 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_RUN_USERMODE
);
289 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_RUN_SYSCALL
);
292 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_IDLE
);
294 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.STATUS
);
295 ss
.modifyAttribute(ts
, value
, quark
);
299 case 8: // "sched_process_fork":
300 /* Fields: string parent_comm, int32 parent_tid,
301 * string child_comm, int32 child_tid */
303 // String parentProcessName = (String) event.getFieldValue("parent_comm");
304 String childProcessName
= (String
) content
.getField(LttngStrings
.CHILD_COMM
).getValue();
305 // assert ( parentProcessName.equals(childProcessName) );
307 Integer parentTid
= ((Long
) content
.getField(LttngStrings
.PARENT_TID
).getValue()).intValue();
308 Integer childTid
= ((Long
) content
.getField(LttngStrings
.CHILD_TID
).getValue()).intValue();
310 Integer parentTidNode
= ss
.getQuarkRelativeAndAdd(threadsNode
, parentTid
.toString());
311 Integer childTidNode
= ss
.getQuarkRelativeAndAdd(threadsNode
, childTid
.toString());
313 /* Assign the PPID to the new process */
314 quark
= ss
.getQuarkRelativeAndAdd(childTidNode
, Attributes
.PPID
);
315 value
= TmfStateValue
.newValueInt(parentTid
);
316 ss
.modifyAttribute(ts
, value
, quark
);
318 /* Set the new process' exec_name */
319 quark
= ss
.getQuarkRelativeAndAdd(childTidNode
, Attributes
.EXEC_NAME
);
320 value
= TmfStateValue
.newValueString(childProcessName
);
321 ss
.modifyAttribute(ts
, value
, quark
);
323 /* Set the new process' status */
324 quark
= ss
.getQuarkRelativeAndAdd(childTidNode
, Attributes
.STATUS
);
325 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_WAIT_FOR_CPU
);
326 ss
.modifyAttribute(ts
, value
, quark
);
328 /* Set the process' syscall name, to be the same as the parent's */
329 quark
= ss
.getQuarkRelativeAndAdd(parentTidNode
, Attributes
.SYSTEM_CALL
);
330 value
= ss
.queryOngoingState(quark
);
331 quark
= ss
.getQuarkRelativeAndAdd(childTidNode
, Attributes
.SYSTEM_CALL
);
332 ss
.modifyAttribute(ts
, value
, quark
);
336 case 9: // "sched_process_exit":
337 /* Fields: string comm, int32 tid, int32 prio */
340 case 10: // "sched_process_free":
341 /* Fields: string comm, int32 tid, int32 prio */
343 * A sched_process_free will always happen after the sched_switch
344 * that will remove the process from the cpu for the last time. So
345 * this is when we should delete everything wrt to the process.
348 Integer tid
= ((Long
) content
.getField(LttngStrings
.TID
).getValue()).intValue();
350 * Remove the process and all its sub-attributes from the
353 quark
= ss
.getQuarkRelativeAndAdd(threadsNode
, tid
.toString());
354 ss
.removeAttribute(ts
, quark
);
358 case 11: // "lttng_statedump_process_state":
360 * int32 type, int32 mode, int32 pid, int32 submode, int32 vpid,
361 * int32 ppid, int32 tid, string name, int32 status, int32 vtid */
363 Integer tid
= ((Long
) content
.getField(LttngStrings
.TID
).getValue()).intValue();
364 int ppid
= ((Long
) content
.getField(LttngStrings
.PPID
).getValue()).intValue();
365 int status
= ((Long
) content
.getField(LttngStrings
.STATUS
).getValue()).intValue();
366 String name
= (String
) content
.getField(LttngStrings
.NAME
).getValue();
368 * "mode" could be interesting too, but it doesn't seem to be
369 * populated with anything relevant for now.
372 int curThreadNode
= ss
.getQuarkRelativeAndAdd(threadsNode
, tid
.toString());
374 /* Set the process' name */
375 quark
= ss
.getQuarkRelativeAndAdd(curThreadNode
, Attributes
.EXEC_NAME
);
376 if (ss
.queryOngoingState(quark
).isNull()) {
377 /* If the value didn't exist previously, set it */
378 value
= TmfStateValue
.newValueString(name
);
379 ss
.modifyAttribute(ts
, value
, quark
);
382 /* Set the process' PPID */
383 quark
= ss
.getQuarkRelativeAndAdd(curThreadNode
, Attributes
.PPID
);
384 if (ss
.queryOngoingState(quark
).isNull()) {
385 value
= TmfStateValue
.newValueInt(ppid
);
386 ss
.modifyAttribute(ts
, value
, quark
);
389 /* Set the process' status */
390 quark
= ss
.getQuarkRelativeAndAdd(curThreadNode
, Attributes
.STATUS
);
391 if (ss
.queryOngoingState(quark
).isNull()) {
392 /* "2" here means "WAIT_FOR_CPU", and "5" "WAIT_BLOCKED" in the LTTng kernel. */
394 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_WAIT_FOR_CPU
);
395 } else if (status
== 5) {
396 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_WAIT_BLOCKED
);
398 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_UNKNOWN
);
400 ss
.modifyAttribute(ts
, value
, quark
);
406 /* Other event types not covered by the main switch */
408 if (eventName
.startsWith(LttngStrings
.SYSCALL_PREFIX
)
409 || eventName
.startsWith(LttngStrings
.COMPAT_SYSCALL_PREFIX
)) {
411 * This is a replacement for the old sys_enter event. Now
412 * syscall names are listed into the event type
415 /* Assign the new system call to the process */
416 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.SYSTEM_CALL
);
417 value
= TmfStateValue
.newValueString(eventName
);
418 ss
.modifyAttribute(ts
, value
, quark
);
420 /* Put the process in system call mode */
421 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.STATUS
);
422 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_RUN_SYSCALL
);
423 ss
.modifyAttribute(ts
, value
, quark
);
425 /* Put the CPU in system call (kernel) mode */
426 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.STATUS
);
427 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_RUN_SYSCALL
);
428 ss
.modifyAttribute(ts
, value
, quark
);
432 } // End of big switch
438 /* Number of events of each type, globally */
439 // quark = ss.getQuarkAbsoluteAndAdd(Attributes.STATISTICS,
440 // Attributes.EVENT_TYPES, eventName);
441 // ss.incrementAttribute(ts, quark);
443 /* Number of events per CPU */
444 // quark = ss.getQuarkRelativeAndAdd(currentCPUNode,
445 // Attributes.STATISTICS, Attributes.EVENT_TYPES, eventName);
446 // ss.incrementAttribute(ts, quark);
448 /* Number of events per process */
449 // quark = ss.getQuarkRelativeAndAdd(currentThreadNode,
450 // Attributes.STATISTICS, Attributes.EVENT_TYPES, eventName);
451 // ss.incrementAttribute(ts, quark);
453 } catch (AttributeNotFoundException ae
) {
455 * This would indicate a problem with the logic of the manager here,
456 * so it shouldn't happen.
458 ae
.printStackTrace();
460 } catch (TimeRangeException tre
) {
462 * This would happen if the events in the trace aren't ordered
463 * chronologically, which should never be the case ...
465 System
.err
.println("TimeRangeExcpetion caught in the state system's event manager."); //$NON-NLS-1$
466 System
.err
.println("Are the events in the trace correctly ordered?"); //$NON-NLS-1$
467 tre
.printStackTrace();
469 } catch (StateValueTypeException sve
) {
471 * This would happen if we were trying to push/pop attributes not of
472 * type integer. Which, once again, should never happen.
474 sve
.printStackTrace();
478 private void setupCommonLocations() {
479 cpusNode
= ss
.getQuarkAbsoluteAndAdd(Attributes
.CPUS
);
480 threadsNode
= ss
.getQuarkAbsoluteAndAdd(Attributes
.THREADS
);
481 irqsNode
= ss
.getQuarkAbsoluteAndAdd(Attributes
.RESOURCES
, Attributes
.IRQS
);
482 softIrqsNode
= ss
.getQuarkAbsoluteAndAdd(Attributes
.RESOURCES
, Attributes
.SOFT_IRQS
);
485 private static HashMap
<String
, Integer
> fillEventNames() {
487 * TODO Replace with straight strings in the switch/case once we move to
490 HashMap
<String
, Integer
> map
= new HashMap
<String
, Integer
>();
492 map
.put(LttngStrings
.EXIT_SYSCALL
, 1);
493 map
.put(LttngStrings
.IRQ_HANDLER_ENTRY
, 2);
494 map
.put(LttngStrings
.IRQ_HANDLER_EXIT
, 3);
495 map
.put(LttngStrings
.SOFTIRQ_ENTRY
, 4);
496 map
.put(LttngStrings
.SOFTIRQ_EXIT
, 5);
497 map
.put(LttngStrings
.SOFTIRQ_RAISE
, 6);
498 map
.put(LttngStrings
.SCHED_SWITCH
, 7);
499 map
.put(LttngStrings
.SCHED_PROCESS_FORK
, 8);
500 map
.put(LttngStrings
.SCHED_PROCESS_EXIT
, 9);
501 map
.put(LttngStrings
.SCHED_PROCESS_FREE
, 10);
502 map
.put(LttngStrings
.STATEDUMP_PROCESS_STATE
, 11);
507 private int getEventIndex(String eventName
) {
508 Integer ret
= knownEventNames
.get(eventName
);
509 return (ret
!= null) ? ret
: -1;
513 * When we want to set a process back to a "running" state, first check
514 * its current System_call attribute. If there is a system call active, we
515 * put the process back in the syscall state. If not, we put it back in
518 private void setProcessToRunning(long ts
, int currentThreadNode
)
519 throws AttributeNotFoundException
, TimeRangeException
,
520 StateValueTypeException
{
522 ITmfStateValue value
;
524 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.SYSTEM_CALL
);
525 if (ss
.queryOngoingState(quark
).isNull()) {
526 /* We were in user mode before the interruption */
527 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_RUN_USERMODE
);
529 /* We were previously in kernel mode */
530 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_RUN_SYSCALL
);
532 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.STATUS
);
533 ss
.modifyAttribute(ts
, value
, quark
);
537 * Similar logic as above, but to set the CPU's status when it's coming out
538 * of an interruption.
540 private void cpuExitInterrupt(long ts
, int currentCpuNode
, int currentThreadNode
)
541 throws StateValueTypeException
, AttributeNotFoundException
,
544 ITmfStateValue value
;
546 quark
= ss
.getQuarkRelativeAndAdd(currentCpuNode
, Attributes
.CURRENT_THREAD
);
547 if (ss
.queryOngoingState(quark
).unboxInt() > 0) {
548 /* There was a process on the CPU */
549 quark
= ss
.getQuarkRelative(currentThreadNode
, Attributes
.SYSTEM_CALL
);
550 if (ss
.queryOngoingState(quark
).isNull()) {
551 /* That process was in user mode */
552 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_RUN_USERMODE
);
554 /* That process was in a system call */
555 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_RUN_SYSCALL
);
558 /* There was no real process scheduled, CPU was idle */
559 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_IDLE
);
561 quark
= ss
.getQuarkRelativeAndAdd(currentCpuNode
, Attributes
.STATUS
);
562 ss
.modifyAttribute(ts
, value
, quark
);