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
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
42d5b5f2 13package org.eclipse.tracecompass.lttng2.kernel.core.analysis.kernel;
efc403bb 14
d0c7e4ba
AM
15import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
16
7411cd67
AM
17import java.util.Map;
18
19import org.eclipse.jdt.annotation.NonNull;
9bc60be7 20import org.eclipse.tracecompass.internal.lttng2.kernel.core.Attributes;
9bc60be7 21import org.eclipse.tracecompass.internal.lttng2.kernel.core.StateValues;
7411cd67 22import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.IKernelAnalysisEventLayout;
e894a508
AM
23import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
24import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
25import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
26import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
27import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
28import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
2bdf0193
AM
29import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
30import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
1786026d 31import org.eclipse.tracecompass.tmf.core.event.aspect.TmfCpuAspect;
2bdf0193
AM
32import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider;
33import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
1786026d 34import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
efc403bb 35
7411cd67
AM
36import com.google.common.collect.ImmutableMap;
37
efc403bb
AM
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.
d85d2a6d 41 *
efc403bb 42 * It uses the reference handler defined in CTFKernelHandler.java.
d85d2a6d 43 *
efc403bb 44 * @author alexmont
d85d2a6d 45 *
efc403bb 46 */
d3ba47d4 47public class LttngKernelStateProvider extends AbstractTmfStateProvider {
efc403bb 48
7411cd67
AM
49 // ------------------------------------------------------------------------
50 // Static fields
51 // ------------------------------------------------------------------------
52
a96cc6be
AM
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 */
acba092b 57 private static final int VERSION = 5;
a96cc6be 58
7411cd67
AM
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
6383e95d
AM
79 // ------------------------------------------------------------------------
80 // Constructor
81 // ------------------------------------------------------------------------
efc403bb
AM
82
83 /**
84 * Instantiate a new state provider plugin.
d85d2a6d
AM
85 *
86 * @param trace
efc403bb 87 * The LTTng 2.0 kernel trace directory
7411cd67
AM
88 * @param layout
89 * The event layout to use for this state provider. Usually
90 * depending on the tracer implementation.
efc403bb 91 */
d0c7e4ba 92 public LttngKernelStateProvider(@NonNull ITmfTrace trace, @NonNull IKernelAnalysisEventLayout layout) {
7411cd67
AM
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
7411cd67
AM
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);
bd0e2f70
AM
114
115 if (layout.eventStatedumpProcessState() != null) {
116 builder.put(layout.eventStatedumpProcessState(), STATEDUMP_PROCESS_STATE_INDEX);
117 }
7411cd67
AM
118
119 for (String eventSchedWakeup : layout.eventsSchedWakeup()) {
120 builder.put(eventSchedWakeup, SCHED_WAKEUP_INDEX);
121 }
122
123 return builder.build();
2c2f900e 124 }
efc403bb 125
6383e95d
AM
126 // ------------------------------------------------------------------------
127 // IStateChangeInput
128 // ------------------------------------------------------------------------
129
a96cc6be
AM
130 @Override
131 public int getVersion() {
132 return VERSION;
133 }
134
2c2f900e 135 @Override
f1f86dfb 136 public void assignTargetStateSystem(ITmfStateSystemBuilder ssb) {
79e0a1df
AM
137 /* We can only set up the locations once the state system is assigned */
138 super.assignTargetStateSystem(ssb);
2c2f900e 139 }
efc403bb 140
e96ab5c4 141 @Override
d3ba47d4 142 public LttngKernelStateProvider getNewInstance() {
7411cd67 143 return new LttngKernelStateProvider(this.getTrace(), fLayout);
e96ab5c4
AM
144 }
145
efc403bb 146 @Override
1786026d 147 protected void eventHandle(ITmfEvent event) {
d0c7e4ba
AM
148 ITmfStateSystemBuilder ss = checkNotNull(getStateSystemBuilder());
149
1786026d
GB
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 */
e1de2fd4
AM
160 return;
161 }
79e0a1df 162
33803b9b 163 final String eventName = event.getType().getName();
79e0a1df
AM
164 final long ts = event.getTimestamp().getValue();
165
2c2f900e 166 try {
79e0a1df 167 /* Shortcut for the "current CPU" attribute node */
d0c7e4ba 168 final int currentCPUNode = ss.getQuarkRelativeAndAdd(getNodeCPUs(ss), cpu.toString());
79e0a1df
AM
169
170 /*
171 * Shortcut for the "current thread" attribute node. It requires
172 * querying the current CPU's current thread.
173 */
3ae73cfa
AM
174 int quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.CURRENT_THREAD);
175 ITmfStateValue value = ss.queryOngoingState(quark);
359eeba0 176 int thread = value.isNull() ? -1 : value.unboxInt();
d0c7e4ba 177 final int currentThreadNode = ss.getQuarkRelativeAndAdd(getNodeThreads(ss), String.valueOf(thread));
79e0a1df
AM
178
179 /*
180 * Feed event to the history system if it's known to cause a state
181 * transition.
182 */
7411cd67
AM
183 Integer idx = fEventNames.get(eventName);
184 int intval = (idx == null ? -1 : idx.intValue());
185 switch (intval) {
79e0a1df 186
7411cd67 187 case IRQ_HANDLER_ENTRY_INDEX:
79e0a1df 188 {
7411cd67 189 Integer irqId = ((Long) event.getContent().getField(fLayout.fieldIrq()).getValue()).intValue();
79e0a1df
AM
190
191 /* Mark this IRQ as active in the resource tree.
192 * The state value = the CPU on which this IRQ is sitting */
d0c7e4ba 193 quark = ss.getQuarkRelativeAndAdd(getNodeIRQs(ss), irqId.toString());
1786026d 194 value = TmfStateValue.newValueInt(cpu.intValue());
79e0a1df
AM
195 ss.modifyAttribute(ts, value, quark);
196
197 /* Change the status of the running process to interrupted */
198 quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
dfb27cee 199 value = StateValues.PROCESS_STATUS_INTERRUPTED_VALUE;
79e0a1df
AM
200 ss.modifyAttribute(ts, value, quark);
201
202 /* Change the status of the CPU to interrupted */
203 quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
dfb27cee 204 value = StateValues.CPU_STATUS_IRQ_VALUE;
79e0a1df
AM
205 ss.modifyAttribute(ts, value, quark);
206 }
207 break;
208
7411cd67 209 case IRQ_HANDLER_EXIT_INDEX:
79e0a1df 210 {
7411cd67 211 Integer irqId = ((Long) event.getContent().getField(fLayout.fieldIrq()).getValue()).intValue();
79e0a1df
AM
212
213 /* Put this IRQ back to inactive in the resource tree */
d0c7e4ba 214 quark = ss.getQuarkRelativeAndAdd(getNodeIRQs(ss), irqId.toString());
79e0a1df
AM
215 value = TmfStateValue.nullValue();
216 ss.modifyAttribute(ts, value, quark);
217
218 /* Set the previous process back to running */
d0c7e4ba 219 setProcessToRunning(ss, ts, currentThreadNode);
79e0a1df
AM
220
221 /* Set the CPU status back to running or "idle" */
d0c7e4ba 222 cpuExitInterrupt(ss, ts, currentCPUNode, currentThreadNode);
79e0a1df
AM
223 }
224 break;
225
7411cd67 226 case SOFT_IRQ_ENTRY_INDEX:
79e0a1df 227 {
7411cd67 228 Integer softIrqId = ((Long) event.getContent().getField(fLayout.fieldVec()).getValue()).intValue();
79e0a1df
AM
229
230 /* Mark this SoftIRQ as active in the resource tree.
231 * The state value = the CPU on which this SoftIRQ is processed */
d0c7e4ba 232 quark = ss.getQuarkRelativeAndAdd(getNodeSoftIRQs(ss), softIrqId.toString());
1786026d 233 value = TmfStateValue.newValueInt(cpu.intValue());
79e0a1df
AM
234 ss.modifyAttribute(ts, value, quark);
235
236 /* Change the status of the running process to interrupted */
237 quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
dfb27cee 238 value = StateValues.PROCESS_STATUS_INTERRUPTED_VALUE;
79e0a1df
AM
239 ss.modifyAttribute(ts, value, quark);
240
241 /* Change the status of the CPU to interrupted */
242 quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
dfb27cee 243 value = StateValues.CPU_STATUS_SOFTIRQ_VALUE;
79e0a1df
AM
244 ss.modifyAttribute(ts, value, quark);
245 }
246 break;
247
7411cd67 248 case SOFT_IRQ_EXIT_INDEX:
79e0a1df 249 {
7411cd67 250 Integer softIrqId = ((Long) event.getContent().getField(fLayout.fieldVec()).getValue()).intValue();
79e0a1df
AM
251
252 /* Put this SoftIRQ back to inactive (= -1) in the resource tree */
d0c7e4ba 253 quark = ss.getQuarkRelativeAndAdd(getNodeSoftIRQs(ss), softIrqId.toString());
79e0a1df
AM
254 value = TmfStateValue.nullValue();
255 ss.modifyAttribute(ts, value, quark);
256
257 /* Set the previous process back to running */
d0c7e4ba 258 setProcessToRunning(ss, ts, currentThreadNode);
79e0a1df
AM
259
260 /* Set the CPU status back to "busy" or "idle" */
d0c7e4ba 261 cpuExitInterrupt(ss, ts, currentCPUNode, currentThreadNode);
79e0a1df
AM
262 }
263 break;
264
7411cd67 265 case SOFT_IRQ_RAISE_INDEX:
79e0a1df
AM
266 /* Fields: int32 vec */
267 {
7411cd67 268 Integer softIrqId = ((Long) event.getContent().getField(fLayout.fieldVec()).getValue()).intValue();
79e0a1df
AM
269
270 /* Mark this SoftIRQ as *raised* in the resource tree.
271 * State value = -2 */
d0c7e4ba 272 quark = ss.getQuarkRelativeAndAdd(getNodeSoftIRQs(ss), softIrqId.toString());
dfb27cee 273 value = StateValues.SOFT_IRQ_RAISED_VALUE;
79e0a1df
AM
274 ss.modifyAttribute(ts, value, quark);
275 }
276 break;
277
7411cd67 278 case SCHED_SWITCH_INDEX:
79e0a1df 279 {
7a2f04a6 280 ITmfEventField content = event.getContent();
7411cd67
AM
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();
79e0a1df 285
d0c7e4ba
AM
286 Integer formerThreadNode = ss.getQuarkRelativeAndAdd(getNodeThreads(ss), prevTid.toString());
287 Integer newCurrentThreadNode = ss.getQuarkRelativeAndAdd(getNodeThreads(ss), nextTid.toString());
79e0a1df
AM
288
289 /* Set the status of the process that got scheduled out. */
290 quark = ss.getQuarkRelativeAndAdd(formerThreadNode, Attributes.STATUS);
f2338178 291 if (prevState != 0) {
dfb27cee 292 value = StateValues.PROCESS_STATUS_WAIT_BLOCKED_VALUE;
f2338178 293 } else {
dfb27cee 294 value = StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE;
f2338178 295 }
79e0a1df
AM
296 ss.modifyAttribute(ts, value, quark);
297
298 /* Set the status of the new scheduled process */
d0c7e4ba 299 setProcessToRunning(ss, ts, newCurrentThreadNode);
79e0a1df
AM
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
25e43749
AM
306 /* Make sure the PPID and system_call sub-attributes exist */
307 ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.SYSTEM_CALL);
308 ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.PPID);
79e0a1df
AM
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()) {
dfb27cee 320 value = StateValues.CPU_STATUS_RUN_USERMODE_VALUE;
79e0a1df 321 } else {
dfb27cee 322 value = StateValues.CPU_STATUS_RUN_SYSCALL_VALUE;
79e0a1df
AM
323 }
324 } else {
dfb27cee 325 value = StateValues.CPU_STATUS_IDLE_VALUE;
79e0a1df
AM
326 }
327 quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
328 ss.modifyAttribute(ts, value, quark);
329 }
330 break;
331
7411cd67 332 case SCHED_PROCESS_FORK_INDEX:
79e0a1df 333 {
7a2f04a6 334 ITmfEventField content = event.getContent();
79e0a1df 335 // String parentProcessName = (String) event.getFieldValue("parent_comm");
7411cd67 336 String childProcessName = (String) content.getField(fLayout.fieldChildComm()).getValue();
79e0a1df
AM
337 // assert ( parentProcessName.equals(childProcessName) );
338
7411cd67
AM
339 Integer parentTid = ((Long) content.getField(fLayout.fieldParentTid()).getValue()).intValue();
340 Integer childTid = ((Long) content.getField(fLayout.fieldChildTid()).getValue()).intValue();
79e0a1df 341
d0c7e4ba
AM
342 Integer parentTidNode = ss.getQuarkRelativeAndAdd(getNodeThreads(ss), parentTid.toString());
343 Integer childTidNode = ss.getQuarkRelativeAndAdd(getNodeThreads(ss), childTid.toString());
79e0a1df
AM
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);
dfb27cee 357 value = StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE;
79e0a1df
AM
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);
b46ea93c
AM
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 */
7411cd67 368 value = TmfStateValue.newValueString(fLayout.eventSyscallEntryPrefix() + IKernelAnalysisEventLayout.INITIAL_SYSCALL_NAME);
b46ea93c 369 }
79e0a1df
AM
370 quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.SYSTEM_CALL);
371 ss.modifyAttribute(ts, value, quark);
372 }
373 break;
374
7411cd67 375 case SCHED_PROCESS_EXIT_INDEX:
79e0a1df
AM
376 break;
377
7411cd67 378 case SCHED_PROCESS_FREE_INDEX:
79e0a1df 379 {
7411cd67 380 Integer tid = ((Long) event.getContent().getField(fLayout.fieldTid()).getValue()).intValue();
79e0a1df
AM
381 /*
382 * Remove the process and all its sub-attributes from the
383 * current state
384 */
d0c7e4ba 385 quark = ss.getQuarkRelativeAndAdd(getNodeThreads(ss), tid.toString());
79e0a1df
AM
386 ss.removeAttribute(ts, quark);
387 }
388 break;
389
7411cd67
AM
390 case STATEDUMP_PROCESS_STATE_INDEX:
391 /* LTTng-specific */
79e0a1df 392 {
7a2f04a6 393 ITmfEventField content = event.getContent();
7411cd67
AM
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$
79e0a1df
AM
399 /*
400 * "mode" could be interesting too, but it doesn't seem to be
401 * populated with anything relevant for now.
402 */
403
d0c7e4ba 404 int curThreadNode = ss.getQuarkRelativeAndAdd(getNodeThreads(ss), String.valueOf(tid));
79e0a1df
AM
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()) {
bc19bff3
AM
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 }
79e0a1df
AM
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()) {
f2338178
MD
430 /* "2" here means "WAIT_FOR_CPU", and "5" "WAIT_BLOCKED" in the LTTng kernel. */
431 if (status == 2) {
dfb27cee 432 value = StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE;
f2338178 433 } else if (status == 5) {
dfb27cee 434 value = StateValues.PROCESS_STATUS_WAIT_BLOCKED_VALUE;
79e0a1df 435 } else {
dfb27cee 436 value = StateValues.PROCESS_STATUS_UNKNOWN_VALUE;
79e0a1df
AM
437 }
438 ss.modifyAttribute(ts, value, quark);
439 }
440 }
441 break;
442
7411cd67 443 case SCHED_WAKEUP_INDEX:
d1b933e7 444 {
7411cd67 445 final int tid = ((Long) event.getContent().getField(fLayout.fieldTid()).getValue()).intValue();
d0c7e4ba 446 final int threadNode = ss.getQuarkRelativeAndAdd(getNodeThreads(ss), String.valueOf(tid));
d1b933e7
AM
447
448 /*
449 * The process indicated in the event's payload is now ready to
3d6e6112
FR
450 * run. Assign it to the "wait for cpu" state, but only if it
451 * was not already running.
d1b933e7
AM
452 */
453 quark = ss.getQuarkRelativeAndAdd(threadNode, Attributes.STATUS);
3d6e6112
FR
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 }
d1b933e7
AM
461 }
462 break;
463
79e0a1df
AM
464 default:
465 /* Other event types not covered by the main switch */
466 {
7411cd67
AM
467 if (eventName.startsWith(fLayout.eventSyscallEntryPrefix())
468 || eventName.startsWith(fLayout.eventCompatSyscallEntryPrefix())) {
79e0a1df
AM
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);
dfb27cee 477 value = StateValues.PROCESS_STATUS_RUN_SYSCALL_VALUE;
79e0a1df
AM
478 ss.modifyAttribute(ts, value, quark);
479
480 /* Put the CPU in system call (kernel) mode */
481 quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
dfb27cee 482 value = StateValues.CPU_STATUS_RUN_SYSCALL_VALUE;
79e0a1df 483 ss.modifyAttribute(ts, value, quark);
acba092b
AM
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);
79e0a1df 501 }
acba092b 502
79e0a1df
AM
503 }
504 break;
505 } // End of big switch
506
79e0a1df
AM
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();
2c2f900e
AM
529 }
530 }
531
6383e95d
AM
532 // ------------------------------------------------------------------------
533 // Convenience methods for commonly-used attribute tree locations
534 // ------------------------------------------------------------------------
535
d0c7e4ba
AM
536 private static int getNodeCPUs(ITmfStateSystemBuilder ssb) {
537 return ssb.getQuarkAbsoluteAndAdd(Attributes.CPUS);
79e0a1df
AM
538 }
539
d0c7e4ba
AM
540 private static int getNodeThreads(ITmfStateSystemBuilder ssb) {
541 return ssb.getQuarkAbsoluteAndAdd(Attributes.THREADS);
6383e95d
AM
542 }
543
d0c7e4ba
AM
544 private static int getNodeIRQs(ITmfStateSystemBuilder ssb) {
545 return ssb.getQuarkAbsoluteAndAdd(Attributes.RESOURCES, Attributes.IRQS);
6383e95d
AM
546 }
547
d0c7e4ba
AM
548 private static int getNodeSoftIRQs(ITmfStateSystemBuilder ssb) {
549 return ssb.getQuarkAbsoluteAndAdd(Attributes.RESOURCES, Attributes.SOFT_IRQS);
6383e95d
AM
550 }
551
6383e95d
AM
552 // ------------------------------------------------------------------------
553 // Advanced state-setting methods
554 // ------------------------------------------------------------------------
555
79e0a1df
AM
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 */
d0c7e4ba 562 private static void setProcessToRunning(ITmfStateSystemBuilder ssb, long ts, int currentThreadNode)
79e0a1df
AM
563 throws AttributeNotFoundException, TimeRangeException,
564 StateValueTypeException {
565 int quark;
566 ITmfStateValue value;
567
d0c7e4ba
AM
568 quark = ssb.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
569 if (ssb.queryOngoingState(quark).isNull()) {
79e0a1df 570 /* We were in user mode before the interruption */
dfb27cee 571 value = StateValues.PROCESS_STATUS_RUN_USERMODE_VALUE;
79e0a1df
AM
572 } else {
573 /* We were previously in kernel mode */
dfb27cee 574 value = StateValues.PROCESS_STATUS_RUN_SYSCALL_VALUE;
79e0a1df 575 }
d0c7e4ba
AM
576 quark = ssb.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
577 ssb.modifyAttribute(ts, value, quark);
79e0a1df
AM
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 */
d0c7e4ba
AM
584 private static void cpuExitInterrupt(ITmfStateSystemBuilder ssb, long ts,
585 int currentCpuNode, int currentThreadNode)
79e0a1df
AM
586 throws StateValueTypeException, AttributeNotFoundException,
587 TimeRangeException {
588 int quark;
589 ITmfStateValue value;
590
d0c7e4ba
AM
591 quark = ssb.getQuarkRelativeAndAdd(currentCpuNode, Attributes.CURRENT_THREAD);
592 if (ssb.queryOngoingState(quark).unboxInt() > 0) {
79e0a1df 593 /* There was a process on the CPU */
d0c7e4ba
AM
594 quark = ssb.getQuarkRelative(currentThreadNode, Attributes.SYSTEM_CALL);
595 if (ssb.queryOngoingState(quark).isNull()) {
79e0a1df 596 /* That process was in user mode */
dfb27cee 597 value = StateValues.CPU_STATUS_RUN_USERMODE_VALUE;
79e0a1df
AM
598 } else {
599 /* That process was in a system call */
dfb27cee 600 value = StateValues.CPU_STATUS_RUN_SYSCALL_VALUE;
79e0a1df
AM
601 }
602 } else {
603 /* There was no real process scheduled, CPU was idle */
dfb27cee 604 value = StateValues.CPU_STATUS_IDLE_VALUE;
2c2f900e 605 }
d0c7e4ba
AM
606 quark = ssb.getQuarkRelativeAndAdd(currentCpuNode, Attributes.STATUS);
607 ssb.modifyAttribute(ts, value, quark);
efc403bb
AM
608 }
609}
This page took 0.084444 seconds and 5 git commands to generate.