lib: use object pool for event and packet notifications
[babeltrace.git] / plugins / ctf / fs-src / fs.c
index 74e9b52aaf9fe04d7418bb6e40e0f3358642fd40..04421d3147a8f3b5f70ea5e9b555181dab9a1c8c 100644 (file)
@@ -59,6 +59,7 @@ int notif_iter_data_set_current_ds_file(struct ctf_fs_notif_iter_data *notif_ite
        ctf_fs_ds_file_destroy(notif_iter_data->ds_file);
        notif_iter_data->ds_file = ctf_fs_ds_file_create(
                notif_iter_data->ds_file_group->ctf_fs_trace,
+               notif_iter_data->graph,
                notif_iter_data->notif_iter,
                notif_iter_data->ds_file_group->stream,
                ds_file_info->path->str);
@@ -96,19 +97,52 @@ struct bt_notification_iterator_next_method_return ctf_fs_iterator_next(
 
        BT_ASSERT(notif_iter_data->ds_file);
        next_ret = ctf_fs_ds_file_next(notif_iter_data->ds_file);
-       if (next_ret.status == BT_NOTIFICATION_ITERATOR_STATUS_END) {
-               BT_ASSERT(!next_ret.notification);
+
+       if (next_ret.status == BT_NOTIFICATION_ITERATOR_STATUS_OK &&
+                       bt_notification_get_type(next_ret.notification) ==
+                       BT_NOTIFICATION_TYPE_STREAM_BEGIN) {
+               if (notif_iter_data->skip_stream_begin_notifs) {
+                       /*
+                        * We already emitted a
+                        * BT_NOTIFICATION_TYPE_STREAM_BEGIN
+                        * notification: skip this one, get a new one.
+                        */
+                       BT_PUT(next_ret.notification);
+                       next_ret = ctf_fs_ds_file_next(notif_iter_data->ds_file);
+                       BT_ASSERT(next_ret.status != BT_NOTIFICATION_ITERATOR_STATUS_END);
+                       goto end;
+               } else {
+                       /*
+                        * First BT_NOTIFICATION_TYPE_STREAM_BEGIN
+                        * notification: skip all following.
+                        */
+                       notif_iter_data->skip_stream_begin_notifs = true;
+                       goto end;
+               }
+       }
+
+       if (next_ret.status == BT_NOTIFICATION_ITERATOR_STATUS_OK &&
+                       bt_notification_get_type(next_ret.notification) ==
+                       BT_NOTIFICATION_TYPE_STREAM_END) {
                notif_iter_data->ds_file_info_index++;
 
                if (notif_iter_data->ds_file_info_index ==
                                notif_iter_data->ds_file_group->ds_file_infos->len) {
                        /*
                         * No more stream files to read: we reached the
-                        * real end.
+                        * real end. Emit this
+                        * BT_NOTIFICATION_TYPE_STREAM_END notification.
+                        * The next time ctf_fs_iterator_next() is
+                        * called for this notification iterator,
+                        * ctf_fs_ds_file_next() will return
+                        * BT_NOTIFICATION_ITERATOR_STATUS_END().
                         */
                        goto end;
                }
 
+               BT_PUT(next_ret.notification);
+               bt_notif_iter_reset(notif_iter_data->notif_iter);
+
                /*
                 * Open and start reading the next stream file within
                 * our stream file group.
@@ -122,14 +156,30 @@ struct bt_notification_iterator_next_method_return ctf_fs_iterator_next(
                next_ret = ctf_fs_ds_file_next(notif_iter_data->ds_file);
 
                /*
-                * We should not get BT_NOTIFICATION_ITERATOR_STATUS_END
-                * with a brand new stream file because empty stream
-                * files are not even part of stream file groups, which
-                * means we're sure to get at least one pair of "packet
-                * begin" and "packet end" notifications in the case of
-                * a single, empty packet.
+                * If we get a notification, we expect to get a
+                * BT_NOTIFICATION_TYPE_STREAM_BEGIN notification
+                * because the iterator's state machine emits one before
+                * even requesting the first block of data from the
+                * medium. Skip this notification because we're not
+                * really starting a new stream here, and try getting a
+                * new notification (which, if it works, is a
+                * BT_NOTIFICATION_TYPE_PACKET_BEGIN one). We're sure to
+                * get at least one pair of
+                * BT_NOTIFICATION_TYPE_PACKET_BEGIN and
+                * BT_NOTIFICATION_TYPE_PACKET_END notifications in the
+                * case of a single, empty packet. We know there's at
+                * least one packet because the stream file group does
+                * not contain empty stream files.
                 */
-               BT_ASSERT(next_ret.status != BT_NOTIFICATION_ITERATOR_STATUS_END);
+               BT_ASSERT(notif_iter_data->skip_stream_begin_notifs);
+
+               if (next_ret.status == BT_NOTIFICATION_ITERATOR_STATUS_OK) {
+                       BT_ASSERT(bt_notification_get_type(next_ret.notification) ==
+                               BT_NOTIFICATION_TYPE_STREAM_BEGIN);
+                       BT_PUT(next_ret.notification);
+                       next_ret = ctf_fs_ds_file_next(notif_iter_data->ds_file);
+                       BT_ASSERT(next_ret.status != BT_NOTIFICATION_ITERATOR_STATUS_END);
+               }
        }
 
 end:
@@ -166,6 +216,8 @@ enum bt_notification_iterator_status ctf_fs_iterator_init(
                goto error;
        }
 
+       notif_iter_data->graph = bt_component_borrow_graph(
+               bt_component_borrow_from_private(port_data->ctf_fs->priv_comp));
        notif_iter_data->notif_iter = bt_notif_iter_create(
                port_data->ds_file_group->ctf_fs_trace->metadata->trace,
                bt_common_get_page_size() * 8,
@@ -317,6 +369,7 @@ int create_one_port_for_trace(struct ctf_fs_component *ctf_fs,
                goto error;
        }
 
+       port_data->ctf_fs = ctf_fs;
        port_data->ds_file_group = ds_file_group;
        ret = bt_private_component_source_add_output_private_port(
                ctf_fs->priv_comp, port_name->str, port_data, NULL);
@@ -376,13 +429,13 @@ uint64_t get_packet_header_stream_instance_id(struct ctf_fs_trace *ctf_fs_trace,
                goto end;
        }
 
-       stream_instance_id_field = bt_field_structure_get_field_by_name(
+       stream_instance_id_field = bt_field_structure_borrow_field_by_name(
                packet_header_field, "stream_instance_id");
        if (!stream_instance_id_field) {
                goto end;
        }
 
-       ret = bt_field_unsigned_integer_get_value(stream_instance_id_field,
+       ret = bt_field_integer_unsigned_get_value(stream_instance_id_field,
                &stream_instance_id);
        if (ret) {
                stream_instance_id = -1ULL;
@@ -390,7 +443,6 @@ uint64_t get_packet_header_stream_instance_id(struct ctf_fs_trace *ctf_fs_trace,
        }
 
 end:
-       bt_put(stream_instance_id_field);
        return stream_instance_id;
 }
 
@@ -405,40 +457,33 @@ uint64_t get_packet_context_timestamp_begin_ns(
        uint64_t timestamp_begin_ns = -1ULL;
        int64_t timestamp_begin_ns_signed;
        struct bt_clock_class *timestamp_begin_clock_class = NULL;
-       struct bt_clock_value *clock_value = NULL;
 
        if (!packet_context_field) {
                goto end;
        }
 
-       timestamp_begin_field = bt_field_structure_get_field_by_name(
+       timestamp_begin_field = bt_field_structure_borrow_field_by_name(
                packet_context_field, "timestamp_begin");
        if (!timestamp_begin_field) {
                goto end;
        }
 
-       timestamp_begin_ft = bt_field_get_type(timestamp_begin_field);
+       timestamp_begin_ft = bt_field_borrow_type(timestamp_begin_field);
        BT_ASSERT(timestamp_begin_ft);
        timestamp_begin_clock_class =
-               bt_field_type_integer_get_mapped_clock_class(timestamp_begin_ft);
+               bt_field_type_integer_borrow_mapped_clock_class(timestamp_begin_ft);
        if (!timestamp_begin_clock_class) {
                goto end;
        }
 
-       ret = bt_field_unsigned_integer_get_value(timestamp_begin_field,
+       ret = bt_field_integer_unsigned_get_value(timestamp_begin_field,
                &timestamp_begin_raw_value);
        if (ret) {
                goto end;
        }
 
-       clock_value = bt_clock_value_create(timestamp_begin_clock_class,
-               timestamp_begin_raw_value);
-       if (!clock_value) {
-               goto end;
-       }
-
-       ret = bt_clock_value_get_value_ns_from_epoch(clock_value,
-               &timestamp_begin_ns_signed);
+       ret = bt_clock_class_cycles_to_ns(timestamp_begin_clock_class,
+               timestamp_begin_raw_value, &timestamp_begin_ns_signed);
        if (ret) {
                goto end;
        }
@@ -446,10 +491,6 @@ uint64_t get_packet_context_timestamp_begin_ns(
        timestamp_begin_ns = (uint64_t) timestamp_begin_ns_signed;
 
 end:
-       bt_put(timestamp_begin_field);
-       bt_put(timestamp_begin_ft);
-       bt_put(timestamp_begin_clock_class);
-       bt_put(clock_value);
        return timestamp_begin_ns;
 }
 
@@ -605,7 +646,7 @@ end:
 
 static
 int add_ds_file_to_ds_file_group(struct ctf_fs_trace *ctf_fs_trace,
-               const char *path)
+               struct bt_graph *graph, const char *path)
 {
        struct bt_field *packet_header_field = NULL;
        struct bt_field *packet_context_field = NULL;
@@ -627,12 +668,13 @@ int add_ds_file_to_ds_file_group(struct ctf_fs_trace *ctf_fs_trace,
                goto error;
        }
 
-       ds_file = ctf_fs_ds_file_create(ctf_fs_trace, notif_iter, NULL, path);
+       ds_file = ctf_fs_ds_file_create(ctf_fs_trace, graph, notif_iter,
+               NULL, path);
        if (!ds_file) {
                goto error;
        }
 
-       ret = ctf_fs_ds_file_get_packet_header_context_fields(ds_file,
+       ret = ctf_fs_ds_file_borrow_packet_header_context_fields(ds_file,
                &packet_header_field, &packet_context_field);
        if (ret) {
                BT_LOGE("Cannot get stream file's first packet's header and context fields (`%s`).",
@@ -644,7 +686,7 @@ int add_ds_file_to_ds_file_group(struct ctf_fs_trace *ctf_fs_trace,
                packet_header_field);
        begin_ns = get_packet_context_timestamp_begin_ns(ctf_fs_trace,
                packet_context_field);
-       stream_class = ctf_utils_stream_class_from_packet_header(
+       stream_class = ctf_utils_borrow_stream_class_from_packet_header(
                ctf_fs_trace->metadata->trace, packet_header_field);
        if (!stream_class) {
                goto error;
@@ -743,14 +785,12 @@ end:
        }
 
        ctf_fs_ds_index_destroy(index);
-       bt_put(packet_header_field);
-       bt_put(packet_context_field);
-       bt_put(stream_class);
        return ret;
 }
 
 static
-int create_ds_file_groups(struct ctf_fs_trace *ctf_fs_trace)
+int create_ds_file_groups(struct ctf_fs_trace *ctf_fs_trace,
+               struct bt_graph *graph)
 {
        int ret = 0;
        const char *basename;
@@ -815,7 +855,7 @@ int create_ds_file_groups(struct ctf_fs_trace *ctf_fs_trace)
                        continue;
                }
 
-               ret = add_ds_file_to_ds_file_group(ctf_fs_trace,
+               ret = add_ds_file_to_ds_file_group(ctf_fs_trace, graph,
                        file->path->str);
                if (ret) {
                        BT_LOGE("Cannot add stream file `%s` to stream file group",
@@ -844,12 +884,14 @@ int create_ds_file_groups(struct ctf_fs_trace *ctf_fs_trace)
                }
 
                if (ds_file_group->stream_id == -1ULL) {
-                       /* No stream ID */
+                       /* No stream ID: use 0 */
                        ds_file_group->stream = bt_stream_create(
-                               ds_file_group->stream_class, name->str);
+                               ds_file_group->stream_class, name->str,
+                               ctf_fs_trace->next_stream_id);
+                       ctf_fs_trace->next_stream_id++;
                } else {
                        /* Specific stream ID */
-                       ds_file_group->stream = bt_stream_create_with_id(
+                       ds_file_group->stream = bt_stream_create(
                                ds_file_group->stream_class, name->str,
                                ds_file_group->stream_id);
                }
@@ -902,13 +944,12 @@ int create_cc_prio_map(struct ctf_fs_trace *ctf_fs_trace)
 
        for (i = 0; i < count; i++) {
                struct bt_clock_class *clock_class =
-                       bt_trace_get_clock_class_by_index(
+                       bt_trace_borrow_clock_class_by_index(
                                ctf_fs_trace->metadata->trace, i);
 
                BT_ASSERT(clock_class);
                ret = bt_clock_class_priority_map_add_clock_class(
                        ctf_fs_trace->cc_prio_map, clock_class, 0);
-               BT_PUT(clock_class);
 
                if (ret) {
                        goto end;
@@ -921,7 +962,8 @@ end:
 
 BT_HIDDEN
 struct ctf_fs_trace *ctf_fs_trace_create(const char *path, const char *name,
-               struct ctf_fs_metadata_config *metadata_config)
+               struct ctf_fs_metadata_config *metadata_config,
+               struct bt_graph *graph)
 {
        struct ctf_fs_trace *ctf_fs_trace;
        int ret;
@@ -957,7 +999,7 @@ struct ctf_fs_trace *ctf_fs_trace_create(const char *path, const char *name,
                goto error;
        }
 
-       ret = create_ds_file_groups(ctf_fs_trace);
+       ret = create_ds_file_groups(ctf_fs_trace, graph);
        if (ret) {
                goto error;
        }
@@ -1203,9 +1245,13 @@ int create_ctf_fs_traces(struct ctf_fs_component *ctf_fs,
                        tn_node = g_list_next(tn_node)) {
                GString *trace_path = tp_node->data;
                GString *trace_name = tn_node->data;
+               struct bt_graph *graph = bt_component_borrow_graph(
+                       bt_component_borrow_from_private(ctf_fs->priv_comp));
 
+               BT_ASSERT(graph);
                ctf_fs_trace = ctf_fs_trace_create(trace_path->str,
-                               trace_name->str, &ctf_fs->metadata_config);
+                               trace_name->str, &ctf_fs->metadata_config,
+                               graph);
                if (!ctf_fs_trace) {
                        BT_LOGE("Cannot create trace for `%s`.",
                                trace_path->str);
@@ -1279,15 +1325,14 @@ struct ctf_fs_component *ctf_fs_create(struct bt_private_component *priv_comp,
         * private component should also exist.
         */
        ctf_fs->priv_comp = priv_comp;
-       value = bt_value_map_get(params, "path");
+       value = bt_value_map_borrow(params, "path");
        if (value && !bt_value_is_string(value)) {
                goto error;
        }
 
        value_ret = bt_value_string_get(value, &path_param);
        BT_ASSERT(value_ret == BT_VALUE_STATUS_OK);
-       BT_PUT(value);
-       value = bt_value_map_get(params, "clock-class-offset-s");
+       value = bt_value_map_borrow(params, "clock-class-offset-s");
        if (value) {
                if (!bt_value_is_integer(value)) {
                        BT_LOGE("clock-class-offset-s should be an integer");
@@ -1296,10 +1341,9 @@ struct ctf_fs_component *ctf_fs_create(struct bt_private_component *priv_comp,
                value_ret = bt_value_integer_get(value,
                        &ctf_fs->metadata_config.clock_class_offset_s);
                BT_ASSERT(value_ret == BT_VALUE_STATUS_OK);
-               BT_PUT(value);
        }
 
-       value = bt_value_map_get(params, "clock-class-offset-ns");
+       value = bt_value_map_borrow(params, "clock-class-offset-ns");
        if (value) {
                if (!bt_value_is_integer(value)) {
                        BT_LOGE("clock-class-offset-ns should be an integer");
@@ -1308,7 +1352,6 @@ struct ctf_fs_component *ctf_fs_create(struct bt_private_component *priv_comp,
                value_ret = bt_value_integer_get(value,
                        &ctf_fs->metadata_config.clock_class_offset_ns);
                BT_ASSERT(value_ret == BT_VALUE_STATUS_OK);
-               BT_PUT(value);
        }
 
        ctf_fs->port_data = g_ptr_array_new_with_free_func(port_data_destroy);
@@ -1335,7 +1378,6 @@ error:
        BT_ASSERT(ret == BT_COMPONENT_STATUS_OK);
 
 end:
-       bt_put(value);
        return ctf_fs;
 }
 
This page took 0.046341 seconds and 4 git commands to generate.