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; |
60fb38b8 | 22 | import org.eclipse.linuxtools.ctf.core.event.CTFCallsite; |
a4fa4e36 | 23 | import org.eclipse.linuxtools.ctf.core.event.EventDefinition; |
8e964be1 | 24 | import org.eclipse.linuxtools.ctf.core.event.IEventDeclaration; |
009883d7 | 25 | import org.eclipse.linuxtools.ctf.core.event.types.ICompositeDefinition; |
cc98c947 | 26 | import org.eclipse.linuxtools.ctf.core.event.types.IDefinition; |
f332660b | 27 | import org.eclipse.linuxtools.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() { | |
e5f7f02c | 153 | CtfTmfEventType ctfTmfEventType = CtfTmfEventType.get(getTrace(), fEventName); |
6cfa0200 AM |
154 | if (ctfTmfEventType == null) { |
155 | /* Should only return null the first time */ | |
e5f7f02c | 156 | ctfTmfEventType = new CtfTmfEventType(fEventName, getTrace(), getContent()); |
c26afeaf MD |
157 | } |
158 | return ctfTmfEventType; | |
a3fc8213 AM |
159 | } |
160 | ||
8e964be1 | 161 | /** |
8e964be1 MK |
162 | * @since 2.0 |
163 | */ | |
860b76d4 | 164 | @Override |
8e964be1 | 165 | public Set<String> listCustomAttributes() { |
a4fa4e36 | 166 | if (fEventDeclaration == null) { |
a4524c1b | 167 | return new HashSet<>(); |
8e964be1 | 168 | } |
a4fa4e36 | 169 | return fEventDeclaration.getCustomAttributes(); |
8e964be1 MK |
170 | } |
171 | ||
172 | /** | |
8e964be1 MK |
173 | * @since 2.0 |
174 | */ | |
860b76d4 | 175 | @Override |
8e964be1 | 176 | public String getCustomAttribute(String name) { |
a4fa4e36 | 177 | if (fEventDeclaration == null) { |
8e964be1 MK |
178 | return null; |
179 | } | |
a4fa4e36 | 180 | return fEventDeclaration.getCustomAttribute(name); |
8e964be1 MK |
181 | } |
182 | ||
60fb38b8 | 183 | /** |
f47ed727 | 184 | * Get the call site for this event. |
60fb38b8 | 185 | * |
f47ed727 | 186 | * @return the call site information, or null if there is none |
60fb38b8 PT |
187 | * @since 2.0 |
188 | */ | |
f47ed727 | 189 | @Override |
60fb38b8 PT |
190 | public CtfTmfCallsite getCallsite() { |
191 | CTFCallsite callsite = null; | |
f332660b MK |
192 | CtfTmfTrace trace = getTrace(); |
193 | if (trace == null) { | |
194 | return null; | |
195 | } | |
196 | CTFTrace ctfTrace = trace.getCTFTrace(); | |
197 | /* Should not happen, but it is a good check */ | |
198 | if (ctfTrace == null) { | |
60fb38b8 PT |
199 | return null; |
200 | } | |
201 | if (getContent() != null) { | |
202 | ITmfEventField ipField = getContent().getField(CtfConstants.CONTEXT_FIELD_PREFIX + CtfConstants.IP_KEY); | |
203 | if (ipField != null && ipField.getValue() instanceof Long) { | |
204 | long ip = (Long) ipField.getValue(); | |
ed6baa55 | 205 | callsite = ctfTrace.getCallsite(fEventName, ip); |
60fb38b8 PT |
206 | } |
207 | } | |
208 | if (callsite == null) { | |
ed6baa55 | 209 | callsite = ctfTrace.getCallsite(fEventName); |
60fb38b8 PT |
210 | } |
211 | if (callsite != null) { | |
212 | return new CtfTmfCallsite(callsite); | |
213 | } | |
214 | return null; | |
215 | } | |
216 | ||
f47ed727 BH |
217 | /** |
218 | * @since 2.0 | |
219 | */ | |
220 | @Override | |
221 | public String getModelUri() { | |
222 | return getCustomAttribute(CtfConstants.MODEL_URI_KEY); | |
223 | } | |
224 | ||
a4fa4e36 MK |
225 | @Override |
226 | public synchronized ITmfEventField getContent() { | |
227 | if (fContent == null) { | |
228 | fContent = new TmfEventField( | |
229 | ITmfEventField.ROOT_FIELD_ID, null, parseFields(fEvent)); | |
230 | } | |
231 | return fContent; | |
232 | } | |
233 | ||
234 | /** | |
235 | * Extract the field information from the structDefinition haze-inducing | |
236 | * mess, and put them into something ITmfEventField can cope with. | |
237 | */ | |
238 | private static CtfTmfEventField[] parseFields(@NonNull EventDefinition eventDef) { | |
239 | List<CtfTmfEventField> fields = new ArrayList<>(); | |
240 | ||
009883d7 | 241 | ICompositeDefinition structFields = eventDef.getFields(); |
a4fa4e36 MK |
242 | if (structFields != null) { |
243 | if (structFields.getFieldNames() != null) { | |
244 | for (String curFieldName : structFields.getFieldNames()) { | |
5f715709 | 245 | fields.add(CtfTmfEventField.parseField((IDefinition) structFields.getDefinition(curFieldName), curFieldName)); |
a4fa4e36 MK |
246 | } |
247 | } | |
248 | } | |
249 | /* Add context information as CtfTmfEventField */ | |
009883d7 | 250 | ICompositeDefinition structContext = eventDef.getContext(); |
a4fa4e36 MK |
251 | if (structContext != null) { |
252 | for (String contextName : structContext.getFieldNames()) { | |
253 | /* Prefix field name */ | |
254 | String curContextName = CtfConstants.CONTEXT_FIELD_PREFIX + contextName; | |
5f715709 | 255 | fields.add(CtfTmfEventField.parseField((IDefinition) structContext.getDefinition(contextName), curContextName)); |
a4fa4e36 MK |
256 | } |
257 | } | |
258 | ||
259 | return fields.toArray(new CtfTmfEventField[fields.size()]); | |
260 | } | |
261 | ||
a3fc8213 | 262 | } |