tmf: Split the state system in a separate plugin
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng2.kernel.core / src / org / eclipse / linuxtools / internal / lttng2 / kernel / core / stateprovider / LttngKernelStateProvider.java
CommitLineData
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
13package org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider;
14
79e0a1df
AM
15import org.eclipse.linuxtools.internal.lttng2.kernel.core.Attributes;
16import org.eclipse.linuxtools.internal.lttng2.kernel.core.LttngStrings;
17import org.eclipse.linuxtools.internal.lttng2.kernel.core.StateValues;
bcec0116
AM
18import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder;
19import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException;
20import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException;
21import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException;
22import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue;
23import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue;
2c2f900e 24import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
79e0a1df 25import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
0fe46f2a 26import org.eclipse.linuxtools.tmf.core.statesystem.AbstractTmfStateProvider;
91e7f946
AM
27import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfEvent;
28import 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 39public 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}
This page took 0.077738 seconds and 5 git commands to generate.