os.linux: Rename the "kernelanalysis" package to just "kernel"
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.os.linux.core / src / org / eclipse / tracecompass / internal / analysis / os / linux / core / kernel / handlers / SchedSwitchHandler.java
CommitLineData
c8f45ad2
MK
1/*******************************************************************************
2 * Copyright (c) 2015 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Matthew Khouzam - Initial API and implementation
11 *******************************************************************************/
12
13package org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers;
14
15import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
16
0f7a12d3
AM
17import org.eclipse.tracecompass.analysis.os.linux.core.kernel.Attributes;
18import org.eclipse.tracecompass.analysis.os.linux.core.kernel.LinuxValues;
19import org.eclipse.tracecompass.analysis.os.linux.core.kernel.StateValues;
c8f45ad2
MK
20import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout;
21import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
22import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
23import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
24import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
25import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
26import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
27
28/**
29 * Scheduler switch event handler
30 */
31public class SchedSwitchHandler extends KernelEventHandler {
32
33 /**
34 * Constructor
35 *
36 * @param layout
37 * event layout
38 */
39 public SchedSwitchHandler(IKernelAnalysisEventLayout layout) {
40 super(layout);
41 }
42
43 @Override
44 public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException {
45 Integer cpu = KernelEventHandlerUtils.getCpu(event);
46 if (cpu == null) {
47 return;
48 }
49
50 ITmfEventField content = event.getContent();
51 Integer prevTid = ((Long) content.getField(getLayout().fieldPrevTid()).getValue()).intValue();
52 Long prevState = checkNotNull((Long) content.getField(getLayout().fieldPrevState()).getValue());
53 String nextProcessName = checkNotNull((String) content.getField(getLayout().fieldNextComm()).getValue());
54 Integer nextTid = ((Long) content.getField(getLayout().fieldNextTid()).getValue()).intValue();
55 Integer nextPrio = ((Long) content.getField(getLayout().fieldNextPrio()).getValue()).intValue();
56
57 int nodeThreads = KernelEventHandlerUtils.getNodeThreads(ss);
58 int formerThreadNode = ss.getQuarkRelativeAndAdd(nodeThreads, prevTid.toString());
59 int newCurrentThreadNode = ss.getQuarkRelativeAndAdd(nodeThreads, nextTid.toString());
60
61 long timestamp = KernelEventHandlerUtils.getTimestamp(event);
62 /* Set the status of the process that got scheduled out. */
63 setOldProcessStatus(ss, prevState, formerThreadNode, timestamp);
64
65 /* Set the status of the new scheduled process */
66 KernelEventHandlerUtils.setProcessToRunning(timestamp, newCurrentThreadNode, ss);
67
68 /* Set the exec name of the new process */
69 setNewProcessExecName(ss, nextProcessName, newCurrentThreadNode, timestamp);
70
71 /* Set the current prio for the new process */
72 setNewProcessPio(ss, nextPrio, newCurrentThreadNode, timestamp);
73
74 /* Make sure the PPID and system_call sub-attributes exist */
75 ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.SYSTEM_CALL);
76 ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.PPID);
77
78 /* Set the current scheduled process on the relevant CPU */
79 int currentCPUNode = KernelEventHandlerUtils.getCurrentCPUNode(cpu, ss);
80 setCpuProcess(ss, nextTid, timestamp, currentCPUNode);
81
82 /* Set the status of the CPU itself */
83 setCpuStatus(ss, nextTid, newCurrentThreadNode, timestamp, currentCPUNode);
84 }
85
86 private static void setOldProcessStatus(ITmfStateSystemBuilder ss, Long prevState, Integer formerThreadNode, long timestamp) throws AttributeNotFoundException {
87 ITmfStateValue value;
88 /*
978a610e
MK
89 * Empirical observations and look into the linux code have shown that
90 * the TASK_STATE_MAX flag is used internally and |'ed with other
91 * states, most often the running state, so it is ignored from the
92 * prevState value.
c8f45ad2
MK
93 */
94 int state = (int) (prevState & ~(LinuxValues.TASK_STATE_MAX));
95
978a610e 96 if (isRunning(state)) {
c8f45ad2 97 value = StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE;
978a610e 98 } else if (isWaiting(state)) {
c8f45ad2 99 value = StateValues.PROCESS_STATUS_WAIT_BLOCKED_VALUE;
978a610e 100 } else if (isDead(state)) {
c8f45ad2 101 value = TmfStateValue.nullValue();
978a610e 102 } else {
c8f45ad2 103 value = StateValues.PROCESS_STATUS_WAIT_UNKNOWN_VALUE;
c8f45ad2
MK
104 }
105 int quark = ss.getQuarkRelativeAndAdd(formerThreadNode, Attributes.STATUS);
106 ss.modifyAttribute(timestamp, value, quark);
107
108 }
109
978a610e
MK
110 private static boolean isDead(int state) {
111 return (state & LinuxValues.TASK_DEAD) != 0;
112 }
113
114 private static boolean isWaiting(int state) {
115 return (state & (LinuxValues.TASK_INTERRUPTIBLE | LinuxValues.TASK_UNINTERRUPTIBLE)) != 0;
116 }
117
118 private static boolean isRunning(int state) {
119 // special case, this means ALL STATES ARE 0
120 // this is effectively an anti-state
121 return state == 0;
122 }
123
c8f45ad2
MK
124 private static void setCpuStatus(ITmfStateSystemBuilder ss, Integer nextTid, Integer newCurrentThreadNode, long timestamp, int currentCPUNode) throws AttributeNotFoundException {
125 int quark;
126 ITmfStateValue value;
127 if (nextTid > 0) {
128 /* Check if the entering process is in kernel or user mode */
129 quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.SYSTEM_CALL);
130 ITmfStateValue queryOngoingState = ss.queryOngoingState(quark);
131 if (queryOngoingState.isNull()) {
132 value = StateValues.CPU_STATUS_RUN_USERMODE_VALUE;
133 } else {
134 value = StateValues.CPU_STATUS_RUN_SYSCALL_VALUE;
135 }
136 } else {
137 value = StateValues.CPU_STATUS_IDLE_VALUE;
138 }
139 quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
140 ss.modifyAttribute(timestamp, value, quark);
141 }
142
143 private static void setCpuProcess(ITmfStateSystemBuilder ss, Integer nextTid, long timestamp, int currentCPUNode) throws AttributeNotFoundException {
144 int quark;
145 ITmfStateValue value;
146 quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.CURRENT_THREAD);
147 value = TmfStateValue.newValueInt(nextTid);
148 ss.modifyAttribute(timestamp, value, quark);
149 }
150
151 private static void setNewProcessPio(ITmfStateSystemBuilder ss, Integer nextPrio, Integer newCurrentThreadNode, long timestamp) throws AttributeNotFoundException {
152 int quark;
153 ITmfStateValue value;
154 quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.PRIO);
155 value = TmfStateValue.newValueInt(nextPrio);
156 ss.modifyAttribute(timestamp, value, quark);
157 }
158
159 private static void setNewProcessExecName(ITmfStateSystemBuilder ss, String nextProcessName, Integer newCurrentThreadNode, long timestamp) throws AttributeNotFoundException {
160 int quark;
161 ITmfStateValue value;
162 quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.EXEC_NAME);
163 value = TmfStateValue.newValueString(nextProcessName);
164 ss.modifyAttribute(timestamp, value, quark);
165 }
166
167}
This page took 0.051465 seconds and 5 git commands to generate.