lib: graph: remove useless checks, make functions inline on fast path
[babeltrace.git] / include / babeltrace / ctf-ir / event-internal.h
CommitLineData
adc315b8
JG
1#ifndef BABELTRACE_CTF_IR_EVENT_INTERNAL_H
2#define BABELTRACE_CTF_IR_EVENT_INTERNAL_H
273b65be
JG
3
4/*
272df73e 5 * Babeltrace - CTF IR: Event internal
273b65be 6 *
de9dd397 7 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
273b65be
JG
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
3dca2276 30#include <babeltrace/assert-pre-internal.h>
273b65be 31#include <babeltrace/babeltrace-internal.h>
dac5c838 32#include <babeltrace/values.h>
123fbdec
JG
33#include <babeltrace/ctf-ir/stream-class.h>
34#include <babeltrace/ctf-ir/stream.h>
5c3b707d 35#include <babeltrace/ctf-ir/packet.h>
6c677fb5 36#include <babeltrace/ctf-ir/packet-internal.h>
3dca2276
PP
37#include <babeltrace/ctf-ir/fields.h>
38#include <babeltrace/ctf-ir/fields-internal.h>
39#include <babeltrace/ctf-ir/event-class-internal.h>
6c677fb5 40#include <babeltrace/ctf-ir/clock-value-internal.h>
312c056a 41#include <babeltrace/ctf-ir/field-wrapper-internal.h>
3dca2276 42#include <babeltrace/ctf-ir/validation-internal.h>
83509119 43#include <babeltrace/object-internal.h>
f6ccaed9 44#include <babeltrace/assert-internal.h>
273b65be
JG
45#include <glib.h>
46
50842bdc 47struct bt_stream_pos;
dc3fffef 48
3dca2276 49struct bt_event_common {
83509119 50 struct bt_object base;
3dca2276 51 struct bt_event_class_common *class;
312c056a 52 struct bt_field_wrapper *header_field;
3dca2276
PP
53 struct bt_field_common *stream_event_context_field;
54 struct bt_field_common *context_field;
55 struct bt_field_common *payload_field;
56 int frozen;
57};
58
59struct bt_event {
60 struct bt_event_common common;
61
50842bdc 62 /* Maps clock classes to bt_clock_value. */
1556a1af 63 GHashTable *clock_values;
3dca2276 64 struct bt_packet *packet;
273b65be
JG
65};
66
273b65be 67BT_HIDDEN
3dca2276 68int _bt_event_common_validate(struct bt_event_common *event);
273b65be 69
4ce9f9d0 70BT_HIDDEN
6c677fb5
PP
71void _bt_event_common_set_is_frozen(struct bt_event_common *event,
72 bool is_frozen);
4ce9f9d0 73
f6ccaed9 74BT_HIDDEN
6c677fb5 75void _bt_event_set_is_frozen(struct bt_event *event, bool is_frozen);
f6ccaed9
PP
76
77#ifdef BT_DEV_MODE
6c677fb5
PP
78# define bt_event_common_validate _bt_event_common_validate
79# define bt_event_common_set_is_frozen _bt_event_common_set_is_frozen
80# define bt_event_set_is_frozen _bt_event_set_is_frozen
f6ccaed9 81#else
6c677fb5
PP
82# define bt_event_common_validate(_event) 0
83# define bt_event_common_set_is_frozen(_event, _is_frozen)
84# define bt_event_set_is_frozen(_event, _is_frozen)
f6ccaed9
PP
85#endif
86
3dca2276
PP
87#define BT_ASSERT_PRE_EVENT_COMMON_HOT(_event, _name) \
88 BT_ASSERT_PRE_HOT((_event), (_name), ": +%!+_e", (_event))
89
dc3fffef 90static inline
3dca2276
PP
91struct bt_event_class_common *bt_event_common_borrow_class(
92 struct bt_event_common *event)
dc3fffef 93{
f6ccaed9 94 BT_ASSERT(event);
3dca2276
PP
95 return event->class;
96}
97
2dd764c1
PP
98typedef void *(*create_field_func)(void *);
99typedef void (*release_field_func)(void *);
100typedef void *(*create_header_field_func)(void *, void *);
101typedef void (*release_header_field_func)(void *, void *);
102
3dca2276
PP
103BT_HIDDEN
104int bt_event_common_initialize(struct bt_event_common *event,
105 struct bt_event_class_common *event_class,
106 struct bt_clock_class *init_expected_clock_class,
3fea54f6 107 bool is_shared_with_parent, bt_object_release_func release_func,
3dca2276
PP
108 bt_validation_flag_copy_field_type_func field_type_copy_func,
109 bool must_be_in_trace,
110 int (*map_clock_classes_func)(struct bt_stream_class_common *stream_class,
111 struct bt_field_type_common *packet_context_field_type,
112 struct bt_field_type_common *event_header_field_type),
2dd764c1
PP
113 create_field_func create_field_func,
114 release_field_func release_field_func,
115 create_header_field_func create_header_field_func,
116 release_header_field_func release_header_field_func);
3dca2276
PP
117
118static inline
094ff7c0 119struct bt_field_common *bt_event_common_borrow_payload(
3dca2276
PP
120 struct bt_event_common *event)
121{
122 struct bt_field_common *payload = NULL;
123
124 BT_ASSERT_PRE_NON_NULL(event, "Event");
125
126 if (!event->payload_field) {
127 BT_LOGV("Event has no current payload field: addr=%p, "
128 "event-class-name=\"%s\", event-class-id=%" PRId64,
129 event, bt_event_class_common_get_name(event->class),
130 bt_event_class_common_get_id(event->class));
131 goto end;
132 }
133
134 payload = event->payload_field;
3dca2276
PP
135
136end:
137 return payload;
138}
139
3dca2276 140static inline
094ff7c0 141struct bt_field_common *bt_event_common_borrow_header(
3dca2276
PP
142 struct bt_event_common *event)
143{
144 struct bt_field_common *header = NULL;
145
146 BT_ASSERT_PRE_NON_NULL(event, "Event");
147
148 if (!event->header_field) {
149 BT_LOGV("Event has no current header field: addr=%p, "
150 "event-class-name=\"%s\", event-class-id=%" PRId64,
151 event, bt_event_class_common_get_name(event->class),
152 bt_event_class_common_get_id(event->class));
153 goto end;
154 }
155
312c056a 156 header = event->header_field->field;
3dca2276
PP
157
158end:
159 return header;
160}
161
3dca2276 162static inline
094ff7c0 163struct bt_field_common *bt_event_common_borrow_context(
3dca2276
PP
164 struct bt_event_common *event)
165{
166 struct bt_field_common *context = NULL;
167
168 BT_ASSERT_PRE_NON_NULL(event, "Event");
169
170 if (!event->context_field) {
171 BT_LOGV("Event has no current context field: addr=%p, "
172 "event-class-name=\"%s\", event-class-id=%" PRId64,
173 event, bt_event_class_common_get_name(event->class),
174 bt_event_class_common_get_id(event->class));
175 goto end;
176 }
177
178 context = event->context_field;
3dca2276
PP
179
180end:
181 return context;
182}
183
3dca2276 184static inline
094ff7c0 185struct bt_field_common *bt_event_common_borrow_stream_event_context(
3dca2276
PP
186 struct bt_event_common *event)
187{
188 struct bt_field_common *stream_event_context = NULL;
189
190 BT_ASSERT_PRE_NON_NULL(event, "Event");
191
192 if (!event->stream_event_context_field) {
193 BT_LOGV("Event has no current stream event context field: addr=%p, "
194 "event-class-name=\"%s\", event-class-id=%" PRId64,
195 event, bt_event_class_common_get_name(event->class),
196 bt_event_class_common_get_id(event->class));
197 goto end;
198 }
199
200 stream_event_context = event->stream_event_context_field;
201
202end:
094ff7c0 203 return stream_event_context;
3dca2276
PP
204}
205
206static inline
312c056a
PP
207void bt_event_common_finalize(struct bt_object *obj,
208 void (*field_release_func)(void *),
209 void (*header_field_release_func)(void *, struct bt_event_common *))
3dca2276
PP
210{
211 struct bt_event_common *event = (void *) obj;
212
213 BT_LOGD("Destroying event: addr=%p, "
214 "event-class-name=\"%s\", event-class-id=%" PRId64,
312c056a
PP
215 event,
216 event->class ? bt_event_class_common_get_name(event->class) : NULL,
217 event->class ? bt_event_class_common_get_id(event->class) : INT64_C(-1));
218
219 if (event->header_field) {
220 BT_LOGD_STR("Releasing event's header field.");
221 header_field_release_func(event->header_field, event);
222 }
223
224 if (event->stream_event_context_field) {
225 BT_LOGD_STR("Releasing event's stream event context field.");
226 field_release_func(event->stream_event_context_field);
227 }
228
229 if (event->context_field) {
230 BT_LOGD_STR("Releasing event's context field.");
231 field_release_func(event->context_field);
232 }
233
234 if (event->payload_field) {
235 BT_LOGD_STR("Releasing event's payload field.");
236 field_release_func(event->payload_field);
237 }
3dca2276 238
312c056a
PP
239 /*
240 * Leave this after calling header_field_release_func() because
241 * this function receives the event object and could need its
242 * class to perform some cleanup.
243 */
3dca2276
PP
244 if (!event->base.parent) {
245 /*
246 * Event was keeping a reference to its class since it shared no
247 * common ancestor with it to guarantee they would both have the
248 * same lifetime.
249 */
250 bt_put(event->class);
251 }
dc3fffef
PP
252}
253
6c677fb5
PP
254BT_UNUSED
255static inline
256void _bt_event_reset_dev_mode(struct bt_event *event)
257{
258 GHashTableIter iter;
259 gpointer key, value;
312c056a 260
6c677fb5 261 BT_ASSERT(event);
312c056a 262
6c677fb5
PP
263 if (event->common.header_field) {
264 bt_field_common_set_is_frozen_recursive(
265 event->common.header_field->field, false);
266 bt_field_common_reset_recursive(
267 event->common.header_field->field);
268 }
269
270 if (event->common.stream_event_context_field) {
271 bt_field_common_set_is_frozen_recursive(
272 event->common.stream_event_context_field, false);
273 bt_field_common_reset_recursive(
274 event->common.stream_event_context_field);
275 }
276
277 if (event->common.context_field) {
278 bt_field_common_set_is_frozen_recursive(
279 event->common.context_field, false);
280 bt_field_common_reset_recursive(event->common.context_field);
281 }
282
283 if (event->common.payload_field) {
284 bt_field_common_set_is_frozen_recursive(
285 event->common.payload_field, false);
286 bt_field_common_reset_recursive(event->common.payload_field);
287 }
288
289 g_hash_table_iter_init(&iter, event->clock_values);
290 while (g_hash_table_iter_next(&iter, &key, &value)) {
291 struct bt_clock_value *clock_value = value;
292
293 BT_ASSERT(clock_value);
294 bt_clock_value_reset(clock_value);
295 bt_clock_value_set_is_frozen(clock_value, false);
296 }
297}
298
299#ifdef BT_DEV_MODE
300# define bt_event_reset_dev_mode _bt_event_reset_dev_mode
301#else
302# define bt_event_reset_dev_mode(_x)
303#endif
312c056a
PP
304
305BT_HIDDEN
306void bt_event_destroy(struct bt_event *event);
307
6c677fb5
PP
308static inline
309void bt_event_reset(struct bt_event *event)
310{
311 BT_ASSERT(event);
312 bt_event_set_is_frozen(event, false);
313 bt_event_reset_dev_mode(event);
314 bt_object_put_no_null_check(&event->packet->base);
315 event->packet = NULL;
316}
317
318static inline
319void bt_event_recycle(struct bt_event *event)
320{
321 struct bt_event_class *event_class;
322
323 BT_ASSERT(event);
324 BT_LIB_LOGD("Recycling event: %!+e", event);
325
326 /*
327 * Those are the important ordered steps:
328 *
329 * 1. Reset the event object (put any permanent reference it
330 * has, unfreeze it and its fields in developer mode, etc.),
331 * but do NOT put its class's reference. This event class
332 * contains the pool to which we're about to recycle this
333 * event object, so we must guarantee its existence thanks
334 * to this existing reference.
335 *
336 * 2. Move the event class reference to our `event_class`
337 * variable so that we can set the event's class member
338 * to NULL before recycling it. We CANNOT do this after
339 * we put the event class reference because this bt_put()
340 * could destroy the event class, also destroying its
341 * event pool, thus also destroying our event object (this
342 * would result in an invalid write access).
343 *
344 * 3. Recycle the event object.
345 *
346 * 4. Put our event class reference.
347 */
348 bt_event_reset(event);
349 event_class = BT_FROM_COMMON(event->common.class);
350 BT_ASSERT(event_class);
351 event->common.class = NULL;
352 bt_object_pool_recycle_object(&event_class->event_pool, event);
353 bt_object_put_no_null_check(&event_class->common.base);
354}
355
356static inline
357void bt_event_set_packet(struct bt_event *event, struct bt_packet *packet)
358{
359 BT_ASSERT_PRE_NON_NULL(event, "Event");
360 BT_ASSERT_PRE_NON_NULL(packet, "Packet");
361 BT_ASSERT_PRE_EVENT_COMMON_HOT(BT_TO_COMMON(event), "Event");
362 BT_ASSERT(!event->packet);
363 event->packet = packet;
364 bt_object_get_no_null_check_no_parent_check(&event->packet->base);
365 BT_LOGV("Set event's packet: event-addr=%p, "
366 "event-class-name=\"%s\", event-class-id=%" PRId64 ", "
367 "packet-addr=%p",
368 event, bt_event_class_common_get_name(event->common.class),
369 bt_event_class_common_get_id(event->common.class), packet);
370}
371
372static inline
373struct bt_event *bt_event_create(struct bt_event_class *event_class,
374 struct bt_packet *packet)
375{
376 struct bt_event *event = NULL;
377
378 BT_ASSERT(event_class);
379 event = bt_object_pool_create_object(&event_class->event_pool);
380 if (unlikely(!event)) {
381 BT_LIB_LOGE("Cannot allocate one event from event class's event pool: "
382 "%![event-class-]+E", event_class);
383 goto end;
384 }
385
386 if (unlikely(!event->common.class)) {
387 event->common.class = BT_TO_COMMON(event_class);
388 bt_object_get_no_null_check(&event_class->common.base);
389 }
390
391 BT_ASSERT(packet);
392 bt_event_set_packet(event, packet);
393 goto end;
394
395end:
396 return event;
397}
398
312c056a 399BT_HIDDEN
6c677fb5 400struct bt_event *bt_event_new(struct bt_event_class *event_class);
312c056a 401
adc315b8 402#endif /* BABELTRACE_CTF_IR_EVENT_INTERNAL_H */
This page took 0.064768 seconds and 4 git commands to generate.