lib: add internal object pool API and use it; adapt plugins/tests
[babeltrace.git] / lib / ctf-ir / stream-class.c
index 92d09467ee79eeb4fce6654b4a6ac343006430e8..c414f79d96c808be2ba5433adfd043d39009fc72 100644 (file)
@@ -39,6 +39,7 @@
 #include <babeltrace/ctf-ir/visitor-internal.h>
 #include <babeltrace/ctf-ir/utils.h>
 #include <babeltrace/ctf-ir/utils-internal.h>
+#include <babeltrace/ctf-ir/field-wrapper-internal.h>
 #include <babeltrace/ref.h>
 #include <babeltrace/compiler-internal.h>
 #include <babeltrace/align-internal.h>
@@ -115,10 +116,36 @@ void bt_stream_class_destroy(struct bt_object *obj)
        BT_LOGD("Destroying stream class: addr=%p, name=\"%s\", id=%" PRId64,
                stream_class, bt_stream_class_get_name(stream_class),
                bt_stream_class_get_id(stream_class));
+
+       /*
+        * IMPORTANT: Finalize the common stream class BEFORE finalizing
+        * the pools because otherwise this scenario is possible:
+        *
+        * 1. Event header field object pool is finalized, thus
+        *    destroying its internal array and state.
+        *
+        * 2. Stream class is finalized: each event class is destroyed.
+        *
+        * 3. Destroying an event class finalizes its event pool,
+        *    destroying each contained event.
+        *
+        * 4. Destroying an event makes it recycle its event header
+        *    field to its stream class's event header field pool. But
+        *    said pool is already destroyed.
+        */
        bt_stream_class_common_finalize(BT_TO_COMMON(stream_class));
+       bt_object_pool_finalize(&stream_class->event_header_field_pool);
+       bt_object_pool_finalize(&stream_class->packet_context_field_pool);
        g_free(stream_class);
 }
 
+static
+void free_field_wrapper(struct bt_field_wrapper *field_wrapper,
+               struct bt_stream_class *stream_class)
+{
+       bt_field_wrapper_destroy((void *) field_wrapper);
+}
+
 struct bt_stream_class *bt_stream_class_create(const char *name)
 {
        struct bt_stream_class *stream_class = NULL;
@@ -138,6 +165,26 @@ struct bt_stream_class *bt_stream_class_create(const char *name)
                goto error;
        }
 
+       ret = bt_object_pool_initialize(&stream_class->event_header_field_pool,
+               (bt_object_pool_new_object_func) bt_field_wrapper_new,
+               (bt_object_pool_destroy_object_func) free_field_wrapper,
+               stream_class);
+       if (ret) {
+               BT_LOGE("Failed to initialize event header field pool: ret=%d",
+                       ret);
+               goto error;
+       }
+
+       ret = bt_object_pool_initialize(&stream_class->packet_context_field_pool,
+               (bt_object_pool_new_object_func) bt_field_wrapper_new,
+               (bt_object_pool_destroy_object_func) free_field_wrapper,
+               stream_class);
+       if (ret) {
+               BT_LOGE("Failed to initialize packet context field pool: ret=%d",
+                       ret);
+               goto error;
+       }
+
        BT_LOGD("Created stream class object: addr=%p, name=\"%s\"",
                stream_class, name);
        return stream_class;
@@ -147,9 +194,75 @@ error:
        return NULL;
 }
 
-struct bt_trace *bt_stream_class_get_trace(struct bt_stream_class *stream_class)
+struct bt_event_header_field *bt_stream_class_create_event_header_field(
+               struct bt_stream_class *stream_class)
 {
-       return BT_FROM_COMMON(bt_stream_class_common_get_trace(
+       struct bt_field_wrapper *field_wrapper;
+
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       BT_ASSERT_PRE(stream_class->common.frozen,
+               "Stream class is not part of a trace: %!+S", stream_class);
+       BT_ASSERT_PRE(stream_class->common.event_header_field_type,
+               "Stream class has no event header field type: %!+S",
+               stream_class);
+       field_wrapper = bt_field_wrapper_create(
+               &stream_class->event_header_field_pool,
+               (void *) stream_class->common.event_header_field_type);
+       if (!field_wrapper) {
+               BT_LIB_LOGE("Cannot allocate one event header field from stream class: "
+                       "%![sc-]+S", stream_class);
+               goto error;
+       }
+
+       BT_ASSERT(field_wrapper->field);
+       goto end;
+
+error:
+       if (field_wrapper) {
+               bt_field_wrapper_destroy(field_wrapper);
+               field_wrapper = NULL;
+       }
+
+end:
+       return (void *) field_wrapper;
+}
+
+struct bt_packet_context_field *bt_stream_class_create_packet_context_field(
+               struct bt_stream_class *stream_class)
+{
+       struct bt_field_wrapper *field_wrapper;
+
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       BT_ASSERT_PRE(stream_class->common.frozen,
+               "Stream class is not part of a trace: %!+S", stream_class);
+       BT_ASSERT_PRE(stream_class->common.packet_context_field_type,
+               "Stream class has no packet context field type: %!+S",
+               stream_class);
+       field_wrapper = bt_field_wrapper_create(
+               &stream_class->packet_context_field_pool,
+               (void *) stream_class->common.packet_context_field_type);
+       if (!field_wrapper) {
+               BT_LIB_LOGE("Cannot allocate one packet context field from stream class: "
+                       "%![sc-]+S", stream_class);
+               goto error;
+       }
+
+       BT_ASSERT(field_wrapper->field);
+       goto end;
+
+error:
+       if (field_wrapper) {
+               bt_field_wrapper_destroy(field_wrapper);
+               field_wrapper = NULL;
+       }
+
+end:
+       return (void *) field_wrapper;
+}
+
+struct bt_trace *bt_stream_class_borrow_trace(struct bt_stream_class *stream_class)
+{
+       return BT_FROM_COMMON(bt_stream_class_common_borrow_trace(
                BT_TO_COMMON(stream_class)));
 }
 
@@ -252,8 +365,7 @@ int bt_stream_class_common_add_event_class(
                event_class,
                bt_event_class_common_get_name(event_class),
                bt_event_class_common_get_id(event_class));
-
-       trace = bt_stream_class_common_get_trace(stream_class);
+       trace = bt_stream_class_common_borrow_trace(stream_class);
 
        if (stream_class->frozen) {
                /*
@@ -341,20 +453,22 @@ int bt_stream_class_common_add_event_class(
                BT_ASSERT(trace->valid);
                BT_ASSERT(stream_class->valid);
                packet_header_type =
-                       bt_trace_common_get_packet_header_field_type(trace);
+                       bt_trace_common_borrow_packet_header_field_type(trace);
                packet_context_type =
-                       bt_stream_class_common_get_packet_context_field_type(
+                       bt_stream_class_common_borrow_packet_context_field_type(
                                stream_class);
                event_header_type =
-                       bt_stream_class_common_get_event_header_field_type(
+                       bt_stream_class_common_borrow_event_header_field_type(
                                stream_class);
                stream_event_ctx_type =
-                       bt_stream_class_common_get_event_context_field_type(
+                       bt_stream_class_common_borrow_event_context_field_type(
                                stream_class);
                event_context_type =
-                       bt_event_class_common_get_context_field_type(event_class);
+                       bt_event_class_common_borrow_context_field_type(
+                               event_class);
                event_payload_type =
-                       bt_event_class_common_get_payload_field_type(event_class);
+                       bt_event_class_common_borrow_payload_field_type(
+                               event_class);
                ret = bt_validate_class_types(
                        trace->environment, packet_header_type,
                        packet_context_type, event_header_type,
@@ -363,12 +477,6 @@ int bt_stream_class_common_add_event_class(
                        stream_class->valid, event_class->valid,
                        &validation_output, validation_flags,
                        copy_field_type_func);
-               BT_PUT(packet_header_type);
-               BT_PUT(packet_context_type);
-               BT_PUT(event_header_type);
-               BT_PUT(stream_event_ctx_type);
-               BT_PUT(event_context_type);
-               BT_PUT(event_payload_type);
 
                if (ret) {
                        /*
@@ -458,15 +566,8 @@ int bt_stream_class_common_add_event_class(
                bt_event_class_common_get_id(event_class));
 
 end:
-       BT_PUT(trace);
        bt_validation_output_put_types(&validation_output);
        bt_put(expected_clock_class);
-       BT_ASSERT(!packet_header_type);
-       BT_ASSERT(!packet_context_type);
-       BT_ASSERT(!event_header_type);
-       BT_ASSERT(!stream_event_ctx_type);
-       BT_ASSERT(!event_context_type);
-       BT_ASSERT(!event_payload_type);
        g_free(event_id);
        return ret;
 }
@@ -477,6 +578,8 @@ int bt_stream_class_add_event_class(
 {
        struct bt_trace *trace;
        int ret = 0;
+       uint64_t i;
+       struct bt_clock_class *old_clock_class;
 
        if (!stream_class) {
                BT_LOGW("Invalid parameter: stream class is NULL: "
@@ -485,6 +588,7 @@ int bt_stream_class_add_event_class(
                goto end;
        }
 
+       old_clock_class = stream_class->common.clock_class;
        trace = BT_FROM_COMMON(bt_stream_class_common_borrow_trace(
                BT_TO_COMMON(stream_class)));
        if (trace && trace->is_static) {
@@ -510,6 +614,28 @@ int bt_stream_class_add_event_class(
                (void) bt_trace_object_modification(&obj, trace);
        }
 
+       if (!old_clock_class && stream_class->common.clock_class) {
+               /*
+                * Adding this event class updated the stream class's
+                * single clock class: make sure all the events which
+                * exist in event pools have an existing clock value for
+                * this clock class so that any created event object in
+                * the future (from a pool or not) has this clock value
+                * available.
+                */
+               for (i = 0; i < stream_class->common.event_classes->len; i++) {
+                       struct bt_event_class *event_class =
+                               stream_class->common.event_classes->pdata[i];
+
+                       BT_ASSERT(event_class);
+                       ret = bt_event_class_update_event_pool_clock_values(
+                               event_class);
+                       if (ret) {
+                               goto end;
+                       }
+               }
+       }
+
 end:
        return ret;
 }
@@ -521,24 +647,24 @@ int64_t bt_stream_class_get_event_class_count(
                BT_TO_COMMON(stream_class));
 }
 
-struct bt_event_class *bt_stream_class_get_event_class_by_index(
+struct bt_event_class *bt_stream_class_borrow_event_class_by_index(
                struct bt_stream_class *stream_class, uint64_t index)
 {
-       return BT_FROM_COMMON(bt_stream_class_common_get_event_class_by_index(
+       return BT_FROM_COMMON(bt_stream_class_common_borrow_event_class_by_index(
                BT_TO_COMMON(stream_class), index));
 }
 
-struct bt_event_class *bt_stream_class_get_event_class_by_id(
+struct bt_event_class *bt_stream_class_borrow_event_class_by_id(
                struct bt_stream_class *stream_class, uint64_t id)
 {
-       return BT_FROM_COMMON(bt_stream_class_common_get_event_class_by_id(
+       return BT_FROM_COMMON(bt_stream_class_common_borrow_event_class_by_id(
                BT_TO_COMMON(stream_class), id));
 }
 
-struct bt_field_type *bt_stream_class_get_packet_context_field_type(
+struct bt_field_type *bt_stream_class_borrow_packet_context_field_type(
                struct bt_stream_class *stream_class)
 {
-       return BT_FROM_COMMON(bt_stream_class_common_get_packet_context_field_type(
+       return BT_FROM_COMMON(bt_stream_class_common_borrow_packet_context_field_type(
                BT_TO_COMMON(stream_class)));
 }
 
@@ -550,10 +676,10 @@ int bt_stream_class_set_packet_context_field_type(
                BT_TO_COMMON(stream_class), (void *) packet_context_type);
 }
 
-struct bt_field_type *bt_stream_class_get_event_header_field_type(
+struct bt_field_type *bt_stream_class_borrow_event_header_field_type(
                struct bt_stream_class *stream_class)
 {
-       return BT_FROM_COMMON(bt_stream_class_common_get_event_header_field_type(
+       return BT_FROM_COMMON(bt_stream_class_common_borrow_event_header_field_type(
                BT_TO_COMMON(stream_class)));
 }
 
@@ -565,10 +691,10 @@ int bt_stream_class_set_event_header_field_type(
                BT_TO_COMMON(stream_class), (void *) event_header_type);
 }
 
-struct bt_field_type *bt_stream_class_get_event_context_field_type(
+struct bt_field_type *bt_stream_class_borrow_event_context_field_type(
                struct bt_stream_class *stream_class)
 {
-       return BT_FROM_COMMON(bt_stream_class_common_get_event_context_field_type(
+       return BT_FROM_COMMON(bt_stream_class_common_borrow_event_context_field_type(
                BT_TO_COMMON(stream_class)));
 }
 
This page took 0.02876 seconds and 4 git commands to generate.