1 /*******************************************************************************
2 * Copyright (c) 2012, 2014 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 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
;
18 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystemBuilder
;
19 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
20 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateValueTypeException
;
21 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.TimeRangeException
;
22 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
23 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.TmfStateValue
;
24 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
25 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEventField
;
26 import org
.eclipse
.tracecompass
.tmf
.core
.statesystem
.AbstractTmfStateProvider
;
27 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
30 * This is the state change input plugin for TMF's state system which handles
31 * the LTTng 2.0 kernel traces in CTF format.
33 * It uses the reference handler defined in CTFKernelHandler.java.
38 public class LttngKernelStateProvider
extends AbstractTmfStateProvider
{
41 * Version number of this state provider. Please bump this if you modify the
42 * contents of the generated state history in some way.
44 private static final int VERSION
= 4;
46 // ------------------------------------------------------------------------
48 // ------------------------------------------------------------------------
51 * Instantiate a new state provider plugin.
54 * The LTTng 2.0 kernel trace directory
56 public LttngKernelStateProvider(ITmfTrace trace
) {
57 super(trace
, ITmfEvent
.class, "LTTng Kernel"); //$NON-NLS-1$
60 // ------------------------------------------------------------------------
62 // ------------------------------------------------------------------------
65 public int getVersion() {
70 public void assignTargetStateSystem(ITmfStateSystemBuilder ssb
) {
71 /* We can only set up the locations once the state system is assigned */
72 super.assignTargetStateSystem(ssb
);
76 public LttngKernelStateProvider
getNewInstance() {
77 return new LttngKernelStateProvider(this.getTrace());
81 protected void eventHandle(ITmfEvent event
) {
83 * AbstractStateChangeInput should have already checked for the correct
87 final String eventName
= event
.getType().getName();
88 final long ts
= event
.getTimestamp().getValue();
91 /* Shortcut for the "current CPU" attribute node */
92 final Integer currentCPUNode
= ss
.getQuarkRelativeAndAdd(getNodeCPUs(), event
.getSource());
95 * Shortcut for the "current thread" attribute node. It requires
96 * querying the current CPU's current thread.
98 int quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.CURRENT_THREAD
);
99 ITmfStateValue value
= ss
.queryOngoingState(quark
);
100 int thread
= value
.isNull() ?
-1 : value
.unboxInt();
101 final Integer currentThreadNode
= ss
.getQuarkRelativeAndAdd(getNodeThreads(), String
.valueOf(thread
));
104 * Feed event to the history system if it's known to cause a state
109 case LttngStrings
.EXIT_SYSCALL
:
110 /* Fields: int64 ret */
112 /* Clear the current system call on the process */
113 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.SYSTEM_CALL
);
114 value
= TmfStateValue
.nullValue();
115 ss
.modifyAttribute(ts
, value
, quark
);
117 /* Put the process' status back to user mode */
118 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.STATUS
);
119 value
= StateValues
.PROCESS_STATUS_RUN_USERMODE_VALUE
;
120 ss
.modifyAttribute(ts
, value
, quark
);
122 /* Put the CPU's status back to user mode */
123 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.STATUS
);
124 value
= StateValues
.CPU_STATUS_RUN_USERMODE_VALUE
;
125 ss
.modifyAttribute(ts
, value
, quark
);
129 case LttngStrings
.IRQ_HANDLER_ENTRY
:
130 /* Fields: int32 irq, string name */
132 Integer irqId
= ((Long
) event
.getContent().getField(LttngStrings
.IRQ
).getValue()).intValue();
134 /* Mark this IRQ as active in the resource tree.
135 * The state value = the CPU on which this IRQ is sitting */
136 quark
= ss
.getQuarkRelativeAndAdd(getNodeIRQs(), irqId
.toString());
137 value
= TmfStateValue
.newValueInt(Integer
.parseInt(event
.getSource()));
138 ss
.modifyAttribute(ts
, value
, quark
);
140 /* Change the status of the running process to interrupted */
141 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.STATUS
);
142 value
= StateValues
.PROCESS_STATUS_INTERRUPTED_VALUE
;
143 ss
.modifyAttribute(ts
, value
, quark
);
145 /* Change the status of the CPU to interrupted */
146 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.STATUS
);
147 value
= StateValues
.CPU_STATUS_IRQ_VALUE
;
148 ss
.modifyAttribute(ts
, value
, quark
);
152 case LttngStrings
.IRQ_HANDLER_EXIT
:
153 /* Fields: int32 irq, int32 ret */
155 Integer irqId
= ((Long
) event
.getContent().getField(LttngStrings
.IRQ
).getValue()).intValue();
157 /* Put this IRQ back to inactive in the resource tree */
158 quark
= ss
.getQuarkRelativeAndAdd(getNodeIRQs(), irqId
.toString());
159 value
= TmfStateValue
.nullValue();
160 ss
.modifyAttribute(ts
, value
, quark
);
162 /* Set the previous process back to running */
163 setProcessToRunning(ts
, currentThreadNode
);
165 /* Set the CPU status back to running or "idle" */
166 cpuExitInterrupt(ts
, currentCPUNode
, currentThreadNode
);
170 case LttngStrings
.SOFTIRQ_ENTRY
:
171 /* Fields: int32 vec */
173 Integer softIrqId
= ((Long
) event
.getContent().getField(LttngStrings
.VEC
).getValue()).intValue();
175 /* Mark this SoftIRQ as active in the resource tree.
176 * The state value = the CPU on which this SoftIRQ is processed */
177 quark
= ss
.getQuarkRelativeAndAdd(getNodeSoftIRQs(), softIrqId
.toString());
178 value
= TmfStateValue
.newValueInt(Integer
.parseInt(event
.getSource()));
179 ss
.modifyAttribute(ts
, value
, quark
);
181 /* Change the status of the running process to interrupted */
182 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.STATUS
);
183 value
= StateValues
.PROCESS_STATUS_INTERRUPTED_VALUE
;
184 ss
.modifyAttribute(ts
, value
, quark
);
186 /* Change the status of the CPU to interrupted */
187 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.STATUS
);
188 value
= StateValues
.CPU_STATUS_SOFTIRQ_VALUE
;
189 ss
.modifyAttribute(ts
, value
, quark
);
193 case LttngStrings
.SOFTIRQ_EXIT
:
194 /* Fields: int32 vec */
196 Integer softIrqId
= ((Long
) event
.getContent().getField(LttngStrings
.VEC
).getValue()).intValue();
198 /* Put this SoftIRQ back to inactive (= -1) in the resource tree */
199 quark
= ss
.getQuarkRelativeAndAdd(getNodeSoftIRQs(), softIrqId
.toString());
200 value
= TmfStateValue
.nullValue();
201 ss
.modifyAttribute(ts
, value
, quark
);
203 /* Set the previous process back to running */
204 setProcessToRunning(ts
, currentThreadNode
);
206 /* Set the CPU status back to "busy" or "idle" */
207 cpuExitInterrupt(ts
, currentCPUNode
, currentThreadNode
);
211 case LttngStrings
.SOFTIRQ_RAISE
:
212 /* Fields: int32 vec */
214 Integer softIrqId
= ((Long
) event
.getContent().getField(LttngStrings
.VEC
).getValue()).intValue();
216 /* Mark this SoftIRQ as *raised* in the resource tree.
217 * State value = -2 */
218 quark
= ss
.getQuarkRelativeAndAdd(getNodeSoftIRQs(), softIrqId
.toString());
219 value
= StateValues
.SOFT_IRQ_RAISED_VALUE
;
220 ss
.modifyAttribute(ts
, value
, quark
);
224 case LttngStrings
.SCHED_SWITCH
:
226 * Fields: string prev_comm, int32 prev_tid, int32 prev_prio, int64 prev_state,
227 * string next_comm, int32 next_tid, int32 next_prio
230 ITmfEventField content
= event
.getContent();
231 Integer prevTid
= ((Long
) content
.getField(LttngStrings
.PREV_TID
).getValue()).intValue();
232 Long prevState
= (Long
) content
.getField(LttngStrings
.PREV_STATE
).getValue();
233 String nextProcessName
= (String
) content
.getField(LttngStrings
.NEXT_COMM
).getValue();
234 Integer nextTid
= ((Long
) content
.getField(LttngStrings
.NEXT_TID
).getValue()).intValue();
236 Integer formerThreadNode
= ss
.getQuarkRelativeAndAdd(getNodeThreads(), prevTid
.toString());
237 Integer newCurrentThreadNode
= ss
.getQuarkRelativeAndAdd(getNodeThreads(), nextTid
.toString());
239 /* Set the status of the process that got scheduled out. */
240 quark
= ss
.getQuarkRelativeAndAdd(formerThreadNode
, Attributes
.STATUS
);
241 if (prevState
!= 0) {
242 value
= StateValues
.PROCESS_STATUS_WAIT_BLOCKED_VALUE
;
244 value
= StateValues
.PROCESS_STATUS_WAIT_FOR_CPU_VALUE
;
246 ss
.modifyAttribute(ts
, value
, quark
);
248 /* Set the status of the new scheduled process */
249 setProcessToRunning(ts
, newCurrentThreadNode
);
251 /* Set the exec name of the new process */
252 quark
= ss
.getQuarkRelativeAndAdd(newCurrentThreadNode
, Attributes
.EXEC_NAME
);
253 value
= TmfStateValue
.newValueString(nextProcessName
);
254 ss
.modifyAttribute(ts
, value
, quark
);
256 /* Make sure the PPID and system_call sub-attributes exist */
257 ss
.getQuarkRelativeAndAdd(newCurrentThreadNode
, Attributes
.SYSTEM_CALL
);
258 ss
.getQuarkRelativeAndAdd(newCurrentThreadNode
, Attributes
.PPID
);
260 /* Set the current scheduled process on the relevant CPU */
261 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.CURRENT_THREAD
);
262 value
= TmfStateValue
.newValueInt(nextTid
);
263 ss
.modifyAttribute(ts
, value
, quark
);
265 /* Set the status of the CPU itself */
267 /* Check if the entering process is in kernel or user mode */
268 quark
= ss
.getQuarkRelativeAndAdd(newCurrentThreadNode
, Attributes
.SYSTEM_CALL
);
269 if (ss
.queryOngoingState(quark
).isNull()) {
270 value
= StateValues
.CPU_STATUS_RUN_USERMODE_VALUE
;
272 value
= StateValues
.CPU_STATUS_RUN_SYSCALL_VALUE
;
275 value
= StateValues
.CPU_STATUS_IDLE_VALUE
;
277 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.STATUS
);
278 ss
.modifyAttribute(ts
, value
, quark
);
282 case LttngStrings
.SCHED_PROCESS_FORK
:
283 /* Fields: string parent_comm, int32 parent_tid,
284 * string child_comm, int32 child_tid */
286 ITmfEventField content
= event
.getContent();
287 // String parentProcessName = (String) event.getFieldValue("parent_comm");
288 String childProcessName
= (String
) content
.getField(LttngStrings
.CHILD_COMM
).getValue();
289 // assert ( parentProcessName.equals(childProcessName) );
291 Integer parentTid
= ((Long
) content
.getField(LttngStrings
.PARENT_TID
).getValue()).intValue();
292 Integer childTid
= ((Long
) content
.getField(LttngStrings
.CHILD_TID
).getValue()).intValue();
294 Integer parentTidNode
= ss
.getQuarkRelativeAndAdd(getNodeThreads(), parentTid
.toString());
295 Integer childTidNode
= ss
.getQuarkRelativeAndAdd(getNodeThreads(), childTid
.toString());
297 /* Assign the PPID to the new process */
298 quark
= ss
.getQuarkRelativeAndAdd(childTidNode
, Attributes
.PPID
);
299 value
= TmfStateValue
.newValueInt(parentTid
);
300 ss
.modifyAttribute(ts
, value
, quark
);
302 /* Set the new process' exec_name */
303 quark
= ss
.getQuarkRelativeAndAdd(childTidNode
, Attributes
.EXEC_NAME
);
304 value
= TmfStateValue
.newValueString(childProcessName
);
305 ss
.modifyAttribute(ts
, value
, quark
);
307 /* Set the new process' status */
308 quark
= ss
.getQuarkRelativeAndAdd(childTidNode
, Attributes
.STATUS
);
309 value
= StateValues
.PROCESS_STATUS_WAIT_FOR_CPU_VALUE
;
310 ss
.modifyAttribute(ts
, value
, quark
);
312 /* Set the process' syscall name, to be the same as the parent's */
313 quark
= ss
.getQuarkRelativeAndAdd(parentTidNode
, Attributes
.SYSTEM_CALL
);
314 value
= ss
.queryOngoingState(quark
);
315 if (value
.isNull()) {
317 * Maybe we were missing info about the parent? At least we
318 * will set the child right. Let's suppose "sys_clone".
320 value
= TmfStateValue
.newValueString(LttngStrings
.SYS_CLONE
);
322 quark
= ss
.getQuarkRelativeAndAdd(childTidNode
, Attributes
.SYSTEM_CALL
);
323 ss
.modifyAttribute(ts
, value
, quark
);
327 case LttngStrings
.SCHED_PROCESS_EXIT
:
328 /* Fields: string comm, int32 tid, int32 prio */
331 case LttngStrings
.SCHED_PROCESS_FREE
:
332 /* Fields: string comm, int32 tid, int32 prio */
334 * A sched_process_free will always happen after the sched_switch
335 * that will remove the process from the cpu for the last time. So
336 * this is when we should delete everything wrt to the process.
339 Integer tid
= ((Long
) event
.getContent().getField(LttngStrings
.TID
).getValue()).intValue();
341 * Remove the process and all its sub-attributes from the
344 quark
= ss
.getQuarkRelativeAndAdd(getNodeThreads(), tid
.toString());
345 ss
.removeAttribute(ts
, quark
);
349 case LttngStrings
.STATEDUMP_PROCESS_STATE
:
351 * int32 type, int32 mode, int32 pid, int32 submode, int32 vpid,
352 * int32 ppid, int32 tid, string name, int32 status, int32 vtid */
354 ITmfEventField content
= event
.getContent();
355 int tid
= ((Long
) content
.getField(LttngStrings
.TID
).getValue()).intValue();
356 int pid
= ((Long
) content
.getField(LttngStrings
.PID
).getValue()).intValue();
357 int ppid
= ((Long
) content
.getField(LttngStrings
.PPID
).getValue()).intValue();
358 int status
= ((Long
) content
.getField(LttngStrings
.STATUS
).getValue()).intValue();
359 String name
= (String
) content
.getField(LttngStrings
.NAME
).getValue();
361 * "mode" could be interesting too, but it doesn't seem to be
362 * populated with anything relevant for now.
365 int curThreadNode
= ss
.getQuarkRelativeAndAdd(getNodeThreads(), String
.valueOf(tid
));
367 /* Set the process' name */
368 quark
= ss
.getQuarkRelativeAndAdd(curThreadNode
, Attributes
.EXEC_NAME
);
369 if (ss
.queryOngoingState(quark
).isNull()) {
370 /* If the value didn't exist previously, set it */
371 value
= TmfStateValue
.newValueString(name
);
372 ss
.modifyAttribute(ts
, value
, quark
);
375 /* Set the process' PPID */
376 quark
= ss
.getQuarkRelativeAndAdd(curThreadNode
, Attributes
.PPID
);
377 if (ss
.queryOngoingState(quark
).isNull()) {
379 /* We have a process. Use the 'PPID' field. */
380 value
= TmfStateValue
.newValueInt(ppid
);
382 /* We have a thread, use the 'PID' field for the parent. */
383 value
= TmfStateValue
.newValueInt(pid
);
385 ss
.modifyAttribute(ts
, value
, quark
);
388 /* Set the process' status */
389 quark
= ss
.getQuarkRelativeAndAdd(curThreadNode
, Attributes
.STATUS
);
390 if (ss
.queryOngoingState(quark
).isNull()) {
391 /* "2" here means "WAIT_FOR_CPU", and "5" "WAIT_BLOCKED" in the LTTng kernel. */
393 value
= StateValues
.PROCESS_STATUS_WAIT_FOR_CPU_VALUE
;
394 } else if (status
== 5) {
395 value
= StateValues
.PROCESS_STATUS_WAIT_BLOCKED_VALUE
;
397 value
= StateValues
.PROCESS_STATUS_UNKNOWN_VALUE
;
399 ss
.modifyAttribute(ts
, value
, quark
);
404 case LttngStrings
.SCHED_WAKEUP
:
405 case LttngStrings
.SCHED_WAKEUP_NEW
:
406 /* Fields (same fields for both types):
407 * string comm, int32 pid, int32 prio, int32 success,
408 * int32 target_cpu */
410 final int tid
= ((Long
) event
.getContent().getField(LttngStrings
.TID
).getValue()).intValue();
411 final int threadNode
= ss
.getQuarkRelativeAndAdd(getNodeThreads(), String
.valueOf(tid
));
414 * The process indicated in the event's payload is now ready to
415 * run. Assign it to the "wait for cpu" state, but only if it
416 * was not already running.
418 quark
= ss
.getQuarkRelativeAndAdd(threadNode
, Attributes
.STATUS
);
419 int status
= ss
.queryOngoingState(quark
).unboxInt();
421 if (status
!= StateValues
.PROCESS_STATUS_RUN_SYSCALL
&&
422 status
!= StateValues
.PROCESS_STATUS_RUN_USERMODE
) {
423 value
= StateValues
.PROCESS_STATUS_WAIT_FOR_CPU_VALUE
;
424 ss
.modifyAttribute(ts
, value
, quark
);
430 /* Other event types not covered by the main switch */
432 if (eventName
.startsWith(LttngStrings
.SYSCALL_PREFIX
)
433 || eventName
.startsWith(LttngStrings
.COMPAT_SYSCALL_PREFIX
)) {
435 * This is a replacement for the old sys_enter event. Now
436 * syscall names are listed into the event type
439 /* Assign the new system call to the process */
440 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.SYSTEM_CALL
);
441 value
= TmfStateValue
.newValueString(eventName
);
442 ss
.modifyAttribute(ts
, value
, quark
);
444 /* Put the process in system call mode */
445 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.STATUS
);
446 value
= StateValues
.PROCESS_STATUS_RUN_SYSCALL_VALUE
;
447 ss
.modifyAttribute(ts
, value
, quark
);
449 /* Put the CPU in system call (kernel) mode */
450 quark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, Attributes
.STATUS
);
451 value
= StateValues
.CPU_STATUS_RUN_SYSCALL_VALUE
;
452 ss
.modifyAttribute(ts
, value
, quark
);
456 } // End of big switch
458 } catch (AttributeNotFoundException ae
) {
460 * This would indicate a problem with the logic of the manager here,
461 * so it shouldn't happen.
463 ae
.printStackTrace();
465 } catch (TimeRangeException tre
) {
467 * This would happen if the events in the trace aren't ordered
468 * chronologically, which should never be the case ...
470 System
.err
.println("TimeRangeExcpetion caught in the state system's event manager."); //$NON-NLS-1$
471 System
.err
.println("Are the events in the trace correctly ordered?"); //$NON-NLS-1$
472 tre
.printStackTrace();
474 } catch (StateValueTypeException sve
) {
476 * This would happen if we were trying to push/pop attributes not of
477 * type integer. Which, once again, should never happen.
479 sve
.printStackTrace();
483 // ------------------------------------------------------------------------
484 // Convenience methods for commonly-used attribute tree locations
485 // ------------------------------------------------------------------------
487 private int getNodeCPUs() {
488 return ss
.getQuarkAbsoluteAndAdd(Attributes
.CPUS
);
491 private int getNodeThreads() {
492 return ss
.getQuarkAbsoluteAndAdd(Attributes
.THREADS
);
495 private int getNodeIRQs() {
496 return ss
.getQuarkAbsoluteAndAdd(Attributes
.RESOURCES
, Attributes
.IRQS
);
499 private int getNodeSoftIRQs() {
500 return ss
.getQuarkAbsoluteAndAdd(Attributes
.RESOURCES
, Attributes
.SOFT_IRQS
);
503 // ------------------------------------------------------------------------
504 // Advanced state-setting methods
505 // ------------------------------------------------------------------------
508 * When we want to set a process back to a "running" state, first check
509 * its current System_call attribute. If there is a system call active, we
510 * put the process back in the syscall state. If not, we put it back in
513 private void setProcessToRunning(long ts
, int currentThreadNode
)
514 throws AttributeNotFoundException
, TimeRangeException
,
515 StateValueTypeException
{
517 ITmfStateValue value
;
519 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.SYSTEM_CALL
);
520 if (ss
.queryOngoingState(quark
).isNull()) {
521 /* We were in user mode before the interruption */
522 value
= StateValues
.PROCESS_STATUS_RUN_USERMODE_VALUE
;
524 /* We were previously in kernel mode */
525 value
= StateValues
.PROCESS_STATUS_RUN_SYSCALL_VALUE
;
527 quark
= ss
.getQuarkRelativeAndAdd(currentThreadNode
, Attributes
.STATUS
);
528 ss
.modifyAttribute(ts
, value
, quark
);
532 * Similar logic as above, but to set the CPU's status when it's coming out
533 * of an interruption.
535 private void cpuExitInterrupt(long ts
, int currentCpuNode
, int currentThreadNode
)
536 throws StateValueTypeException
, AttributeNotFoundException
,
539 ITmfStateValue value
;
541 quark
= ss
.getQuarkRelativeAndAdd(currentCpuNode
, Attributes
.CURRENT_THREAD
);
542 if (ss
.queryOngoingState(quark
).unboxInt() > 0) {
543 /* There was a process on the CPU */
544 quark
= ss
.getQuarkRelative(currentThreadNode
, Attributes
.SYSTEM_CALL
);
545 if (ss
.queryOngoingState(quark
).isNull()) {
546 /* That process was in user mode */
547 value
= StateValues
.CPU_STATUS_RUN_USERMODE_VALUE
;
549 /* That process was in a system call */
550 value
= StateValues
.CPU_STATUS_RUN_SYSCALL_VALUE
;
553 /* There was no real process scheduled, CPU was idle */
554 value
= StateValues
.CPU_STATUS_IDLE_VALUE
;
556 quark
= ss
.getQuarkRelativeAndAdd(currentCpuNode
, Attributes
.STATUS
);
557 ss
.modifyAttribute(ts
, value
, quark
);