Commit | Line | Data |
---|---|---|
af7f72ce FG |
1 | /******************************************************************************* |
2 | * Copyright (c) 2015 École Polytechnique de Montréal | |
3 | * | |
4 | * All rights reserved. This program and the accompanying materials are | |
5 | * made available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | *******************************************************************************/ | |
9 | ||
10 | package org.eclipse.tracecompass.internal.lttng2.kernel.core.analysis.graph.handlers; | |
11 | ||
12 | import java.util.Collection; | |
13 | import java.util.HashMap; | |
14 | import java.util.Map; | |
15 | import java.util.Set; | |
16 | ||
17 | import org.eclipse.tracecompass.analysis.graph.core.building.AbstractTraceEventHandler; | |
5aa7fe19 FG |
18 | import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout; |
19 | import org.eclipse.tracecompass.common.core.NonNullUtils; | |
af7f72ce | 20 | import org.eclipse.tracecompass.internal.lttng2.kernel.core.analysis.graph.building.LttngKernelExecGraphProvider; |
5aa7fe19 FG |
21 | import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.Lttng27EventLayout; |
22 | import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.Lttng28EventLayout; | |
af7f72ce FG |
23 | import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.LttngEventLayout; |
24 | import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; | |
25 | import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; | |
26 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | |
27 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceWithPreDefinedEvents; | |
28 | import org.eclipse.tracecompass.tmf.core.trace.TmfEventTypeCollectionHelper; | |
29 | import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; | |
30 | ||
31 | /** | |
32 | * Holds the fields commons to all handler classes. | |
33 | * | |
34 | * @author Francis Giraldeau <francis.giraldeau@gmail.com> | |
35 | * | |
36 | */ | |
37 | public class BaseHandler extends AbstractTraceEventHandler { | |
38 | ||
39 | private final LttngKernelExecGraphProvider fProvider; | |
5aa7fe19 FG |
40 | |
41 | /** | |
42 | * The fWakeupEventMap is populated with the prefered wake-up event for a | |
43 | * given trace. Here is the possible values for LTTng, that are in priority | |
44 | * order: | |
45 | * | |
46 | * <pre> | |
47 | * - linux all versions and lttng all versions: sched_ttwu | |
48 | * - linux >= 4.3 and lttng >= 2.8: sched_waking + sched_wakeup_new | |
49 | * - linux < 3.8.0: sched_wakeup + sched_wakeup_new | |
50 | * </pre> | |
51 | * | |
52 | * The acronym ttwu stands for "Try To Wake Up". The sched_ttwu requires | |
53 | * lttng-modules addons and works with all versions of linux and LTTng. This | |
54 | * event alone is sufficient, because it a placeholder for both sched_wakeup | |
55 | * and sched_wakeup_new. The event sched_wakeup_new is a special case, and | |
56 | * is emitted when a process is created and is scheduled for the first time. | |
57 | * Therefore, we use in priority sched_ttwu if available, then sched_waking | |
58 | * and as a last resort, we use sched_wakup, but this last option will work | |
59 | * only for older kernels. | |
60 | * | |
61 | * If the trace has more than one type of wake-up event enabled, we ensure | |
62 | * that only one type will be processed. | |
63 | */ | |
64 | private Map<ITmfTrace, String> fWakeupEventMap; | |
af7f72ce FG |
65 | |
66 | BaseHandler(LttngKernelExecGraphProvider provider) { | |
67 | fProvider = provider; | |
5aa7fe19 | 68 | fWakeupEventMap = new HashMap<>(); |
af7f72ce | 69 | ITmfTrace trace = getProvider().getTrace(); |
af7f72ce FG |
70 | Collection<ITmfTrace> traceSet = TmfTraceManager.getTraceSet(trace); |
71 | for (ITmfTrace traceItem : traceSet) { | |
5aa7fe19 | 72 | IKernelAnalysisEventLayout layout = getProvider().getEventLayout(traceItem); |
af7f72ce FG |
73 | if (traceItem instanceof ITmfTraceWithPreDefinedEvents) { |
74 | Set<? extends ITmfEventType> content = ((ITmfTraceWithPreDefinedEvents) traceItem).getContainedEventTypes(); | |
75 | Set<String> traceEvents = TmfEventTypeCollectionHelper.getEventNames(content); | |
5aa7fe19 FG |
76 | |
77 | /* default wake-up event */ | |
78 | String wakeupEvent = layout.eventSchedProcessWakeup(); | |
79 | ||
80 | /* | |
81 | * FIXME: downcast in the client should be avoided | |
82 | */ | |
83 | if (layout instanceof LttngEventLayout) { | |
84 | LttngEventLayout lttngLayout = (LttngEventLayout) layout; | |
85 | if (traceEvents.contains(lttngLayout.eventSchedProcessTTWU())) { | |
86 | /* use sched_ttwu if available */ | |
87 | wakeupEvent = lttngLayout.eventSchedProcessTTWU(); | |
88 | } else if (layout instanceof Lttng28EventLayout) { | |
89 | /* use sched_waking if available */ | |
90 | Lttng28EventLayout layout28 = (Lttng28EventLayout) layout; | |
91 | if (traceEvents.contains(layout28.eventSchedProcessWaking())) { | |
92 | wakeupEvent = layout28.eventSchedProcessWaking(); | |
93 | } | |
94 | } | |
95 | } | |
96 | fWakeupEventMap.put(traceItem, wakeupEvent); | |
af7f72ce FG |
97 | } |
98 | } | |
99 | } | |
100 | ||
101 | /** | |
102 | * Returns the parent graph provider | |
103 | * | |
104 | * @return the graph provider | |
105 | */ | |
106 | public LttngKernelExecGraphProvider getProvider() { | |
5aa7fe19 | 107 | return NonNullUtils.checkNotNull(fProvider); |
af7f72ce FG |
108 | } |
109 | ||
110 | /** | |
5aa7fe19 | 111 | * Return if this event is a wake-up event for this trace |
af7f72ce | 112 | * |
5aa7fe19 | 113 | * @param event |
af7f72ce | 114 | * the trace to check |
5aa7fe19 FG |
115 | * @return true if this is a wake-up event to process, false otherwise |
116 | */ | |
117 | public boolean isWakeupEvent(ITmfEvent event) { | |
118 | String eventName = event.getName(); | |
119 | ITmfTrace trace = event.getTrace(); | |
120 | IKernelAnalysisEventLayout eventLayout = getProvider().getEventLayout(event.getTrace()); | |
121 | String wakeupEventName = NonNullUtils.nullToEmptyString(fWakeupEventMap.get(trace)); | |
122 | ||
123 | /* First, check if sched_ttwu is the current wake-up event for this trace */ | |
124 | if (eventLayout instanceof LttngEventLayout) { | |
125 | LttngEventLayout layoutDefault = (LttngEventLayout) eventLayout; | |
126 | if (wakeupEventName.equals(layoutDefault.eventSchedProcessTTWU())) { | |
127 | return eventName.equals(layoutDefault.eventSchedProcessTTWU()); | |
128 | } | |
129 | } | |
130 | ||
131 | /* Fall back to built-in sched_waking and sched_wakeup_new */ | |
132 | if (eventLayout instanceof Lttng28EventLayout) { | |
133 | Lttng28EventLayout layout28 = (Lttng28EventLayout) eventLayout; | |
134 | if (wakeupEventName.equals(layout28.eventSchedProcessWaking())) { | |
135 | return (eventName.equals(layout28.eventSchedProcessWaking()) || | |
136 | eventName.equals(layout28.eventSchedProcessWakeupNew())); | |
137 | } | |
138 | } | |
139 | ||
140 | /* Legacy support using built-in sched_wakeup and sched_wakeup_new */ | |
141 | if (eventLayout instanceof LttngEventLayout) { | |
142 | LttngEventLayout layoutDefault = (LttngEventLayout) eventLayout; | |
143 | if (wakeupEventName.equals(layoutDefault.eventSchedProcessWakeup())) { | |
144 | return (eventName.equals(layoutDefault.eventSchedProcessWakeup()) || | |
145 | eventName.equals(layoutDefault.eventSchedProcessWakeupNew())); | |
146 | } | |
147 | } | |
148 | return false; | |
149 | } | |
150 | ||
151 | /** | |
152 | * Return true if this event is an IPI entry | |
153 | * | |
154 | * @param event | |
155 | * the event | |
156 | * @return true of this is an IPI entry, false otherwise | |
af7f72ce | 157 | */ |
5aa7fe19 FG |
158 | public boolean isIpiEntry(ITmfEvent event) { |
159 | return layoutContainsEvent(event, true); | |
160 | } | |
161 | ||
162 | /** | |
163 | * Return true if this event is an IPI exit | |
164 | * | |
165 | * @param event | |
166 | * the event | |
167 | * @return true of this is an IPI exit, false otherwise | |
168 | */ | |
169 | public boolean isIpiExit(ITmfEvent event) { | |
170 | return layoutContainsEvent(event, false); | |
171 | } | |
172 | ||
173 | private boolean layoutContainsEvent(ITmfEvent event, boolean entry) { | |
174 | String eventName = event.getName(); | |
175 | ITmfTrace trace = event.getTrace(); | |
176 | IKernelAnalysisEventLayout layout = getProvider().getEventLayout(trace); | |
177 | /* awkward downcast */ | |
178 | if (layout instanceof Lttng27EventLayout) { | |
179 | Lttng27EventLayout layout27 = (Lttng27EventLayout) layout; | |
180 | if (entry) { | |
181 | return layout27.getX86IrqVectorsEntry().contains(eventName); | |
182 | } | |
183 | return layout27.getX86IrqVectorsExit().contains(eventName); | |
af7f72ce | 184 | } |
5aa7fe19 | 185 | return false; |
af7f72ce FG |
186 | } |
187 | ||
188 | @Override | |
189 | public void handleEvent(ITmfEvent event) { | |
190 | } | |
191 | ||
192 | } |