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 |
6cfa0200 AM |
96 | * normal usage, use {@link CtfTmfEventFactory#getNullEvent()} to get an |
97 | * instance of an empty event. | |
c26afeaf | 98 | * |
b8a6e46d AM |
99 | * This needs to be public however because it's used in extension points, |
100 | * and the framework will use this constructor to get the class type. | |
a3fc8213 | 101 | */ |
ce2388e0 | 102 | public CtfTmfEvent() { |
6cfa0200 AM |
103 | super(null, |
104 | ITmfContext.UNKNOWN_RANK, | |
105 | new CtfTmfTimestamp(-1), | |
106 | null, | |
107 | null, | |
214cc822 | 108 | new TmfEventField("", null, new CtfTmfEventField[0]), //$NON-NLS-1$ |
a4fa4e36 | 109 | null); |
ed6baa55 MK |
110 | fSourceCPU = -1; |
111 | fTypeId = -1; | |
112 | fEventName = EMPTY_CTF_EVENT_NAME; | |
a4fa4e36 MK |
113 | fEventDeclaration = null; |
114 | fEvent = EventDefinition.NULL_EVENT; | |
a3fc8213 AM |
115 | } |
116 | ||
117 | // ------------------------------------------------------------------------ | |
118 | // Getters/Setters/Predicates | |
119 | // ------------------------------------------------------------------------ | |
120 | ||
a3fc8213 AM |
121 | /** |
122 | * Gets the cpu core the event was recorded on. | |
123 | * | |
58f3bc52 AM |
124 | * @return The cpu id for a given source. In lttng it's from CPUINFO |
125 | */ | |
a3fc8213 | 126 | public int getCPU() { |
ed6baa55 | 127 | return fSourceCPU; |
a3fc8213 AM |
128 | } |
129 | ||
130 | /** | |
58f3bc52 | 131 | * Return this event's ID, according to the trace's metadata. |
a3fc8213 | 132 | * |
58f3bc52 AM |
133 | * Watch out, this ID is not constant from one trace to another for the same |
134 | * event types! Use "getEventName()" for a constant reference. | |
135 | * | |
136 | * @return The event ID | |
137 | */ | |
a3fc8213 | 138 | public long getID() { |
ed6baa55 | 139 | return fTypeId; |
a3fc8213 AM |
140 | } |
141 | ||
a3fc8213 AM |
142 | @Override |
143 | public CtfTmfTrace getTrace() { | |
f332660b MK |
144 | /* |
145 | * Should be of the right type, since we take a CtfTmfTrace at the | |
146 | * constructor | |
147 | */ | |
6cfa0200 | 148 | return (CtfTmfTrace) super.getTrace(); |
a3fc8213 AM |
149 | } |
150 | ||
151 | @Override | |
152 | public ITmfEventType getType() { | |
e600c338 AM |
153 | CtfTmfEventType ctfTmfEventType = new CtfTmfEventType(fEventName, getContent()); |
154 | ||
155 | /* Register the event type in the owning trace, but only if there is one */ | |
156 | CtfTmfTrace trace = getTrace(); | |
157 | if (trace != null) { | |
158 | trace.registerEventType(ctfTmfEventType); | |
c26afeaf | 159 | } |
e600c338 | 160 | |
c26afeaf | 161 | return ctfTmfEventType; |
a3fc8213 AM |
162 | } |
163 | ||
8e964be1 | 164 | /** |
8e964be1 MK |
165 | * @since 2.0 |
166 | */ | |
860b76d4 | 167 | @Override |
8e964be1 | 168 | public Set<String> listCustomAttributes() { |
a4fa4e36 | 169 | if (fEventDeclaration == null) { |
a4524c1b | 170 | return new HashSet<>(); |
8e964be1 | 171 | } |
a4fa4e36 | 172 | return fEventDeclaration.getCustomAttributes(); |
8e964be1 MK |
173 | } |
174 | ||
175 | /** | |
8e964be1 MK |
176 | * @since 2.0 |
177 | */ | |
860b76d4 | 178 | @Override |
8e964be1 | 179 | public String getCustomAttribute(String name) { |
a4fa4e36 | 180 | if (fEventDeclaration == null) { |
8e964be1 MK |
181 | return null; |
182 | } | |
a4fa4e36 | 183 | return fEventDeclaration.getCustomAttribute(name); |
8e964be1 MK |
184 | } |
185 | ||
60fb38b8 | 186 | /** |
f47ed727 | 187 | * Get the call site for this event. |
60fb38b8 | 188 | * |
f47ed727 | 189 | * @return the call site information, or null if there is none |
60fb38b8 PT |
190 | * @since 2.0 |
191 | */ | |
f47ed727 | 192 | @Override |
60fb38b8 PT |
193 | public CtfTmfCallsite getCallsite() { |
194 | CTFCallsite callsite = null; | |
f332660b MK |
195 | CtfTmfTrace trace = getTrace(); |
196 | if (trace == null) { | |
197 | return null; | |
198 | } | |
199 | CTFTrace ctfTrace = trace.getCTFTrace(); | |
200 | /* Should not happen, but it is a good check */ | |
201 | if (ctfTrace == null) { | |
60fb38b8 PT |
202 | return null; |
203 | } | |
204 | if (getContent() != null) { | |
205 | ITmfEventField ipField = getContent().getField(CtfConstants.CONTEXT_FIELD_PREFIX + CtfConstants.IP_KEY); | |
206 | if (ipField != null && ipField.getValue() instanceof Long) { | |
207 | long ip = (Long) ipField.getValue(); | |
ed6baa55 | 208 | callsite = ctfTrace.getCallsite(fEventName, ip); |
60fb38b8 PT |
209 | } |
210 | } | |
211 | if (callsite == null) { | |
ed6baa55 | 212 | callsite = ctfTrace.getCallsite(fEventName); |
60fb38b8 PT |
213 | } |
214 | if (callsite != null) { | |
215 | return new CtfTmfCallsite(callsite); | |
216 | } | |
217 | return null; | |
218 | } | |
219 | ||
f47ed727 BH |
220 | /** |
221 | * @since 2.0 | |
222 | */ | |
223 | @Override | |
224 | public String getModelUri() { | |
225 | return getCustomAttribute(CtfConstants.MODEL_URI_KEY); | |
226 | } | |
227 | ||
a4fa4e36 MK |
228 | @Override |
229 | public synchronized ITmfEventField getContent() { | |
230 | if (fContent == null) { | |
231 | fContent = new TmfEventField( | |
232 | ITmfEventField.ROOT_FIELD_ID, null, parseFields(fEvent)); | |
233 | } | |
234 | return fContent; | |
235 | } | |
236 | ||
237 | /** | |
238 | * Extract the field information from the structDefinition haze-inducing | |
239 | * mess, and put them into something ITmfEventField can cope with. | |
240 | */ | |
241 | private static CtfTmfEventField[] parseFields(@NonNull EventDefinition eventDef) { | |
242 | List<CtfTmfEventField> fields = new ArrayList<>(); | |
243 | ||
009883d7 | 244 | ICompositeDefinition structFields = eventDef.getFields(); |
a4fa4e36 MK |
245 | if (structFields != null) { |
246 | if (structFields.getFieldNames() != null) { | |
247 | for (String curFieldName : structFields.getFieldNames()) { | |
5f715709 | 248 | fields.add(CtfTmfEventField.parseField((IDefinition) structFields.getDefinition(curFieldName), curFieldName)); |
a4fa4e36 MK |
249 | } |
250 | } | |
251 | } | |
252 | /* Add context information as CtfTmfEventField */ | |
009883d7 | 253 | ICompositeDefinition structContext = eventDef.getContext(); |
a4fa4e36 MK |
254 | if (structContext != null) { |
255 | for (String contextName : structContext.getFieldNames()) { | |
256 | /* Prefix field name */ | |
257 | String curContextName = CtfConstants.CONTEXT_FIELD_PREFIX + contextName; | |
5f715709 | 258 | fields.add(CtfTmfEventField.parseField((IDefinition) structContext.getDefinition(contextName), curContextName)); |
a4fa4e36 MK |
259 | } |
260 | } | |
261 | ||
262 | return fields.toArray(new CtfTmfEventField[fields.size()]); | |
263 | } | |
264 | ||
a3fc8213 | 265 | } |