tmf: Null-annotate state system API classes
[deliverable/tracecompass.git] / org.eclipse.tracecompass.lttng2.kernel.core / src / org / eclipse / tracecompass / lttng2 / kernel / core / analysis / kernel / LttngKernelStateProvider.java
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>
5 *
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
10 *
11 *******************************************************************************/
12
13 package org.eclipse.tracecompass.lttng2.kernel.core.analysis.kernel;
14
15 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
16
17 import java.util.Map;
18
19 import org.eclipse.jdt.annotation.NonNull;
20 import org.eclipse.tracecompass.internal.lttng2.kernel.core.Attributes;
21 import org.eclipse.tracecompass.internal.lttng2.kernel.core.StateValues;
22 import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.IKernelAnalysisEventLayout;
23 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
24 import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
25 import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
26 import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
27 import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
28 import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
29 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
30 import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
31 import org.eclipse.tracecompass.tmf.core.event.aspect.TmfCpuAspect;
32 import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider;
33 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
34 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
35
36 import com.google.common.collect.ImmutableMap;
37
38 /**
39 * This is the state change input plugin for TMF's state system which handles
40 * the LTTng 2.0 kernel traces in CTF format.
41 *
42 * It uses the reference handler defined in CTFKernelHandler.java.
43 *
44 * @author alexmont
45 *
46 */
47 public class LttngKernelStateProvider extends AbstractTmfStateProvider {
48
49 // ------------------------------------------------------------------------
50 // Static fields
51 // ------------------------------------------------------------------------
52
53 /**
54 * Version number of this state provider. Please bump this if you modify the
55 * contents of the generated state history in some way.
56 */
57 private static final int VERSION = 5;
58
59 private static final int IRQ_HANDLER_ENTRY_INDEX = 1;
60 private static final int IRQ_HANDLER_EXIT_INDEX = 2;
61 private static final int SOFT_IRQ_ENTRY_INDEX = 3;
62 private static final int SOFT_IRQ_EXIT_INDEX = 4;
63 private static final int SOFT_IRQ_RAISE_INDEX = 5;
64 private static final int SCHED_SWITCH_INDEX = 6;
65 private static final int SCHED_PROCESS_FORK_INDEX = 7;
66 private static final int SCHED_PROCESS_EXIT_INDEX = 8;
67 private static final int SCHED_PROCESS_FREE_INDEX = 9;
68 private static final int STATEDUMP_PROCESS_STATE_INDEX = 10;
69 private static final int SCHED_WAKEUP_INDEX = 11;
70
71
72 // ------------------------------------------------------------------------
73 // Fields
74 // ------------------------------------------------------------------------
75
76 private final Map<String, Integer> fEventNames;
77 private final @NonNull IKernelAnalysisEventLayout fLayout;
78
79 // ------------------------------------------------------------------------
80 // Constructor
81 // ------------------------------------------------------------------------
82
83 /**
84 * Instantiate a new state provider plugin.
85 *
86 * @param trace
87 * The LTTng 2.0 kernel trace directory
88 * @param layout
89 * The event layout to use for this state provider. Usually
90 * depending on the tracer implementation.
91 */
92 public LttngKernelStateProvider(@NonNull ITmfTrace trace, @NonNull IKernelAnalysisEventLayout layout) {
93 super(trace, ITmfEvent.class, "Kernel"); //$NON-NLS-1$
94 fLayout = layout;
95 fEventNames = buildEventNames(layout);
96 }
97
98 // ------------------------------------------------------------------------
99 // Event names management
100 // ------------------------------------------------------------------------
101
102 private static Map<String, Integer> buildEventNames(IKernelAnalysisEventLayout layout) {
103 ImmutableMap.Builder<String, Integer> builder = ImmutableMap.builder();
104
105 builder.put(layout.eventIrqHandlerEntry(), IRQ_HANDLER_ENTRY_INDEX);
106 builder.put(layout.eventIrqHandlerExit(), IRQ_HANDLER_EXIT_INDEX);
107 builder.put(layout.eventSoftIrqEntry(), SOFT_IRQ_ENTRY_INDEX);
108 builder.put(layout.eventSoftIrqExit(), SOFT_IRQ_EXIT_INDEX);
109 builder.put(layout.eventSoftIrqRaise(), SOFT_IRQ_RAISE_INDEX);
110 builder.put(layout.eventSchedSwitch(), SCHED_SWITCH_INDEX);
111 builder.put(layout.eventSchedProcessFork(), SCHED_PROCESS_FORK_INDEX);
112 builder.put(layout.eventSchedProcessExit(), SCHED_PROCESS_EXIT_INDEX);
113 builder.put(layout.eventSchedProcessFree(), SCHED_PROCESS_FREE_INDEX);
114
115 if (layout.eventStatedumpProcessState() != null) {
116 builder.put(layout.eventStatedumpProcessState(), STATEDUMP_PROCESS_STATE_INDEX);
117 }
118
119 for (String eventSchedWakeup : layout.eventsSchedWakeup()) {
120 builder.put(eventSchedWakeup, SCHED_WAKEUP_INDEX);
121 }
122
123 return builder.build();
124 }
125
126 // ------------------------------------------------------------------------
127 // IStateChangeInput
128 // ------------------------------------------------------------------------
129
130 @Override
131 public int getVersion() {
132 return VERSION;
133 }
134
135 @Override
136 public void assignTargetStateSystem(ITmfStateSystemBuilder ssb) {
137 /* We can only set up the locations once the state system is assigned */
138 super.assignTargetStateSystem(ssb);
139 }
140
141 @Override
142 public LttngKernelStateProvider getNewInstance() {
143 return new LttngKernelStateProvider(this.getTrace(), fLayout);
144 }
145
146 @Override
147 protected void eventHandle(ITmfEvent event) {
148 ITmfStateSystemBuilder ss = checkNotNull(getStateSystemBuilder());
149
150 Integer cpu = null;
151 Iterable<TmfCpuAspect> aspects = TmfTraceUtils.getEventAspectsOfClass(event.getTrace(), TmfCpuAspect.class);
152 for (TmfCpuAspect aspect : aspects) {
153 if (!aspect.resolve(event).equals(TmfCpuAspect.CPU_UNAVAILABLE)) {
154 cpu = aspect.resolve(event);
155 break;
156 }
157 }
158 if (cpu == null) {
159 /* We couldn't find any CPU information, ignore this event */
160 return;
161 }
162
163 final String eventName = event.getType().getName();
164 final long ts = event.getTimestamp().getValue();
165
166 try {
167 /* Shortcut for the "current CPU" attribute node */
168 final int currentCPUNode = ss.getQuarkRelativeAndAdd(getNodeCPUs(ss), cpu.toString());
169
170 /*
171 * Shortcut for the "current thread" attribute node. It requires
172 * querying the current CPU's current thread.
173 */
174 int quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.CURRENT_THREAD);
175 ITmfStateValue value = ss.queryOngoingState(quark);
176 int thread = value.isNull() ? -1 : value.unboxInt();
177 final int currentThreadNode = ss.getQuarkRelativeAndAdd(getNodeThreads(ss), String.valueOf(thread));
178
179 /*
180 * Feed event to the history system if it's known to cause a state
181 * transition.
182 */
183 Integer idx = fEventNames.get(eventName);
184 int intval = (idx == null ? -1 : idx.intValue());
185 switch (intval) {
186
187 case IRQ_HANDLER_ENTRY_INDEX:
188 {
189 Integer irqId = ((Long) event.getContent().getField(fLayout.fieldIrq()).getValue()).intValue();
190
191 /* Mark this IRQ as active in the resource tree.
192 * The state value = the CPU on which this IRQ is sitting */
193 quark = ss.getQuarkRelativeAndAdd(getNodeIRQs(ss), irqId.toString());
194 value = TmfStateValue.newValueInt(cpu.intValue());
195 ss.modifyAttribute(ts, value, quark);
196
197 /* Change the status of the running process to interrupted */
198 quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
199 value = StateValues.PROCESS_STATUS_INTERRUPTED_VALUE;
200 ss.modifyAttribute(ts, value, quark);
201
202 /* Change the status of the CPU to interrupted */
203 quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
204 value = StateValues.CPU_STATUS_IRQ_VALUE;
205 ss.modifyAttribute(ts, value, quark);
206 }
207 break;
208
209 case IRQ_HANDLER_EXIT_INDEX:
210 {
211 Integer irqId = ((Long) event.getContent().getField(fLayout.fieldIrq()).getValue()).intValue();
212
213 /* Put this IRQ back to inactive in the resource tree */
214 quark = ss.getQuarkRelativeAndAdd(getNodeIRQs(ss), irqId.toString());
215 value = TmfStateValue.nullValue();
216 ss.modifyAttribute(ts, value, quark);
217
218 /* Set the previous process back to running */
219 setProcessToRunning(ss, ts, currentThreadNode);
220
221 /* Set the CPU status back to running or "idle" */
222 cpuExitInterrupt(ss, ts, currentCPUNode, currentThreadNode);
223 }
224 break;
225
226 case SOFT_IRQ_ENTRY_INDEX:
227 {
228 Integer softIrqId = ((Long) event.getContent().getField(fLayout.fieldVec()).getValue()).intValue();
229
230 /* Mark this SoftIRQ as active in the resource tree.
231 * The state value = the CPU on which this SoftIRQ is processed */
232 quark = ss.getQuarkRelativeAndAdd(getNodeSoftIRQs(ss), softIrqId.toString());
233 value = TmfStateValue.newValueInt(cpu.intValue());
234 ss.modifyAttribute(ts, value, quark);
235
236 /* Change the status of the running process to interrupted */
237 quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
238 value = StateValues.PROCESS_STATUS_INTERRUPTED_VALUE;
239 ss.modifyAttribute(ts, value, quark);
240
241 /* Change the status of the CPU to interrupted */
242 quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
243 value = StateValues.CPU_STATUS_SOFTIRQ_VALUE;
244 ss.modifyAttribute(ts, value, quark);
245 }
246 break;
247
248 case SOFT_IRQ_EXIT_INDEX:
249 {
250 Integer softIrqId = ((Long) event.getContent().getField(fLayout.fieldVec()).getValue()).intValue();
251
252 /* Put this SoftIRQ back to inactive (= -1) in the resource tree */
253 quark = ss.getQuarkRelativeAndAdd(getNodeSoftIRQs(ss), softIrqId.toString());
254 value = TmfStateValue.nullValue();
255 ss.modifyAttribute(ts, value, quark);
256
257 /* Set the previous process back to running */
258 setProcessToRunning(ss, ts, currentThreadNode);
259
260 /* Set the CPU status back to "busy" or "idle" */
261 cpuExitInterrupt(ss, ts, currentCPUNode, currentThreadNode);
262 }
263 break;
264
265 case SOFT_IRQ_RAISE_INDEX:
266 /* Fields: int32 vec */
267 {
268 Integer softIrqId = ((Long) event.getContent().getField(fLayout.fieldVec()).getValue()).intValue();
269
270 /* Mark this SoftIRQ as *raised* in the resource tree.
271 * State value = -2 */
272 quark = ss.getQuarkRelativeAndAdd(getNodeSoftIRQs(ss), softIrqId.toString());
273 value = StateValues.SOFT_IRQ_RAISED_VALUE;
274 ss.modifyAttribute(ts, value, quark);
275 }
276 break;
277
278 case SCHED_SWITCH_INDEX:
279 {
280 ITmfEventField content = event.getContent();
281 Integer prevTid = ((Long) content.getField(fLayout.fieldPrevTid()).getValue()).intValue();
282 Long prevState = (Long) content.getField(fLayout.fieldPrevState()).getValue();
283 String nextProcessName = (String) content.getField(fLayout.fieldNextComm()).getValue();
284 Integer nextTid = ((Long) content.getField(fLayout.fieldNextTid()).getValue()).intValue();
285
286 Integer formerThreadNode = ss.getQuarkRelativeAndAdd(getNodeThreads(ss), prevTid.toString());
287 Integer newCurrentThreadNode = ss.getQuarkRelativeAndAdd(getNodeThreads(ss), nextTid.toString());
288
289 /* Set the status of the process that got scheduled out. */
290 quark = ss.getQuarkRelativeAndAdd(formerThreadNode, Attributes.STATUS);
291 if (prevState != 0) {
292 value = StateValues.PROCESS_STATUS_WAIT_BLOCKED_VALUE;
293 } else {
294 value = StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE;
295 }
296 ss.modifyAttribute(ts, value, quark);
297
298 /* Set the status of the new scheduled process */
299 setProcessToRunning(ss, ts, newCurrentThreadNode);
300
301 /* Set the exec name of the new process */
302 quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.EXEC_NAME);
303 value = TmfStateValue.newValueString(nextProcessName);
304 ss.modifyAttribute(ts, value, quark);
305
306 /* Make sure the PPID and system_call sub-attributes exist */
307 ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.SYSTEM_CALL);
308 ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.PPID);
309
310 /* Set the current scheduled process on the relevant CPU */
311 quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.CURRENT_THREAD);
312 value = TmfStateValue.newValueInt(nextTid);
313 ss.modifyAttribute(ts, value, quark);
314
315 /* Set the status of the CPU itself */
316 if (nextTid > 0) {
317 /* Check if the entering process is in kernel or user mode */
318 quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.SYSTEM_CALL);
319 if (ss.queryOngoingState(quark).isNull()) {
320 value = StateValues.CPU_STATUS_RUN_USERMODE_VALUE;
321 } else {
322 value = StateValues.CPU_STATUS_RUN_SYSCALL_VALUE;
323 }
324 } else {
325 value = StateValues.CPU_STATUS_IDLE_VALUE;
326 }
327 quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
328 ss.modifyAttribute(ts, value, quark);
329 }
330 break;
331
332 case SCHED_PROCESS_FORK_INDEX:
333 {
334 ITmfEventField content = event.getContent();
335 // String parentProcessName = (String) event.getFieldValue("parent_comm");
336 String childProcessName = (String) content.getField(fLayout.fieldChildComm()).getValue();
337 // assert ( parentProcessName.equals(childProcessName) );
338
339 Integer parentTid = ((Long) content.getField(fLayout.fieldParentTid()).getValue()).intValue();
340 Integer childTid = ((Long) content.getField(fLayout.fieldChildTid()).getValue()).intValue();
341
342 Integer parentTidNode = ss.getQuarkRelativeAndAdd(getNodeThreads(ss), parentTid.toString());
343 Integer childTidNode = ss.getQuarkRelativeAndAdd(getNodeThreads(ss), childTid.toString());
344
345 /* Assign the PPID to the new process */
346 quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.PPID);
347 value = TmfStateValue.newValueInt(parentTid);
348 ss.modifyAttribute(ts, value, quark);
349
350 /* Set the new process' exec_name */
351 quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.EXEC_NAME);
352 value = TmfStateValue.newValueString(childProcessName);
353 ss.modifyAttribute(ts, value, quark);
354
355 /* Set the new process' status */
356 quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.STATUS);
357 value = StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE;
358 ss.modifyAttribute(ts, value, quark);
359
360 /* Set the process' syscall name, to be the same as the parent's */
361 quark = ss.getQuarkRelativeAndAdd(parentTidNode, Attributes.SYSTEM_CALL);
362 value = ss.queryOngoingState(quark);
363 if (value.isNull()) {
364 /*
365 * Maybe we were missing info about the parent? At least we
366 * will set the child right. Let's suppose "sys_clone".
367 */
368 value = TmfStateValue.newValueString(fLayout.eventSyscallEntryPrefix() + IKernelAnalysisEventLayout.INITIAL_SYSCALL_NAME);
369 }
370 quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.SYSTEM_CALL);
371 ss.modifyAttribute(ts, value, quark);
372 }
373 break;
374
375 case SCHED_PROCESS_EXIT_INDEX:
376 break;
377
378 case SCHED_PROCESS_FREE_INDEX:
379 {
380 Integer tid = ((Long) event.getContent().getField(fLayout.fieldTid()).getValue()).intValue();
381 /*
382 * Remove the process and all its sub-attributes from the
383 * current state
384 */
385 quark = ss.getQuarkRelativeAndAdd(getNodeThreads(ss), tid.toString());
386 ss.removeAttribute(ts, quark);
387 }
388 break;
389
390 case STATEDUMP_PROCESS_STATE_INDEX:
391 /* LTTng-specific */
392 {
393 ITmfEventField content = event.getContent();
394 int tid = ((Long) content.getField("tid").getValue()).intValue(); //$NON-NLS-1$
395 int pid = ((Long) content.getField("pid").getValue()).intValue(); //$NON-NLS-1$
396 int ppid = ((Long) content.getField("ppid").getValue()).intValue(); //$NON-NLS-1$
397 int status = ((Long) content.getField("status").getValue()).intValue(); //$NON-NLS-1$
398 String name = (String) content.getField("name").getValue(); //$NON-NLS-1$
399 /*
400 * "mode" could be interesting too, but it doesn't seem to be
401 * populated with anything relevant for now.
402 */
403
404 int curThreadNode = ss.getQuarkRelativeAndAdd(getNodeThreads(ss), String.valueOf(tid));
405
406 /* Set the process' name */
407 quark = ss.getQuarkRelativeAndAdd(curThreadNode, Attributes.EXEC_NAME);
408 if (ss.queryOngoingState(quark).isNull()) {
409 /* If the value didn't exist previously, set it */
410 value = TmfStateValue.newValueString(name);
411 ss.modifyAttribute(ts, value, quark);
412 }
413
414 /* Set the process' PPID */
415 quark = ss.getQuarkRelativeAndAdd(curThreadNode, Attributes.PPID);
416 if (ss.queryOngoingState(quark).isNull()) {
417 if (pid == tid) {
418 /* We have a process. Use the 'PPID' field. */
419 value = TmfStateValue.newValueInt(ppid);
420 } else {
421 /* We have a thread, use the 'PID' field for the parent. */
422 value = TmfStateValue.newValueInt(pid);
423 }
424 ss.modifyAttribute(ts, value, quark);
425 }
426
427 /* Set the process' status */
428 quark = ss.getQuarkRelativeAndAdd(curThreadNode, Attributes.STATUS);
429 if (ss.queryOngoingState(quark).isNull()) {
430 /* "2" here means "WAIT_FOR_CPU", and "5" "WAIT_BLOCKED" in the LTTng kernel. */
431 if (status == 2) {
432 value = StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE;
433 } else if (status == 5) {
434 value = StateValues.PROCESS_STATUS_WAIT_BLOCKED_VALUE;
435 } else {
436 value = StateValues.PROCESS_STATUS_UNKNOWN_VALUE;
437 }
438 ss.modifyAttribute(ts, value, quark);
439 }
440 }
441 break;
442
443 case SCHED_WAKEUP_INDEX:
444 {
445 final int tid = ((Long) event.getContent().getField(fLayout.fieldTid()).getValue()).intValue();
446 final int threadNode = ss.getQuarkRelativeAndAdd(getNodeThreads(ss), String.valueOf(tid));
447
448 /*
449 * The process indicated in the event's payload is now ready to
450 * run. Assign it to the "wait for cpu" state, but only if it
451 * was not already running.
452 */
453 quark = ss.getQuarkRelativeAndAdd(threadNode, Attributes.STATUS);
454 int status = ss.queryOngoingState(quark).unboxInt();
455
456 if (status != StateValues.PROCESS_STATUS_RUN_SYSCALL &&
457 status != StateValues.PROCESS_STATUS_RUN_USERMODE) {
458 value = StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE;
459 ss.modifyAttribute(ts, value, quark);
460 }
461 }
462 break;
463
464 default:
465 /* Other event types not covered by the main switch */
466 {
467 if (eventName.startsWith(fLayout.eventSyscallEntryPrefix())
468 || eventName.startsWith(fLayout.eventCompatSyscallEntryPrefix())) {
469
470 /* Assign the new system call to the process */
471 quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
472 value = TmfStateValue.newValueString(eventName);
473 ss.modifyAttribute(ts, value, quark);
474
475 /* Put the process in system call mode */
476 quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
477 value = StateValues.PROCESS_STATUS_RUN_SYSCALL_VALUE;
478 ss.modifyAttribute(ts, value, quark);
479
480 /* Put the CPU in system call (kernel) mode */
481 quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
482 value = StateValues.CPU_STATUS_RUN_SYSCALL_VALUE;
483 ss.modifyAttribute(ts, value, quark);
484
485 } else if (eventName.startsWith(fLayout.eventSyscallExitPrefix())) {
486
487 /* Clear the current system call on the process */
488 quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
489 value = TmfStateValue.nullValue();
490 ss.modifyAttribute(ts, value, quark);
491
492 /* Put the process' status back to user mode */
493 quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
494 value = StateValues.PROCESS_STATUS_RUN_USERMODE_VALUE;
495 ss.modifyAttribute(ts, value, quark);
496
497 /* Put the CPU's status back to user mode */
498 quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
499 value = StateValues.CPU_STATUS_RUN_USERMODE_VALUE;
500 ss.modifyAttribute(ts, value, quark);
501 }
502
503 }
504 break;
505 } // End of big switch
506
507 } catch (AttributeNotFoundException ae) {
508 /*
509 * This would indicate a problem with the logic of the manager here,
510 * so it shouldn't happen.
511 */
512 ae.printStackTrace();
513
514 } catch (TimeRangeException tre) {
515 /*
516 * This would happen if the events in the trace aren't ordered
517 * chronologically, which should never be the case ...
518 */
519 System.err.println("TimeRangeExcpetion caught in the state system's event manager."); //$NON-NLS-1$
520 System.err.println("Are the events in the trace correctly ordered?"); //$NON-NLS-1$
521 tre.printStackTrace();
522
523 } catch (StateValueTypeException sve) {
524 /*
525 * This would happen if we were trying to push/pop attributes not of
526 * type integer. Which, once again, should never happen.
527 */
528 sve.printStackTrace();
529 }
530 }
531
532 // ------------------------------------------------------------------------
533 // Convenience methods for commonly-used attribute tree locations
534 // ------------------------------------------------------------------------
535
536 private static int getNodeCPUs(ITmfStateSystemBuilder ssb) {
537 return ssb.getQuarkAbsoluteAndAdd(Attributes.CPUS);
538 }
539
540 private static int getNodeThreads(ITmfStateSystemBuilder ssb) {
541 return ssb.getQuarkAbsoluteAndAdd(Attributes.THREADS);
542 }
543
544 private static int getNodeIRQs(ITmfStateSystemBuilder ssb) {
545 return ssb.getQuarkAbsoluteAndAdd(Attributes.RESOURCES, Attributes.IRQS);
546 }
547
548 private static int getNodeSoftIRQs(ITmfStateSystemBuilder ssb) {
549 return ssb.getQuarkAbsoluteAndAdd(Attributes.RESOURCES, Attributes.SOFT_IRQS);
550 }
551
552 // ------------------------------------------------------------------------
553 // Advanced state-setting methods
554 // ------------------------------------------------------------------------
555
556 /**
557 * When we want to set a process back to a "running" state, first check
558 * its current System_call attribute. If there is a system call active, we
559 * put the process back in the syscall state. If not, we put it back in
560 * user mode state.
561 */
562 private static void setProcessToRunning(ITmfStateSystemBuilder ssb, long ts, int currentThreadNode)
563 throws AttributeNotFoundException, TimeRangeException,
564 StateValueTypeException {
565 int quark;
566 ITmfStateValue value;
567
568 quark = ssb.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
569 if (ssb.queryOngoingState(quark).isNull()) {
570 /* We were in user mode before the interruption */
571 value = StateValues.PROCESS_STATUS_RUN_USERMODE_VALUE;
572 } else {
573 /* We were previously in kernel mode */
574 value = StateValues.PROCESS_STATUS_RUN_SYSCALL_VALUE;
575 }
576 quark = ssb.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
577 ssb.modifyAttribute(ts, value, quark);
578 }
579
580 /**
581 * Similar logic as above, but to set the CPU's status when it's coming out
582 * of an interruption.
583 */
584 private static void cpuExitInterrupt(ITmfStateSystemBuilder ssb, long ts,
585 int currentCpuNode, int currentThreadNode)
586 throws StateValueTypeException, AttributeNotFoundException,
587 TimeRangeException {
588 int quark;
589 ITmfStateValue value;
590
591 quark = ssb.getQuarkRelativeAndAdd(currentCpuNode, Attributes.CURRENT_THREAD);
592 if (ssb.queryOngoingState(quark).unboxInt() > 0) {
593 /* There was a process on the CPU */
594 quark = ssb.getQuarkRelative(currentThreadNode, Attributes.SYSTEM_CALL);
595 if (ssb.queryOngoingState(quark).isNull()) {
596 /* That process was in user mode */
597 value = StateValues.CPU_STATUS_RUN_USERMODE_VALUE;
598 } else {
599 /* That process was in a system call */
600 value = StateValues.CPU_STATUS_RUN_SYSCALL_VALUE;
601 }
602 } else {
603 /* There was no real process scheduled, CPU was idle */
604 value = StateValues.CPU_STATUS_IDLE_VALUE;
605 }
606 quark = ssb.getQuarkRelativeAndAdd(currentCpuNode, Attributes.STATUS);
607 ssb.modifyAttribute(ts, value, quark);
608 }
609 }
This page took 0.044643 seconds and 5 git commands to generate.