1 /*******************************************************************************
2 * Copyright (c) 2015 École Polytechnique de Montréal
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 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.internal
.lttng2
.kernel
.core
.analysis
.graph
.handlers
;
12 import java
.util
.Collection
;
13 import java
.util
.HashMap
;
17 import org
.eclipse
.tracecompass
.analysis
.graph
.core
.building
.AbstractTraceEventHandler
;
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
.lttng2
.kernel
.core
.analysis
.graph
.building
.LttngKernelExecGraphProvider
;
21 import org
.eclipse
.tracecompass
.internal
.lttng2
.kernel
.core
.trace
.layout
.Lttng27EventLayout
;
22 import org
.eclipse
.tracecompass
.internal
.lttng2
.kernel
.core
.trace
.layout
.Lttng28EventLayout
;
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
;
32 * Holds the fields commons to all handler classes.
34 * @author Francis Giraldeau <francis.giraldeau@gmail.com>
37 public class BaseHandler
extends AbstractTraceEventHandler
{
39 private final LttngKernelExecGraphProvider fProvider
;
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
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
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.
61 * If the trace has more than one type of wake-up event enabled, we ensure
62 * that only one type will be processed.
64 private Map
<ITmfTrace
, String
> fWakeupEventMap
;
66 BaseHandler(LttngKernelExecGraphProvider provider
) {
68 fWakeupEventMap
= new HashMap
<>();
69 ITmfTrace trace
= getProvider().getTrace();
70 Collection
<ITmfTrace
> traceSet
= TmfTraceManager
.getTraceSet(trace
);
71 for (ITmfTrace traceItem
: traceSet
) {
72 IKernelAnalysisEventLayout layout
= getProvider().getEventLayout(traceItem
);
73 if (traceItem
instanceof ITmfTraceWithPreDefinedEvents
) {
74 Set
<?
extends ITmfEventType
> content
= ((ITmfTraceWithPreDefinedEvents
) traceItem
).getContainedEventTypes();
75 Set
<String
> traceEvents
= TmfEventTypeCollectionHelper
.getEventNames(content
);
77 /* default wake-up event */
78 String wakeupEvent
= layout
.eventSchedProcessWakeup();
81 * FIXME: downcast in the client should be avoided
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();
96 fWakeupEventMap
.put(traceItem
, wakeupEvent
);
102 * Returns the parent graph provider
104 * @return the graph provider
106 public LttngKernelExecGraphProvider
getProvider() {
107 return NonNullUtils
.checkNotNull(fProvider
);
111 * Return if this event is a wake-up event for this trace
115 * @return true if this is a wake-up event to process, false otherwise
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
));
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());
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()));
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()));
152 * Return true if this event is an IPI entry
156 * @return true of this is an IPI entry, false otherwise
158 public boolean isIpiEntry(ITmfEvent event
) {
159 return layoutContainsEvent(event
, true);
163 * Return true if this event is an IPI exit
167 * @return true of this is an IPI exit, false otherwise
169 public boolean isIpiExit(ITmfEvent event
) {
170 return layoutContainsEvent(event
, false);
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
;
181 return layout27
.getX86IrqVectorsEntry().contains(eventName
);
183 return layout27
.getX86IrqVectorsExit().contains(eventName
);
189 public void handleEvent(ITmfEvent event
) {