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