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