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
;
16 import java
.util
.concurrent
.BlockingQueue
;
18 import org
.eclipse
.linuxtools
.internal
.lttng2
.kernel
.core
.Attributes
;
19 import org
.eclipse
.linuxtools
.internal
.lttng2
.kernel
.core
.LttngStrings
;
20 import org
.eclipse
.linuxtools
.internal
.lttng2
.kernel
.core
.StateValues
;
21 import org
.eclipse
.linuxtools
.tmf
.core
.ctfadaptor
.CtfTmfEvent
;
22 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEventField
;
23 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.AttributeNotFoundException
;
24 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.StateValueTypeException
;
25 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.TimeRangeException
;
26 import org
.eclipse
.linuxtools
.tmf
.core
.statesystem
.IStateSystemBuilder
;
27 import org
.eclipse
.linuxtools
.tmf
.core
.statevalue
.ITmfStateValue
;
28 import org
.eclipse
.linuxtools
.tmf
.core
.statevalue
.TmfStateValue
;
31 * This is the reference "state provider" for LTTng 2.0 kernel traces.
36 class CtfKernelHandler
implements Runnable
{
38 private final BlockingQueue
<CtfTmfEvent
> inQueue
;
39 private IStateSystemBuilder ss
;
41 private CtfTmfEvent currentEvent
;
43 /* Event names HashMap. TODO: This can be discarded once we move to Java 7 */
44 private final HashMap
<String
, Integer
> knownEventNames
;
46 /* Common locations in the attribute tree */
47 private int cpusNode
= -1;
48 private int threadsNode
= -1;
49 private int irqsNode
= -1;
50 private int softIrqsNode
= -1;
52 CtfKernelHandler(BlockingQueue
<CtfTmfEvent
> eventsQueue
) {
53 assert (eventsQueue
!= null);
54 this.inQueue
= eventsQueue
;
56 knownEventNames
= fillEventNames();
59 void assignStateSystem(IStateSystemBuilder targetSS
) {
66 System
.err
.println("Cannot run event manager without assigning a target state system first!"); //$NON-NLS-1$
70 setupCommonLocations();
73 event
= inQueue
.take();
74 while (event
.getTimestampValue() != -1) {
76 event
= inQueue
.take();
78 /* We've received the last event, clean up */
81 } catch (InterruptedException e
) {
82 /* We've been interrupted abnormally */
83 System
.out
.println("Event handler interrupted!"); //$NON-NLS-1$
88 private void closeStateSystem() {
89 /* Close the History system, if there is one */
90 if (currentEvent
== null) {
94 ss
.closeHistory(currentEvent
.getTimestamp().getValue());
95 } catch (TimeRangeException e
) {
97 * Since we're using currentEvent.getTimestamp, this shouldn't
104 private void processEvent(CtfTmfEvent event
) {
106 ITmfStateValue value
;
108 currentEvent
= event
;
110 final ITmfEventField content
= event
.getContent();
111 final String eventName
= event
.getEventName();
112 final long ts
= event
.getTimestamp().getValue();
115 /* Shortcut for the "current CPU" attribute node */
116 final Integer currentCPUNode
= ss
.getQuarkRelativeAndAdd(cpusNode
, String
.valueOf(event
.getCPU()));
119 * Shortcut for the "current thread" attribute node. It requires
120 * querying the current CPU's current thread.
122 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.CURRENT_THREAD
);
123 value
= ss
.queryOngoingState(quark
);
124 int thread
= value
.unboxInt();
125 final Integer currentThreadNode
= ss
.getQuarkRelativeAndAdd(threadsNode
, String
.valueOf(thread
));
128 * Feed event to the history system if it's known to cause a state
131 switch (getEventIndex(eventName
)) {
133 case 1: // "exit_syscall":
134 /* Fields: int64 ret */
136 /* Clear the current system call on the process */
137 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.SYSTEM_CALL
);
138 value
= TmfStateValue
.nullValue();
139 ss
.modifyAttribute(ts
, value
, quark
);
141 /* Put the process' status back to user mode */
142 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.STATUS
);
143 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_RUN_USERMODE
);
144 ss
.modifyAttribute(ts
, value
, quark
);
146 /* Put the CPU's status back to user mode */
147 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.STATUS
);
148 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_RUN_USERMODE
);
149 ss
.modifyAttribute(ts
, value
, quark
);
153 case 2: // "irq_handler_entry":
154 /* Fields: int32 irq, string name */
156 Integer irqId
= ((Long
) content
.getField(LttngStrings
.IRQ
).getValue()).intValue();
158 /* Mark this IRQ as active in the resource tree.
159 * The state value = the CPU on which this IRQ is sitting */
160 quark
= ss
.getQuarkRelativeAndAdd(irqsNode
, irqId
.toString());
161 value
= TmfStateValue
.newValueInt(event
.getCPU());
162 ss
.modifyAttribute(ts
, value
, quark
);
164 /* Change the status of the running process to interrupted */
165 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.STATUS
);
166 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_INTERRUPTED
);
167 ss
.modifyAttribute(ts
, value
, quark
);
169 /* Change the status of the CPU to interrupted */
170 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.STATUS
);
171 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_IRQ
);
172 ss
.modifyAttribute(ts
, value
, quark
);
176 case 3: // "irq_handler_exit":
177 /* Fields: int32 irq, int32 ret */
179 Integer irqId
= ((Long
) content
.getField(LttngStrings
.IRQ
).getValue()).intValue();
181 /* Put this IRQ back to inactive in the resource tree */
182 quark
= ss
.getQuarkRelativeAndAdd(irqsNode
, irqId
.toString());
183 value
= TmfStateValue
.nullValue();
184 ss
.modifyAttribute(ts
, value
, quark
);
186 /* Set the previous process back to running */
187 setProcessToRunning(ts
, currentThreadNode
);
189 /* Set the CPU status back to running or "idle" */
190 cpuExitInterrupt(ts
, currentCPUNode
, currentThreadNode
);
194 case 4: // "softirq_entry":
195 /* Fields: int32 vec */
197 Integer softIrqId
= ((Long
) content
.getField(LttngStrings
.VEC
).getValue()).intValue();
199 /* Mark this SoftIRQ as active in the resource tree.
200 * The state value = the CPU on which this SoftIRQ is processed */
201 quark
= ss
.getQuarkRelativeAndAdd(softIrqsNode
, softIrqId
.toString());
202 value
= TmfStateValue
.newValueInt(event
.getCPU());
203 ss
.modifyAttribute(ts
, value
, quark
);
205 /* Change the status of the running process to interrupted */
206 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.STATUS
);
207 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_INTERRUPTED
);
208 ss
.modifyAttribute(ts
, value
, quark
);
210 /* Change the status of the CPU to interrupted */
211 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.STATUS
);
212 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_SOFTIRQ
);
213 ss
.modifyAttribute(ts
, value
, quark
);
217 case 5: // "softirq_exit":
218 /* Fields: int32 vec */
220 Integer softIrqId
= ((Long
) content
.getField(LttngStrings
.VEC
).getValue()).intValue();
222 /* Put this SoftIRQ back to inactive (= -1) in the resource tree */
223 quark
= ss
.getQuarkRelativeAndAdd(softIrqsNode
, softIrqId
.toString());
224 value
= TmfStateValue
.nullValue();
225 ss
.modifyAttribute(ts
, value
, quark
);
227 /* Set the previous process back to running */
228 setProcessToRunning(ts
, currentThreadNode
);
230 /* Set the CPU status back to "busy" or "idle" */
231 cpuExitInterrupt(ts
, currentCPUNode
, currentThreadNode
);
235 case 6: // "softirq_raise":
236 /* Fields: int32 vec */
238 Integer softIrqId
= ((Long
) content
.getField(LttngStrings
.VEC
).getValue()).intValue();
240 /* Mark this SoftIRQ as *raised* in the resource tree.
241 * State value = -2 */
242 quark
= ss
.getQuarkRelativeAndAdd(softIrqsNode
, softIrqId
.toString());
243 value
= TmfStateValue
.newValueInt(StateValues
.SOFT_IRQ_RAISED
);
244 ss
.modifyAttribute(ts
, value
, quark
);
248 case 7: // "sched_switch":
250 * Fields: string prev_comm, int32 prev_tid, int32 prev_prio, int64 prev_state,
251 * string next_comm, int32 next_tid, int32 next_prio
254 Integer prevTid
= ((Long
) content
.getField(LttngStrings
.PREV_TID
).getValue()).intValue();
255 //Long prevState = (Long) content.getField(LttngStrings.PREV_STATE).getValue();
256 String nextProcessName
= (String
) content
.getField(LttngStrings
.NEXT_COMM
).getValue();
257 Integer nextTid
= ((Long
) content
.getField(LttngStrings
.NEXT_TID
).getValue()).intValue();
259 Integer formerThreadNode
= ss
.getQuarkRelativeAndAdd(threadsNode
, prevTid
.toString());
260 Integer newCurrentThreadNode
= ss
.getQuarkRelativeAndAdd(threadsNode
, nextTid
.toString());
262 /* Set the status of the process that got scheduled out. */
263 quark
= ss
.getQuarkRelativeAndAdd(formerThreadNode
, Attributes
.STATUS
);
264 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_WAIT
);
265 ss
.modifyAttribute(ts
, value
, quark
);
267 /* Set the status of the new scheduled process */
268 setProcessToRunning(ts
, newCurrentThreadNode
);
270 /* Set the exec name of the new process */
271 quark
= ss
.getQuarkRelativeAndAdd(newCurrentThreadNode
, Attributes
.EXEC_NAME
);
272 value
= TmfStateValue
.newValueString(nextProcessName
);
273 ss
.modifyAttribute(ts
, value
, quark
);
276 * Check if we need to set the syscall state and the PPID of
277 * the new process (in case we haven't seen this process before)
279 quark
= ss
.getQuarkRelativeAndAdd(newCurrentThreadNode
, Attributes
.SYSTEM_CALL
);
280 if (quark
== ss
.getNbAttributes()) { /* Did we just add this attribute? */
281 value
= TmfStateValue
.nullValue();
282 ss
.modifyAttribute(ts
, value
, quark
);
284 quark
= ss
.getQuarkRelativeAndAdd(newCurrentThreadNode
, Attributes
.PPID
);
285 if (quark
== ss
.getNbAttributes()) {
286 value
= TmfStateValue
.nullValue();
287 ss
.modifyAttribute(ts
, value
, quark
);
290 /* Set the current scheduled process on the relevant CPU */
291 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.CURRENT_THREAD
);
292 value
= TmfStateValue
.newValueInt(nextTid
);
293 ss
.modifyAttribute(ts
, value
, quark
);
295 /* Set the status of the CPU itself */
297 /* Check if the entering process is in kernel or user mode */
298 quark
= ss
.getQuarkRelativeAndAdd(newCurrentThreadNode
, Attributes
.SYSTEM_CALL
);
299 if (ss
.queryOngoingState(quark
).isNull()) {
300 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_RUN_USERMODE
);
302 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_RUN_SYSCALL
);
305 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_IDLE
);
307 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.STATUS
);
308 ss
.modifyAttribute(ts
, value
, quark
);
312 case 8: // "sched_process_fork":
313 /* Fields: string parent_comm, int32 parent_tid,
314 * string child_comm, int32 child_tid */
316 // String parentProcessName = (String) event.getFieldValue("parent_comm");
317 String childProcessName
= (String
) content
.getField(LttngStrings
.CHILD_COMM
).getValue();
318 // assert ( parentProcessName.equals(childProcessName) );
320 Integer parentTid
= ((Long
) content
.getField(LttngStrings
.PARENT_TID
).getValue()).intValue();
321 Integer childTid
= ((Long
) content
.getField(LttngStrings
.CHILD_TID
).getValue()).intValue();
323 Integer parentTidNode
= ss
.getQuarkRelativeAndAdd(threadsNode
, parentTid
.toString());
324 Integer childTidNode
= ss
.getQuarkRelativeAndAdd(threadsNode
, childTid
.toString());
326 /* Assign the PPID to the new process */
327 quark
= ss
.getQuarkRelativeAndAdd(childTidNode
, Attributes
.PPID
);
328 value
= TmfStateValue
.newValueInt(parentTid
);
329 ss
.modifyAttribute(ts
, value
, quark
);
331 /* Set the new process' exec_name */
332 quark
= ss
.getQuarkRelativeAndAdd(childTidNode
, Attributes
.EXEC_NAME
);
333 value
= TmfStateValue
.newValueString(childProcessName
);
334 ss
.modifyAttribute(ts
, value
, quark
);
336 /* Set the new process' status */
337 quark
= ss
.getQuarkRelativeAndAdd(childTidNode
, Attributes
.STATUS
);
338 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_WAIT
);
339 ss
.modifyAttribute(ts
, value
, quark
);
341 /* Set the process' syscall name, to be the same as the parent's */
342 quark
= ss
.getQuarkRelativeAndAdd(parentTidNode
, Attributes
.SYSTEM_CALL
);
343 value
= ss
.queryOngoingState(quark
);
344 quark
= ss
.getQuarkRelativeAndAdd(childTidNode
, Attributes
.SYSTEM_CALL
);
345 ss
.modifyAttribute(ts
, value
, quark
);
349 case 9: // "sched_process_exit":
350 /* Fields: string comm, int32 tid, int32 prio */
353 case 10: // "sched_process_free":
354 /* Fields: string comm, int32 tid, int32 prio */
356 * A sched_process_free will always happen after the sched_switch
357 * that will remove the process from the cpu for the last time. So
358 * this is when we should delete everything wrt to the process.
361 Integer tid
= ((Long
) content
.getField(LttngStrings
.TID
).getValue()).intValue();
363 * Remove the process and all its sub-attributes from the
366 quark
= ss
.getQuarkRelativeAndAdd(threadsNode
, tid
.toString());
367 ss
.removeAttribute(ts
, quark
);
371 case 11: // "lttng_statedump_process_state":
373 * int32 type, int32 mode, int32 pid, int32 submode, int32 vpid,
374 * int32 ppid, int32 tid, string name, int32 status, int32 vtid */
376 Integer tid
= ((Long
) content
.getField(LttngStrings
.TID
).getValue()).intValue();
377 int ppid
= ((Long
) content
.getField(LttngStrings
.PPID
).getValue()).intValue();
378 int status
= ((Long
) content
.getField(LttngStrings
.STATUS
).getValue()).intValue();
379 String name
= (String
) content
.getField(LttngStrings
.NAME
).getValue();
381 * "mode" could be interesting too, but it doesn't seem to be
382 * populated with anything relevant for now.
385 int curThreadNode
= ss
.getQuarkRelativeAndAdd(threadsNode
, tid
.toString());
387 /* Set the process' name */
388 quark
= ss
.getQuarkRelativeAndAdd(curThreadNode
, Attributes
.EXEC_NAME
);
389 if (ss
.queryOngoingState(quark
).isNull()) {
390 /* If the value didn't exist previously, set it */
391 value
= TmfStateValue
.newValueString(name
);
392 ss
.modifyAttribute(ts
, value
, quark
);
395 /* Set the process' PPID */
396 quark
= ss
.getQuarkRelativeAndAdd(curThreadNode
, Attributes
.PPID
);
397 if (ss
.queryOngoingState(quark
).isNull()) {
398 value
= TmfStateValue
.newValueInt(ppid
);
399 ss
.modifyAttribute(ts
, value
, quark
);
402 /* Set the process' status */
403 quark
= ss
.getQuarkRelativeAndAdd(curThreadNode
, Attributes
.STATUS
);
404 if (ss
.queryOngoingState(quark
).isNull()) {
405 /*"5" here means "LTTNG_WAIT" in the LTTng kernel tracer */
407 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_WAIT
);
409 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_UNKNOWN
);
411 ss
.modifyAttribute(ts
, value
, quark
);
417 /* Other event types not covered by the main switch */
419 if (eventName
.startsWith(LttngStrings
.SYSCALL_PREFIX
)
420 || eventName
.startsWith(LttngStrings
.COMPAT_SYSCALL_PREFIX
)) {
422 * This is a replacement for the old sys_enter event. Now
423 * syscall names are listed into the event type
426 /* Assign the new system call to the process */
427 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.SYSTEM_CALL
);
428 value
= TmfStateValue
.newValueString(eventName
);
429 ss
.modifyAttribute(ts
, value
, quark
);
431 /* Put the process in system call mode */
432 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.STATUS
);
433 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_RUN_SYSCALL
);
434 ss
.modifyAttribute(ts
, value
, quark
);
436 /* Put the CPU in system call (kernel) mode */
437 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.STATUS
);
438 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_RUN_SYSCALL
);
439 ss
.modifyAttribute(ts
, value
, quark
);
443 } // End of big switch
449 /* Number of events of each type, globally */
450 // quark = ss.getQuarkAbsoluteAndAdd(Attributes.STATISTICS,
451 // Attributes.EVENT_TYPES, eventName);
452 // ss.incrementAttribute(ts, quark);
454 /* Number of events per CPU */
455 // quark = ss.getQuarkRelativeAndAdd(currentCPUNode,
456 // Attributes.STATISTICS, Attributes.EVENT_TYPES, eventName);
457 // ss.incrementAttribute(ts, quark);
459 /* Number of events per process */
460 // quark = ss.getQuarkRelativeAndAdd(currentThreadNode,
461 // Attributes.STATISTICS, Attributes.EVENT_TYPES, eventName);
462 // ss.incrementAttribute(ts, quark);
464 } catch (AttributeNotFoundException ae
) {
466 * This would indicate a problem with the logic of the manager here,
467 * so it shouldn't happen.
469 ae
.printStackTrace();
471 } catch (TimeRangeException tre
) {
473 * This would happen if the events in the trace aren't ordered
474 * chronologically, which should never be the case ...
476 System
.err
.println("TimeRangeExcpetion caught in the state system's event manager."); //$NON-NLS-1$
477 System
.err
.println("Are the events in the trace correctly ordered?"); //$NON-NLS-1$
478 tre
.printStackTrace();
480 } catch (StateValueTypeException sve
) {
482 * This would happen if we were trying to push/pop attributes not of
483 * type integer. Which, once again, should never happen.
485 sve
.printStackTrace();
489 private void setupCommonLocations() {
490 cpusNode
= ss
.getQuarkAbsoluteAndAdd(Attributes
.CPUS
);
491 threadsNode
= ss
.getQuarkAbsoluteAndAdd(Attributes
.THREADS
);
492 irqsNode
= ss
.getQuarkAbsoluteAndAdd(Attributes
.RESOURCES
, Attributes
.IRQS
);
493 softIrqsNode
= ss
.getQuarkAbsoluteAndAdd(Attributes
.RESOURCES
, Attributes
.SOFT_IRQS
);
496 private static HashMap
<String
, Integer
> fillEventNames() {
498 * TODO Replace with straight strings in the switch/case once we move to
501 HashMap
<String
, Integer
> map
= new HashMap
<String
, Integer
>();
503 map
.put(LttngStrings
.EXIT_SYSCALL
, 1);
504 map
.put(LttngStrings
.IRQ_HANDLER_ENTRY
, 2);
505 map
.put(LttngStrings
.IRQ_HANDLER_EXIT
, 3);
506 map
.put(LttngStrings
.SOFTIRQ_ENTRY
, 4);
507 map
.put(LttngStrings
.SOFTIRQ_EXIT
, 5);
508 map
.put(LttngStrings
.SOFTIRQ_RAISE
, 6);
509 map
.put(LttngStrings
.SCHED_SWITCH
, 7);
510 map
.put(LttngStrings
.SCHED_PROCESS_FORK
, 8);
511 map
.put(LttngStrings
.SCHED_PROCESS_EXIT
, 9);
512 map
.put(LttngStrings
.SCHED_PROCESS_FREE
, 10);
513 map
.put(LttngStrings
.STATEDUMP_PROCESS_STATE
, 11);
518 private int getEventIndex(String eventName
) {
519 Integer ret
= knownEventNames
.get(eventName
);
520 return (ret
!= null) ? ret
: -1;
524 * When we want to set a process back to a "running" state, first check
525 * its current System_call attribute. If there is a system call active, we
526 * put the process back in the syscall state. If not, we put it back in
529 private void setProcessToRunning(long ts
, int currentThreadNode
)
530 throws AttributeNotFoundException
, TimeRangeException
,
531 StateValueTypeException
{
533 ITmfStateValue value
;
535 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.SYSTEM_CALL
);
536 if (ss
.queryOngoingState(quark
).isNull()) {
537 /* We were in user mode before the interruption */
538 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_RUN_USERMODE
);
540 /* We were previously in kernel mode */
541 value
= TmfStateValue
.newValueInt(StateValues
.PROCESS_STATUS_RUN_SYSCALL
);
543 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.STATUS
);
544 ss
.modifyAttribute(ts
, value
, quark
);
548 * Similar logic as above, but to set the CPU's status when it's coming out
549 * of an interruption.
550 * @throws AttributeNotFoundException
551 * @throws StateValueTypeException
552 * @throws TimeRangeException
554 private void cpuExitInterrupt(long ts
, int currentCpuNode
, int currentThreadNode
)
555 throws StateValueTypeException
, AttributeNotFoundException
,
558 ITmfStateValue value
;
560 quark
= ss
.getQuarkRelativeAndAdd(currentCpuNode
, Attributes
.CURRENT_THREAD
);
561 if (ss
.queryOngoingState(quark
).unboxInt() > 0) {
562 /* There was a process on the CPU */
563 quark
= ss
.getQuarkRelative(currentThreadNode
, Attributes
.SYSTEM_CALL
);
564 if (ss
.queryOngoingState(quark
).isNull()) {
565 /* That process was in user mode */
566 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_RUN_USERMODE
);
568 /* That process was in a system call */
569 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_RUN_SYSCALL
);
572 /* There was no real process scheduled, CPU was idle */
573 value
= TmfStateValue
.newValueInt(StateValues
.CPU_STATUS_IDLE
);
575 quark
= ss
.getQuarkRelativeAndAdd(currentCpuNode
, Attributes
.STATUS
);
576 ss
.modifyAttribute(ts
, value
, quark
);