Split CTF IR and CTF writer APIs and implementations
[babeltrace.git] / include / babeltrace / ctf-ir / event-internal.h
1 #ifndef BABELTRACE_CTF_IR_EVENT_INTERNAL_H
2 #define BABELTRACE_CTF_IR_EVENT_INTERNAL_H
3
4 /*
5 * Babeltrace - CTF IR: Event internal
6 *
7 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
8 *
9 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * SOFTWARE.
28 */
29
30 #include <babeltrace/assert-pre-internal.h>
31 #include <babeltrace/babeltrace-internal.h>
32 #include <babeltrace/values.h>
33 #include <babeltrace/ctf-ir/stream-class.h>
34 #include <babeltrace/ctf-ir/stream.h>
35 #include <babeltrace/ctf-ir/packet.h>
36 #include <babeltrace/ctf-ir/fields.h>
37 #include <babeltrace/ctf-ir/fields-internal.h>
38 #include <babeltrace/ctf-ir/event-class-internal.h>
39 #include <babeltrace/ctf-ir/validation-internal.h>
40 #include <babeltrace/object-internal.h>
41 #include <babeltrace/assert-internal.h>
42 #include <glib.h>
43
44 struct bt_stream_pos;
45
46 struct bt_event_common {
47 struct bt_object base;
48 struct bt_event_class_common *class;
49 struct bt_field_common *header_field;
50 struct bt_field_common *stream_event_context_field;
51 struct bt_field_common *context_field;
52 struct bt_field_common *payload_field;
53 int frozen;
54 };
55
56 struct bt_event {
57 struct bt_event_common common;
58
59 /* Maps clock classes to bt_clock_value. */
60 GHashTable *clock_values;
61 struct bt_packet *packet;
62 };
63
64 BT_HIDDEN
65 int _bt_event_common_validate(struct bt_event_common *event);
66
67 BT_HIDDEN
68 void _bt_event_common_freeze(struct bt_event_common *event);
69
70 BT_HIDDEN
71 void _bt_event_freeze(struct bt_event *event);
72
73 #ifdef BT_DEV_MODE
74 # define bt_event_common_validate _bt_event_common_validate
75 # define bt_event_common_freeze _bt_event_common_freeze
76 # define bt_event_freeze _bt_event_freeze
77 #else
78 # define bt_event_common_validate(_event) 0
79 # define bt_event_common_freeze(_event)
80 # define bt_event_freeze(_event)
81 #endif
82
83 #define BT_ASSERT_PRE_EVENT_COMMON_HOT(_event, _name) \
84 BT_ASSERT_PRE_HOT((_event), (_name), ": +%!+_e", (_event))
85
86 static inline struct bt_packet *bt_event_borrow_packet(struct bt_event *event)
87 {
88 BT_ASSERT(event);
89 return event->packet;
90 }
91
92 BT_HIDDEN
93 struct bt_stream *bt_event_borrow_stream(struct bt_event *event);
94
95 static inline
96 struct bt_event_class_common *bt_event_common_borrow_class(
97 struct bt_event_common *event)
98 {
99 BT_ASSERT(event);
100 return event->class;
101 }
102
103 static inline
104 struct bt_event_class *bt_event_borrow_class(struct bt_event *event)
105 {
106 return BT_FROM_COMMON(bt_event_common_borrow_class(
107 BT_TO_COMMON(event)));
108 }
109
110 BT_HIDDEN
111 int bt_event_common_initialize(struct bt_event_common *event,
112 struct bt_event_class_common *event_class,
113 struct bt_clock_class *init_expected_clock_class,
114 bt_object_release_func release_func,
115 bt_validation_flag_copy_field_type_func field_type_copy_func,
116 bool must_be_in_trace,
117 int (*map_clock_classes_func)(struct bt_stream_class_common *stream_class,
118 struct bt_field_type_common *packet_context_field_type,
119 struct bt_field_type_common *event_header_field_type),
120 void *(*create_field_func)(void *));
121
122 static inline
123 struct bt_field_common *bt_event_common_get_payload(
124 struct bt_event_common *event)
125 {
126 struct bt_field_common *payload = NULL;
127
128 BT_ASSERT_PRE_NON_NULL(event, "Event");
129
130 if (!event->payload_field) {
131 BT_LOGV("Event has no current payload field: addr=%p, "
132 "event-class-name=\"%s\", event-class-id=%" PRId64,
133 event, bt_event_class_common_get_name(event->class),
134 bt_event_class_common_get_id(event->class));
135 goto end;
136 }
137
138 payload = event->payload_field;
139 bt_get(payload);
140
141 end:
142 return payload;
143 }
144
145 static inline
146 int bt_event_common_set_payload(struct bt_event_common *event,
147 struct bt_field_common *payload)
148 {
149 BT_ASSERT_PRE_NON_NULL(event, "Event");
150 BT_ASSERT_PRE_EVENT_COMMON_HOT(event, "Event");
151
152 if (payload) {
153 BT_ASSERT_PRE(bt_field_type_common_compare(payload->type,
154 event->class->payload_field_type) == 0,
155 "Payload field's type is different from the "
156 "expected field type: %![event-]+_e, %![ft-]+_F, "
157 "%![expected-ft-]+_F",
158 event, payload->type,
159 event->class->payload_field_type);
160 } else {
161 BT_ASSERT_PRE(!event->class->payload_field_type,
162 "Setting no event payload field, "
163 "but event payload field type is not NULL: ",
164 "%![event-]+_e, %![payload-ft-]+_F",
165 event, event->class->payload_field_type);
166 }
167
168 bt_put(event->payload_field);
169 event->payload_field = bt_get(payload);
170 BT_LOGV("Set event's payload field: event-addr=%p, "
171 "event-class-name=\"%s\", event-class-id=%" PRId64 ", "
172 "payload-field-addr=%p",
173 event, bt_event_class_common_get_name(event->class),
174 bt_event_class_common_get_id(event->class), payload);
175 return 0;
176 }
177
178 static inline
179 struct bt_field_common *bt_event_common_get_header(
180 struct bt_event_common *event)
181 {
182 struct bt_field_common *header = NULL;
183
184 BT_ASSERT_PRE_NON_NULL(event, "Event");
185
186 if (!event->header_field) {
187 BT_LOGV("Event has no current header field: addr=%p, "
188 "event-class-name=\"%s\", event-class-id=%" PRId64,
189 event, bt_event_class_common_get_name(event->class),
190 bt_event_class_common_get_id(event->class));
191 goto end;
192 }
193
194 header = event->header_field;
195 bt_get(header);
196
197 end:
198 return header;
199 }
200
201 static inline
202 int bt_event_common_set_header(struct bt_event_common *event,
203 struct bt_field_common *header)
204 {
205 BT_ASSERT_PRE_NON_NULL(event, "Event");
206 BT_ASSERT_PRE_EVENT_COMMON_HOT(event, "Event");
207
208 /*
209 * Ensure the provided header's type matches the one registered to the
210 * stream class.
211 */
212 if (header) {
213 BT_ASSERT_PRE(bt_field_type_common_compare(header->type,
214 bt_event_class_common_borrow_stream_class(event->class)->event_header_field_type) == 0,
215 "Header field's type is different from the "
216 "expected field type: %![event-]+_e, %![ft-]+_F, "
217 "%![expected-ft-]+_F",
218 event, header->type,
219 bt_event_class_common_borrow_stream_class(event->class)->event_header_field_type);
220 } else {
221 BT_ASSERT_PRE(!bt_event_class_common_borrow_stream_class(event->class)->event_header_field_type,
222 "Setting no event header field, "
223 "but event header field type is not NULL: ",
224 "%![event-]+_e, %![header-ft-]+_F",
225 event,
226 bt_event_class_common_borrow_stream_class(event->class)->event_header_field_type);
227 }
228
229 bt_put(event->header_field);
230 event->header_field = bt_get(header);
231 BT_LOGV("Set event's header field: event-addr=%p, "
232 "event-class-name=\"%s\", event-class-id=%" PRId64 ", "
233 "header-field-addr=%p",
234 event, bt_event_class_common_get_name(event->class),
235 bt_event_class_common_get_id(event->class), header);
236 return 0;
237 }
238
239 static inline
240 struct bt_field_common *bt_event_common_get_context(
241 struct bt_event_common *event)
242 {
243 struct bt_field_common *context = NULL;
244
245 BT_ASSERT_PRE_NON_NULL(event, "Event");
246
247 if (!event->context_field) {
248 BT_LOGV("Event has no current context field: addr=%p, "
249 "event-class-name=\"%s\", event-class-id=%" PRId64,
250 event, bt_event_class_common_get_name(event->class),
251 bt_event_class_common_get_id(event->class));
252 goto end;
253 }
254
255 context = event->context_field;
256 bt_get(context);
257
258 end:
259 return context;
260 }
261
262 static inline
263 int bt_event_common_set_context(struct bt_event_common *event,
264 struct bt_field_common *context)
265 {
266 BT_ASSERT_PRE_NON_NULL(event, "Event");
267 BT_ASSERT_PRE_EVENT_COMMON_HOT(event, "Event");
268
269 if (context) {
270 BT_ASSERT_PRE(bt_field_type_common_compare(context->type,
271 event->class->context_field_type) == 0,
272 "Context field's type is different from the "
273 "expected field type: %![event-]+_e, %![ft-]+_F, "
274 "%![expected-ft-]+_F",
275 event, context->type, event->class->context_field_type);
276 } else {
277 BT_ASSERT_PRE(!event->class->context_field_type,
278 "Setting no event context field, "
279 "but event context field type is not NULL: ",
280 "%![event-]+_e, %![context-ft-]+_F",
281 event, event->class->context_field_type);
282 }
283
284 bt_put(event->context_field);
285 event->context_field = bt_get(context);
286 BT_LOGV("Set event's context field: event-addr=%p, "
287 "event-class-name=\"%s\", event-class-id=%" PRId64 ", "
288 "context-field-addr=%p",
289 event, bt_event_class_common_get_name(event->class),
290 bt_event_class_common_get_id(event->class), context);
291 return 0;
292 }
293
294 static inline
295 struct bt_field_common *bt_event_common_get_stream_event_context(
296 struct bt_event_common *event)
297 {
298 struct bt_field_common *stream_event_context = NULL;
299
300 BT_ASSERT_PRE_NON_NULL(event, "Event");
301
302 if (!event->stream_event_context_field) {
303 BT_LOGV("Event has no current stream event context field: addr=%p, "
304 "event-class-name=\"%s\", event-class-id=%" PRId64,
305 event, bt_event_class_common_get_name(event->class),
306 bt_event_class_common_get_id(event->class));
307 goto end;
308 }
309
310 stream_event_context = event->stream_event_context_field;
311
312 end:
313 return bt_get(stream_event_context);
314 }
315
316 static inline
317 int bt_event_common_set_stream_event_context(struct bt_event_common *event,
318 struct bt_field_common *stream_event_context)
319 {
320 BT_ASSERT_PRE_NON_NULL(event, "Event");
321 BT_ASSERT_PRE_EVENT_COMMON_HOT(event, "Event");
322
323 if (stream_event_context) {
324 BT_ASSERT_PRE(bt_field_type_common_compare(stream_event_context->type,
325 bt_event_class_common_borrow_stream_class(event->class)->event_context_field_type) == 0,
326 "Stream event context field's type is different from the "
327 "expected field type: %![event-]+_e, %![ft-]+_F, "
328 "%![expected-ft-]+_F",
329 event, stream_event_context->type,
330 bt_event_class_common_borrow_stream_class(event->class)->event_context_field_type);
331 } else {
332 BT_ASSERT_PRE(!bt_event_class_common_borrow_stream_class(event->class)->event_context_field_type,
333 "Setting no stream event context field, "
334 "but stream event context field type is not NULL: ",
335 "%![event-]+_e, %![context-ft-]+_F",
336 event,
337 bt_event_class_common_borrow_stream_class(event->class)->event_context_field_type);
338 }
339
340 bt_get(stream_event_context);
341 BT_MOVE(event->stream_event_context_field, stream_event_context);
342 BT_LOGV("Set event's stream event context field: event-addr=%p, "
343 "event-class-name=\"%s\", event-class-id=%" PRId64 ", "
344 "stream-event-context-field-addr=%p",
345 event, bt_event_class_common_get_name(event->class),
346 bt_event_class_common_get_id(event->class),
347 stream_event_context);
348 return 0;
349 }
350
351 static inline
352 void bt_event_common_finalize(struct bt_object *obj)
353 {
354 struct bt_event_common *event = (void *) obj;
355
356 BT_LOGD("Destroying event: addr=%p, "
357 "event-class-name=\"%s\", event-class-id=%" PRId64,
358 event, bt_event_class_common_get_name(event->class),
359 bt_event_class_common_get_id(event->class));
360
361 if (!event->base.parent) {
362 /*
363 * Event was keeping a reference to its class since it shared no
364 * common ancestor with it to guarantee they would both have the
365 * same lifetime.
366 */
367 bt_put(event->class);
368 }
369
370 bt_put(event->header_field);
371 BT_LOGD_STR("Putting event's stream event context field.");
372 bt_put(event->stream_event_context_field);
373 BT_LOGD_STR("Putting event's context field.");
374 bt_put(event->context_field);
375 BT_LOGD_STR("Putting event's payload field.");
376 bt_put(event->payload_field);
377 BT_LOGD_STR("Putting event's packet.");
378 }
379
380 #endif /* BABELTRACE_CTF_IR_EVENT_INTERNAL_H */
This page took 0.044682 seconds and 5 git commands to generate.