94a9933a549cf59f13c7f9c5e68600010c15ac95
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.os.linux.core / src / org / eclipse / tracecompass / internal / analysis / os / linux / core / kernel / KernelStateProvider.java
1 /*******************************************************************************
2 * Copyright (c) 2012, 2015 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.internal.analysis.os.linux.core.kernel;
14
15 import java.util.Map;
16
17 import org.eclipse.jdt.annotation.Nullable;
18 import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout;
19 import org.eclipse.tracecompass.common.core.NonNullUtils;
20 import org.eclipse.tracecompass.internal.analysis.os.linux.core.Activator;
21 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers.IPIEntryHandler;
22 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers.IPIExitHandler;
23 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers.IrqEntryHandler;
24 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers.IrqExitHandler;
25 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers.KernelEventHandler;
26 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers.PiSetprioHandler;
27 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers.ProcessExitHandler;
28 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers.ProcessForkHandler;
29 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers.ProcessFreeHandler;
30 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers.SchedSwitchHandler;
31 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers.SchedWakeupHandler;
32 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers.SoftIrqEntryHandler;
33 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers.SoftIrqExitHandler;
34 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers.SoftIrqRaiseHandler;
35 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers.StateDumpHandler;
36 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers.SysEntryHandler;
37 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers.SysExitHandler;
38 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
39 import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
40 import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
41 import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
42 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
43 import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider;
44 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
45
46 import com.google.common.collect.ImmutableMap;
47
48 /**
49 * This is the state change input plugin for the state system which handles the
50 * kernel traces.
51 *
52 * Attribute tree:
53 *
54 * <pre>
55 * |- CPUs
56 * | |- <CPU number> -> CPU Status
57 * | | |- CURRENT_THREAD
58 * | | |- SOFT_IRQS
59 * | | | |- <Soft IRQ number> -> Soft IRQ Status
60 * | | |- IRQS
61 * | | | |- <IRQ number> -> IRQ Status
62 * |- THREADS
63 * | |- <Thread number> -> Thread Status
64 * | | |- PPID
65 * | | |- EXEC_NAME
66 * | | |- PRIO
67 * | | |- SYSTEM_CALL
68 * </pre>
69 *
70 * @author Alexandre Montplaisir
71 */
72 public class KernelStateProvider extends AbstractTmfStateProvider {
73
74 // ------------------------------------------------------------------------
75 // Static fields
76 // ------------------------------------------------------------------------
77
78 /**
79 * Version number of this state provider. Please bump this if you modify the
80 * contents of the generated state history in some way.
81 */
82 private static final int VERSION = 21;
83
84 // ------------------------------------------------------------------------
85 // Fields
86 // ------------------------------------------------------------------------
87
88 private final Map<String, KernelEventHandler> fEventNames;
89 private final IKernelAnalysisEventLayout fLayout;
90
91 private final KernelEventHandler fSysEntryHandler;
92 private final KernelEventHandler fSysExitHandler;
93
94 // ------------------------------------------------------------------------
95 // Constructor
96 // ------------------------------------------------------------------------
97
98 /**
99 * Instantiate a new state provider plugin.
100 *
101 * @param trace
102 * The LTTng 2.0 kernel trace directory
103 * @param layout
104 * The event layout to use for this state provider. Usually
105 * depending on the tracer implementation.
106 */
107 public KernelStateProvider(ITmfTrace trace, IKernelAnalysisEventLayout layout) {
108 super(trace, "Kernel"); //$NON-NLS-1$
109 fLayout = layout;
110 fEventNames = buildEventNames(layout);
111
112 fSysEntryHandler = new SysEntryHandler(fLayout);
113 fSysExitHandler = new SysExitHandler(fLayout);
114 }
115
116 // ------------------------------------------------------------------------
117 // Event names management
118 // ------------------------------------------------------------------------
119
120 private static Map<String, KernelEventHandler> buildEventNames(IKernelAnalysisEventLayout layout) {
121 ImmutableMap.Builder<String, KernelEventHandler> builder = ImmutableMap.builder();
122
123 builder.put(layout.eventIrqHandlerEntry(), new IrqEntryHandler(layout));
124 builder.put(layout.eventIrqHandlerExit(), new IrqExitHandler(layout));
125 builder.put(layout.eventSoftIrqEntry(), new SoftIrqEntryHandler(layout));
126 builder.put(layout.eventSoftIrqExit(), new SoftIrqExitHandler(layout));
127 builder.put(layout.eventSoftIrqRaise(), new SoftIrqRaiseHandler(layout));
128 builder.put(layout.eventSchedSwitch(), new SchedSwitchHandler(layout));
129 builder.put(layout.eventSchedPiSetprio(), new PiSetprioHandler(layout));
130 builder.put(layout.eventSchedProcessFork(), new ProcessForkHandler(layout));
131 builder.put(layout.eventSchedProcessExit(), new ProcessExitHandler(layout));
132 builder.put(layout.eventSchedProcessFree(), new ProcessFreeHandler(layout));
133 for( String s : layout.getIPIIrqVectorsEntries()) {
134 builder.put(s, new IPIEntryHandler(layout));
135 }
136 for( String s : layout.getIPIIrqVectorsExits()) {
137 builder.put(s, new IPIExitHandler(layout));
138 }
139
140 final String eventStatedumpProcessState = layout.eventStatedumpProcessState();
141 if (eventStatedumpProcessState != null) {
142 builder.put(eventStatedumpProcessState, new StateDumpHandler(layout));
143 }
144
145 for (String eventSchedWakeup : layout.eventsSchedWakeup()) {
146 builder.put(eventSchedWakeup, new SchedWakeupHandler(layout));
147 }
148
149 return builder.build();
150 }
151
152 // ------------------------------------------------------------------------
153 // IStateChangeInput
154 // ------------------------------------------------------------------------
155
156 @Override
157 public int getVersion() {
158 return VERSION;
159 }
160
161 @Override
162 public KernelStateProvider getNewInstance() {
163 return new KernelStateProvider(this.getTrace(), fLayout);
164 }
165
166 @Override
167 protected void eventHandle(@Nullable ITmfEvent event) {
168 if (event == null) {
169 return;
170 }
171
172 final String eventName = event.getName();
173
174 try {
175 final ITmfStateSystemBuilder ss = NonNullUtils.checkNotNull(getStateSystemBuilder());
176 /*
177 * Feed event to the history system if it's known to cause a state
178 * transition.
179 */
180 KernelEventHandler handler = fEventNames.get(eventName);
181 if (handler == null) {
182 if (isSyscallExit(eventName)) {
183 handler = fSysExitHandler;
184 } else if (isSyscallEntry(eventName)) {
185 handler = fSysEntryHandler;
186 }
187 }
188 if (handler != null) {
189 handler.handleEvent(ss, event);
190 }
191
192 } catch (AttributeNotFoundException ae) {
193 /*
194 * This would indicate a problem with the logic of the manager here,
195 * so it shouldn't happen.
196 */
197 Activator.getDefault().logError("Attribute not found: " + ae.getMessage(), ae); //$NON-NLS-1$
198
199 } catch (TimeRangeException tre) {
200 /*
201 * This would happen if the events in the trace aren't ordered
202 * chronologically, which should never be the case ...
203 */
204 Activator.getDefault().logError("TimeRangeExcpetion caught in the state system's event manager.\n" + //$NON-NLS-1$
205 "Are the events in the trace correctly ordered?\n" + tre.getMessage(), tre); //$NON-NLS-1$
206
207 } catch (StateValueTypeException sve) {
208 /*
209 * This would happen if we were trying to push/pop attributes not of
210 * type integer. Which, once again, should never happen.
211 */
212 Activator.getDefault().logError("State value error: " + sve.getMessage(), sve); //$NON-NLS-1$
213 }
214 }
215
216 private boolean isSyscallEntry(String eventName) {
217 return (eventName.startsWith(fLayout.eventSyscallEntryPrefix())
218 || eventName.startsWith(fLayout.eventCompatSyscallEntryPrefix()));
219 }
220
221 private boolean isSyscallExit(String eventName) {
222 return (eventName.startsWith(fLayout.eventSyscallExitPrefix()) ||
223 eventName.startsWith(fLayout.eventCompatSyscallExitPrefix()));
224 }
225
226 }
This page took 0.036266 seconds and 4 git commands to generate.