X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=include%2Fbabeltrace%2Fctf-ir%2Fevent-internal.h;h=39efd2f8de166d3dad1b5137eb50d1e40895db39;hp=b3e05c773c01169b6e9762b1b1fa6cf984357b68;hb=44c440bc5fe8219cc17d1b786d91fd83c4c9860a;hpb=662e778c1c251b8ab256f572913b12b819679d32 diff --git a/include/babeltrace/ctf-ir/event-internal.h b/include/babeltrace/ctf-ir/event-internal.h index b3e05c77..39efd2f8 100644 --- a/include/babeltrace/ctf-ir/event-internal.h +++ b/include/babeltrace/ctf-ir/event-internal.h @@ -2,7 +2,7 @@ #define BABELTRACE_CTF_IR_EVENT_INTERNAL_H /* - * BabelTrace - CTF IR: Event internal + * Babeltrace - CTF IR: Event internal * * Copyright 2013, 2014 Jérémie Galarneau * @@ -27,75 +27,193 @@ * SOFTWARE. */ -#include -#include -#include +/* Protection: this file uses BT_LIB_LOG*() macros directly */ +#ifndef BABELTRACE_LIB_LOGGING_INTERNAL_H +# error Please define include before including this file. +#endif + +#include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -struct bt_ctf_event_class { - struct bt_ctf_ref ref_count; - GQuark name; - int id_set; - uint32_t id; - /* An event class does not have ownership of a stream class */ - struct bt_ctf_stream_class *stream_class; - /* Structure type containing the event's context */ - struct bt_ctf_field_type *context; - /* Structure type containing the event's fields */ - struct bt_ctf_field_type *fields; - int frozen; -}; +#define BT_ASSERT_PRE_EVENT_HOT(_event) \ + BT_ASSERT_PRE_HOT((_event), "Event", ": %!+e", (_event)) -struct bt_ctf_event { - struct bt_ctf_ref ref_count; - uint64_t timestamp; - struct bt_ctf_event_class *event_class; - struct bt_ctf_field *event_header; - struct bt_ctf_field *context_payload; - struct bt_ctf_field *fields_payload; +struct bt_event { + struct bt_object base; + struct bt_event_class *class; + struct bt_packet *packet; + struct bt_field_wrapper *header_field; + struct bt_field *common_context_field; + struct bt_field *specific_context_field; + struct bt_field *payload_field; + struct bt_clock_value *default_cv; + bool frozen; }; BT_HIDDEN -void bt_ctf_event_class_freeze(struct bt_ctf_event_class *event_class); +void bt_event_destroy(struct bt_event *event); BT_HIDDEN -int bt_ctf_event_class_set_stream_class(struct bt_ctf_event_class *event_class, - struct bt_ctf_stream_class *stream_class); +struct bt_event *bt_event_new(struct bt_event_class *event_class); BT_HIDDEN -int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class, - struct metadata_context *context); +void _bt_event_set_is_frozen(struct bt_event *event, bool is_frozen); -BT_HIDDEN -void bt_ctf_event_class_set_native_byte_order( - struct bt_ctf_event_class *event_class, - int byte_order); +#ifdef BT_DEV_MODE +# define bt_event_set_is_frozen _bt_event_set_is_frozen +#else +# define bt_event_set_is_frozen(_event, _is_frozen) +#endif -BT_HIDDEN -int bt_ctf_event_validate(struct bt_ctf_event *event); +BT_UNUSED +static inline +void _bt_event_reset_dev_mode(struct bt_event *event) +{ + BT_ASSERT(event); -BT_HIDDEN -int bt_ctf_event_serialize(struct bt_ctf_event *event, - struct ctf_stream_pos *pos); + if (event->header_field) { + bt_field_set_is_frozen( + event->header_field->field, false); + bt_field_reset( + event->header_field->field); + } -BT_HIDDEN -int bt_ctf_event_set_timestamp(struct bt_ctf_event *event, uint64_t timestamp); + if (event->common_context_field) { + bt_field_set_is_frozen( + event->common_context_field, false); + bt_field_reset( + event->common_context_field); + } -BT_HIDDEN -uint64_t bt_ctf_event_get_timestamp(struct bt_ctf_event *event); + if (event->specific_context_field) { + bt_field_set_is_frozen( + event->specific_context_field, false); + bt_field_reset(event->specific_context_field); + } -/* - * Attempt to populate the "id" and "timestamp" fields of the event header if - * they are present, unset and their types are integers. - * - * Not finding these fields or encountering unexpected types is not an error - * since the user may have defined a different event header layout. In this - * case, it is expected that the fields be manually populated before appending - * an event to a stream. - */ -BT_HIDDEN -int bt_ctf_event_populate_event_header(struct bt_ctf_event *event); + if (event->payload_field) { + bt_field_set_is_frozen( + event->payload_field, false); + bt_field_reset(event->payload_field); + } +} + +#ifdef BT_DEV_MODE +# define bt_event_reset_dev_mode _bt_event_reset_dev_mode +#else +# define bt_event_reset_dev_mode(_x) +#endif + +static inline +void bt_event_reset(struct bt_event *event) +{ + BT_ASSERT(event); + BT_LIB_LOGD("Resetting event: %!+e", event); + bt_event_set_is_frozen(event, false); + + if (event->default_cv) { + bt_clock_value_reset(event->default_cv); + } + + bt_object_put_no_null_check(&event->packet->base); + event->packet = NULL; +} + +static inline +void bt_event_recycle(struct bt_event *event) +{ + struct bt_event_class *event_class; + + BT_ASSERT(event); + BT_LIB_LOGD("Recycling event: %!+e", event); + + /* + * Those are the important ordered steps: + * + * 1. Reset the event object (put any permanent reference it + * has, unfreeze it and its fields in developer mode, etc.), + * but do NOT put its class's reference. This event class + * contains the pool to which we're about to recycle this + * event object, so we must guarantee its existence thanks + * to this existing reference. + * + * 2. Move the event class reference to our `event_class` + * variable so that we can set the event's class member + * to NULL before recycling it. We CANNOT do this after + * we put the event class reference because this bt_put() + * could destroy the event class, also destroying its + * event pool, thus also destroying our event object (this + * would result in an invalid write access). + * + * 3. Recycle the event object. + * + * 4. Put our event class reference. + */ + bt_event_reset(event); + event_class = event->class; + BT_ASSERT(event_class); + event->class = NULL; + bt_object_pool_recycle_object(&event_class->event_pool, event); + bt_object_put_no_null_check(&event_class->base); +} + +static inline +void bt_event_set_packet(struct bt_event *event, struct bt_packet *packet) +{ + BT_ASSERT_PRE_NON_NULL(event, "Event"); + BT_ASSERT_PRE_NON_NULL(packet, "Packet"); + BT_ASSERT_PRE_EVENT_HOT(event); + BT_ASSERT_PRE(bt_event_class_borrow_stream_class( + event->class) == packet->stream->class, + "Packet's stream class and event's stream class differ: " + "%![event-]+e, %![packet-]+a", event, packet); + + BT_ASSERT(!event->packet); + event->packet = packet; + bt_object_get_no_null_check_no_parent_check(&event->packet->base); + BT_LIB_LOGV("Set event's packet: %![event-]+e, %![packet-]+a", + event, packet); +} + +static inline +struct bt_event *bt_event_create(struct bt_event_class *event_class, + struct bt_packet *packet) +{ + struct bt_event *event = NULL; + + BT_ASSERT(event_class); + event = bt_object_pool_create_object(&event_class->event_pool); + if (unlikely(!event)) { + BT_LIB_LOGE("Cannot allocate one event from event class's event pool: " + "%![ec-]+E", event_class); + goto end; + } + + if (likely(!event->class)) { + event->class = event_class; + bt_object_get_no_null_check(&event_class->base); + } + + BT_ASSERT(packet); + bt_event_set_packet(event, packet); + goto end; + +end: + return event; +} #endif /* BABELTRACE_CTF_IR_EVENT_INTERNAL_H */