Commit | Line | Data |
---|---|---|
a3fc8213 | 1 | /******************************************************************************* |
60ae41e1 | 2 | * Copyright (c) 2011, 2014 Ericsson |
a3fc8213 AM |
3 | * |
4 | * All rights reserved. This program and the accompanying materials are made | |
5 | * 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 | * | |
58f3bc52 AM |
9 | * Contributors: |
10 | * Alexandre Montplaisir - Initial API and implementation | |
f47ed727 | 11 | * Bernd Hufmann - Updated for source and model lookup interfaces |
a3fc8213 AM |
12 | *******************************************************************************/ |
13 | ||
2bdf0193 | 14 | package org.eclipse.tracecompass.tmf.ctf.core; |
a3fc8213 | 15 | |
a4fa4e36 | 16 | import java.util.ArrayList; |
8e964be1 | 17 | import java.util.HashSet; |
a4fa4e36 | 18 | import java.util.List; |
8e964be1 | 19 | import java.util.Set; |
a3fc8213 | 20 | |
a4fa4e36 | 21 | import org.eclipse.jdt.annotation.NonNull; |
f357bcd4 AM |
22 | import org.eclipse.tracecompass.ctf.core.event.CTFCallsite; |
23 | import org.eclipse.tracecompass.ctf.core.event.EventDefinition; | |
24 | import org.eclipse.tracecompass.ctf.core.event.IEventDeclaration; | |
25 | import org.eclipse.tracecompass.ctf.core.event.types.ICompositeDefinition; | |
26 | import org.eclipse.tracecompass.ctf.core.event.types.IDefinition; | |
27 | import org.eclipse.tracecompass.ctf.core.trace.CTFTrace; | |
2bdf0193 AM |
28 | import org.eclipse.tracecompass.tmf.core.event.ITmfCustomAttributes; |
29 | import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; | |
30 | import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; | |
31 | import org.eclipse.tracecompass.tmf.core.event.TmfEvent; | |
32 | import org.eclipse.tracecompass.tmf.core.event.TmfEventField; | |
33 | import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfModelLookup; | |
34 | import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfSourceLookup; | |
35 | import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; | |
a3fc8213 AM |
36 | |
37 | /** | |
f332660b MK |
38 | * A wrapper class around CTF's Event Definition/Declaration that maps all types |
39 | * of Declaration to native Java types. | |
6256d8ad | 40 | * |
d09f973b FC |
41 | * @version 1.0 |
42 | * @author Alexandre Montplaisir | |
93bfd50a | 43 | * @since 2.0 |
a3fc8213 | 44 | */ |
c26d0fe0 | 45 | public class CtfTmfEvent extends TmfEvent |
860b76d4 | 46 | implements ITmfSourceLookup, ITmfModelLookup, ITmfCustomAttributes { |
a3fc8213 AM |
47 | |
48 | // ------------------------------------------------------------------------ | |
49 | // Constants | |
50 | // ------------------------------------------------------------------------ | |
51 | ||
a3fc8213 | 52 | private static final String EMPTY_CTF_EVENT_NAME = "Empty CTF event"; //$NON-NLS-1$ |
aa572e22 | 53 | |
a3fc8213 AM |
54 | // ------------------------------------------------------------------------ |
55 | // Attributes | |
56 | // ------------------------------------------------------------------------ | |
57 | ||
ed6baa55 MK |
58 | private final int fSourceCPU; |
59 | private final long fTypeId; | |
60 | private final String fEventName; | |
a4fa4e36 MK |
61 | private final IEventDeclaration fEventDeclaration; |
62 | @NonNull | |
63 | private final EventDefinition fEvent; | |
64 | private ITmfEventField fContent; | |
a3fc8213 AM |
65 | |
66 | // ------------------------------------------------------------------------ | |
67 | // Constructors | |
68 | // ------------------------------------------------------------------------ | |
69 | ||
70 | /** | |
6cfa0200 | 71 | * Constructor used by {@link CtfTmfEventFactory#createEvent} |
a3fc8213 | 72 | */ |
6cfa0200 | 73 | CtfTmfEvent(CtfTmfTrace trace, long rank, CtfTmfTimestamp timestamp, |
a4fa4e36 | 74 | String fileName, int cpu, IEventDeclaration declaration, @NonNull EventDefinition eventDefinition) { |
6cfa0200 AM |
75 | super(trace, |
76 | rank, | |
77 | timestamp, | |
78 | String.valueOf(cpu), // Source | |
a4fa4e36 MK |
79 | null, // Event type. We don't use TmfEvent's field here, we |
80 | // re-implement getType() | |
81 | null, // Content handled with a lazy loaded re-implemented in | |
82 | // getContent() | |
6cfa0200 AM |
83 | fileName // Reference |
84 | ); | |
85 | ||
a4fa4e36 | 86 | fEventDeclaration = declaration; |
ed6baa55 | 87 | fSourceCPU = cpu; |
5f715709 | 88 | fTypeId = declaration.getId().longValue(); |
ed6baa55 | 89 | fEventName = declaration.getName(); |
a4fa4e36 | 90 | fEvent = eventDefinition; |
e73a4ba5 | 91 | |
a3fc8213 AM |
92 | } |
93 | ||
94 | /** | |
b8a6e46d | 95 | * Inner constructor to create "null" events. Don't use this directly in |
ca5b04ad GB |
96 | * normal usage, use {@link CtfTmfEventFactory#getNullEvent(CtfTmfTrace)} to |
97 | * get an instance of an empty event. | |
c26afeaf | 98 | * |
ca5b04ad GB |
99 | * There is no need to give higher visibility to this method than package |
100 | * visible. | |
101 | * | |
102 | * @param trace | |
103 | * The trace associated with this event | |
a3fc8213 | 104 | */ |
ca5b04ad GB |
105 | CtfTmfEvent(CtfTmfTrace trace) { |
106 | super(trace, | |
6cfa0200 AM |
107 | ITmfContext.UNKNOWN_RANK, |
108 | new CtfTmfTimestamp(-1), | |
109 | null, | |
110 | null, | |
214cc822 | 111 | new TmfEventField("", null, new CtfTmfEventField[0]), //$NON-NLS-1$ |
a4fa4e36 | 112 | null); |
ed6baa55 MK |
113 | fSourceCPU = -1; |
114 | fTypeId = -1; | |
115 | fEventName = EMPTY_CTF_EVENT_NAME; | |
a4fa4e36 MK |
116 | fEventDeclaration = null; |
117 | fEvent = EventDefinition.NULL_EVENT; | |
a3fc8213 AM |
118 | } |
119 | ||
ca5b04ad GB |
120 | /** |
121 | * Default constructor. Do not use directly, but it needs to be present | |
122 | * because it's used in extension points, and the framework will use this | |
123 | * constructor to get the class type. | |
124 | */ | |
125 | public CtfTmfEvent() { | |
126 | this(null); | |
127 | } | |
128 | ||
a3fc8213 AM |
129 | // ------------------------------------------------------------------------ |
130 | // Getters/Setters/Predicates | |
131 | // ------------------------------------------------------------------------ | |
132 | ||
a3fc8213 AM |
133 | /** |
134 | * Gets the cpu core the event was recorded on. | |
135 | * | |
58f3bc52 AM |
136 | * @return The cpu id for a given source. In lttng it's from CPUINFO |
137 | */ | |
a3fc8213 | 138 | public int getCPU() { |
ed6baa55 | 139 | return fSourceCPU; |
a3fc8213 AM |
140 | } |
141 | ||
142 | /** | |
58f3bc52 | 143 | * Return this event's ID, according to the trace's metadata. |
a3fc8213 | 144 | * |
58f3bc52 AM |
145 | * Watch out, this ID is not constant from one trace to another for the same |
146 | * event types! Use "getEventName()" for a constant reference. | |
147 | * | |
148 | * @return The event ID | |
149 | */ | |
a3fc8213 | 150 | public long getID() { |
ed6baa55 | 151 | return fTypeId; |
a3fc8213 AM |
152 | } |
153 | ||
a3fc8213 AM |
154 | @Override |
155 | public CtfTmfTrace getTrace() { | |
f332660b MK |
156 | /* |
157 | * Should be of the right type, since we take a CtfTmfTrace at the | |
158 | * constructor | |
159 | */ | |
6cfa0200 | 160 | return (CtfTmfTrace) super.getTrace(); |
a3fc8213 AM |
161 | } |
162 | ||
163 | @Override | |
164 | public ITmfEventType getType() { | |
e600c338 AM |
165 | CtfTmfEventType ctfTmfEventType = new CtfTmfEventType(fEventName, getContent()); |
166 | ||
167 | /* Register the event type in the owning trace, but only if there is one */ | |
168 | CtfTmfTrace trace = getTrace(); | |
ca5b04ad | 169 | trace.registerEventType(ctfTmfEventType); |
e600c338 | 170 | |
c26afeaf | 171 | return ctfTmfEventType; |
a3fc8213 AM |
172 | } |
173 | ||
8e964be1 | 174 | /** |
8e964be1 MK |
175 | * @since 2.0 |
176 | */ | |
860b76d4 | 177 | @Override |
8e964be1 | 178 | public Set<String> listCustomAttributes() { |
a4fa4e36 | 179 | if (fEventDeclaration == null) { |
a4524c1b | 180 | return new HashSet<>(); |
8e964be1 | 181 | } |
a4fa4e36 | 182 | return fEventDeclaration.getCustomAttributes(); |
8e964be1 MK |
183 | } |
184 | ||
185 | /** | |
8e964be1 MK |
186 | * @since 2.0 |
187 | */ | |
860b76d4 | 188 | @Override |
8e964be1 | 189 | public String getCustomAttribute(String name) { |
a4fa4e36 | 190 | if (fEventDeclaration == null) { |
8e964be1 MK |
191 | return null; |
192 | } | |
a4fa4e36 | 193 | return fEventDeclaration.getCustomAttribute(name); |
8e964be1 MK |
194 | } |
195 | ||
60fb38b8 | 196 | /** |
f47ed727 | 197 | * Get the call site for this event. |
60fb38b8 | 198 | * |
f47ed727 | 199 | * @return the call site information, or null if there is none |
60fb38b8 PT |
200 | * @since 2.0 |
201 | */ | |
f47ed727 | 202 | @Override |
60fb38b8 PT |
203 | public CtfTmfCallsite getCallsite() { |
204 | CTFCallsite callsite = null; | |
f332660b | 205 | CtfTmfTrace trace = getTrace(); |
f332660b MK |
206 | CTFTrace ctfTrace = trace.getCTFTrace(); |
207 | /* Should not happen, but it is a good check */ | |
208 | if (ctfTrace == null) { | |
60fb38b8 PT |
209 | return null; |
210 | } | |
211 | if (getContent() != null) { | |
212 | ITmfEventField ipField = getContent().getField(CtfConstants.CONTEXT_FIELD_PREFIX + CtfConstants.IP_KEY); | |
213 | if (ipField != null && ipField.getValue() instanceof Long) { | |
214 | long ip = (Long) ipField.getValue(); | |
ed6baa55 | 215 | callsite = ctfTrace.getCallsite(fEventName, ip); |
60fb38b8 PT |
216 | } |
217 | } | |
218 | if (callsite == null) { | |
ed6baa55 | 219 | callsite = ctfTrace.getCallsite(fEventName); |
60fb38b8 PT |
220 | } |
221 | if (callsite != null) { | |
222 | return new CtfTmfCallsite(callsite); | |
223 | } | |
224 | return null; | |
225 | } | |
226 | ||
f47ed727 BH |
227 | /** |
228 | * @since 2.0 | |
229 | */ | |
230 | @Override | |
231 | public String getModelUri() { | |
232 | return getCustomAttribute(CtfConstants.MODEL_URI_KEY); | |
233 | } | |
234 | ||
a4fa4e36 MK |
235 | @Override |
236 | public synchronized ITmfEventField getContent() { | |
237 | if (fContent == null) { | |
238 | fContent = new TmfEventField( | |
239 | ITmfEventField.ROOT_FIELD_ID, null, parseFields(fEvent)); | |
240 | } | |
241 | return fContent; | |
242 | } | |
243 | ||
244 | /** | |
245 | * Extract the field information from the structDefinition haze-inducing | |
246 | * mess, and put them into something ITmfEventField can cope with. | |
247 | */ | |
248 | private static CtfTmfEventField[] parseFields(@NonNull EventDefinition eventDef) { | |
249 | List<CtfTmfEventField> fields = new ArrayList<>(); | |
250 | ||
009883d7 | 251 | ICompositeDefinition structFields = eventDef.getFields(); |
a4fa4e36 MK |
252 | if (structFields != null) { |
253 | if (structFields.getFieldNames() != null) { | |
254 | for (String curFieldName : structFields.getFieldNames()) { | |
5f715709 | 255 | fields.add(CtfTmfEventField.parseField((IDefinition) structFields.getDefinition(curFieldName), curFieldName)); |
a4fa4e36 MK |
256 | } |
257 | } | |
258 | } | |
259 | /* Add context information as CtfTmfEventField */ | |
009883d7 | 260 | ICompositeDefinition structContext = eventDef.getContext(); |
a4fa4e36 MK |
261 | if (structContext != null) { |
262 | for (String contextName : structContext.getFieldNames()) { | |
263 | /* Prefix field name */ | |
264 | String curContextName = CtfConstants.CONTEXT_FIELD_PREFIX + contextName; | |
5f715709 | 265 | fields.add(CtfTmfEventField.parseField((IDefinition) structContext.getDefinition(contextName), curContextName)); |
a4fa4e36 MK |
266 | } |
267 | } | |
268 | ||
269 | return fields.toArray(new CtfTmfEventField[fields.size()]); | |
270 | } | |
271 | ||
a3fc8213 | 272 | } |