X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=lib%2Fctf-ir%2Fstream.c;h=665347a2404701cc31815fc1f7e0bc424733a9ec;hp=8e5b18c5ab304c093e3dec6aef0fb3c9c8892c56;hb=44c440bc5fe8219cc17d1b786d91fd83c4c9860a;hpb=3fea54f69edd1780566230255da196cb6e82df62 diff --git a/lib/ctf-ir/stream.c b/lib/ctf-ir/stream.c index 8e5b18c5..665347a2 100644 --- a/lib/ctf-ir/stream.c +++ b/lib/ctf-ir/stream.c @@ -41,199 +41,89 @@ #include #include #include +#include #include #include -BT_HIDDEN -void bt_stream_common_finalize(struct bt_stream_common *stream) -{ - int i; - - BT_LOGD("Finalizing common stream object: addr=%p, name=\"%s\"", - stream, bt_stream_common_get_name(stream)); +#define BT_ASSERT_PRE_STREAM_HOT(_stream) \ + BT_ASSERT_PRE_HOT((_stream), "Stream", ": %!+s", (_stream)) - /* Call destroy listeners in reverse registration order */ - if (stream->destroy_listeners) { - for (i = stream->destroy_listeners->len - 1; i >= 0; i--) { - struct bt_stream_common_destroy_listener *listener = - &g_array_index(stream->destroy_listeners, - struct bt_stream_common_destroy_listener, i); +static +void destroy_stream(struct bt_object *obj) +{ + struct bt_stream *stream = (void *) obj; - BT_LOGD("Calling destroy listener: func=%p, data=%p, index=%d", - listener->func, listener->data, i); - listener->func(stream, listener->data); - } - } + BT_LIB_LOGD("Destroying stream object: %!+s", stream); - if (stream->name) { - g_string_free(stream->name, TRUE); + if (stream->name.str) { + g_string_free(stream->name.str, TRUE); } - if (stream->destroy_listeners) { - g_array_free(stream->destroy_listeners, TRUE); - } + bt_object_pool_finalize(&stream->packet_pool); + g_free(stream); } static -void bt_stream_destroy(struct bt_object *obj) +void bt_stream_free_packet(struct bt_packet *packet, struct bt_stream *stream) { - struct bt_stream *stream = (void *) obj; - - BT_LOGD("Destroying stream object: addr=%p, name=\"%s\"", - stream, bt_stream_get_name(stream)); - bt_object_pool_finalize(&stream->packet_pool); - bt_stream_common_finalize((void *) obj); - g_free(stream); + bt_packet_destroy(packet); } -BT_HIDDEN -int bt_stream_common_initialize( - struct bt_stream_common *stream, - struct bt_stream_class_common *stream_class, const char *name, - uint64_t id, bt_object_release_func release_func) +BT_ASSERT_PRE_FUNC +static inline +bool stream_id_is_unique(struct bt_trace *trace, + struct bt_stream_class *stream_class, uint64_t id) { - int ret = 0; - struct bt_trace_common *trace = NULL; - - bt_object_init_shared_with_parent(&stream->base, release_func); - - if (!stream_class) { - BT_LOGW_STR("Invalid parameter: stream class is NULL."); - goto error; - } - - BT_LOGD("Initializing common stream object: stream-class-addr=%p, " - "stream-class-name=\"%s\", stream-name=\"%s\", " - "stream-id=%" PRIu64, - stream_class, bt_stream_class_common_get_name(stream_class), - name, id); - trace = bt_stream_class_common_borrow_trace(stream_class); - if (!trace) { - BT_LOGW("Invalid parameter: cannot create stream from a stream class which is not part of trace: " - "stream-class-addr=%p, stream-class-name=\"%s\", " - "stream-name=\"%s\"", - stream_class, - bt_stream_class_common_get_name(stream_class), name); - goto error; - } - - if (id != -1ULL) { - /* - * Validate that the given ID is unique amongst all the - * existing trace's streams created from the same stream - * class. - */ - size_t i; + uint64_t i; + bool is_unique = true; - for (i = 0; i < trace->streams->len; i++) { - struct bt_stream_common *trace_stream = - g_ptr_array_index(trace->streams, i); + for (i = 0; i < trace->streams->len; i++) { + struct bt_stream *stream = trace->streams->pdata[i]; - if (trace_stream->stream_class != (void *) stream_class) { - continue; - } - - if (trace_stream->id == id) { - BT_LOGW_STR("Invalid parameter: another stream in the same trace already has this ID."); - goto error; - } + if (stream->class != stream_class) { + continue; } - } - - /* - * Acquire reference to parent since stream will become publicly - * reachable; it needs its parent to remain valid. - */ - bt_object_set_parent(&stream->base, &trace->base); - stream->stream_class = stream_class; - stream->id = (int64_t) id; - stream->destroy_listeners = g_array_new(FALSE, TRUE, - sizeof(struct bt_stream_common_destroy_listener)); - if (!stream->destroy_listeners) { - BT_LOGE_STR("Failed to allocate a GArray."); - goto error; - } - if (name) { - stream->name = g_string_new(name); - if (!stream->name) { - BT_LOGE_STR("Failed to allocate a GString."); - goto error; + if (stream->id == id) { + is_unique = false; + goto end; } } - BT_LOGD("Set common stream's trace parent: trace-addr=%p", trace); - - /* Add this stream to the trace's streams */ - BT_LOGD("Created common stream object: addr=%p", stream); - goto end; - -error: - ret = -1; - end: - return ret; + return is_unique; } static -void bt_stream_free_packet(struct bt_packet *packet, struct bt_stream *stream) -{ - bt_packet_destroy(packet); -} - -static -struct bt_stream *bt_stream_create_with_id_no_check( - struct bt_stream_class *stream_class, - const char *name, uint64_t id) +struct bt_stream *create_stream_with_id(struct bt_stream_class *stream_class, + uint64_t id) { int ret; - struct bt_stream *stream = NULL; - struct bt_trace *trace = NULL; - - BT_LOGD("Creating stream object: stream-class-addr=%p, " - "stream-class-name=\"%s\", stream-name=\"%s\", " - "stream-id=%" PRIu64, - stream_class, bt_stream_class_get_name(stream_class), - name, id); - - trace = BT_FROM_COMMON(bt_stream_class_common_borrow_trace( - BT_TO_COMMON(stream_class))); - if (!trace) { - BT_LOGW("Invalid parameter: cannot create stream from a stream class which is not part of trace: " - "stream-class-addr=%p, stream-class-name=\"%s\", " - "stream-name=\"%s\"", - stream_class, bt_stream_class_get_name(stream_class), - name); - goto error; - } - - if (bt_trace_is_static(trace)) { - /* - * A static trace has the property that all its stream - * classes, clock classes, and streams are definitive: - * no more can be added, and each object is also frozen. - */ - BT_LOGW("Invalid parameter: cannot create stream from a stream class which is part of a static trace: " - "stream-class-addr=%p, stream-class-name=\"%s\", " - "stream-name=\"%s\", trace-addr=%p", - stream_class, bt_stream_class_get_name(stream_class), - name, trace); - goto error; - } - + struct bt_stream *stream; + struct bt_trace *trace; + + BT_ASSERT(stream_class); + trace = bt_stream_class_borrow_trace_inline(stream_class); + BT_ASSERT_PRE(stream_id_is_unique(trace, stream_class, id), + "Duplicate stream ID: %![trace-]+t, id=%" PRIu64, trace, id); + BT_ASSERT_PRE(!trace->is_static, + "Trace is static: %![trace-]+t", trace); + BT_LIB_LOGD("Creating stream object: %![trace-]+t, id=%" PRIu64, + trace, id); stream = g_new0(struct bt_stream, 1); if (!stream) { BT_LOGE_STR("Failed to allocate one stream."); goto error; } - ret = bt_stream_common_initialize(BT_TO_COMMON(stream), - BT_TO_COMMON(stream_class), name, id, bt_stream_destroy); - if (ret) { - /* bt_stream_common_initialize() logs errors */ + bt_object_init_shared_with_parent(&stream->base, destroy_stream); + stream->name.str = g_string_new(NULL); + if (!stream->name.str) { + BT_LOGE_STR("Failed to allocate a GString."); goto error; } + stream->id = id; ret = bt_object_pool_initialize(&stream->packet_pool, (bt_object_pool_new_object_func) bt_packet_new, (bt_object_pool_destroy_object_func) bt_stream_free_packet, @@ -243,8 +133,10 @@ struct bt_stream *bt_stream_create_with_id_no_check( goto error; } - g_ptr_array_add(trace->common.streams, stream); - BT_LOGD("Created stream object: addr=%p", stream); + stream->class = stream_class; + bt_trace_add_stream(trace, stream); + bt_stream_class_freeze(stream_class); + BT_LIB_LOGD("Created stream object: %!+s", stream); goto end; error: @@ -254,83 +146,63 @@ end: return stream; } -struct bt_stream *bt_stream_create(struct bt_stream_class *stream_class, - const char *name, uint64_t id_param) +struct bt_stream *bt_stream_create(struct bt_stream_class *stream_class) { - struct bt_stream *stream = NULL; - int64_t id = (int64_t) id_param; - - if (!stream_class) { - BT_LOGW_STR("Invalid parameter: stream class is NULL."); - goto end; - } - - if (id < 0) { - BT_LOGW("Invalid parameter: invalid stream's ID: " - "name=\"%s\", id=%" PRIu64, - name, id_param); - goto end; - } - - stream = bt_stream_create_with_id_no_check(stream_class, - name, id_param); + uint64_t id; + + BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class"); + BT_ASSERT_PRE(stream_class->assigns_automatic_stream_id, + "Stream class does not automatically assigns stream IDs: " + "%![sc-]+S", stream_class); + id = bt_trace_get_automatic_stream_id( + bt_stream_class_borrow_trace_inline(stream_class), + stream_class); + return create_stream_with_id(stream_class, id); +} -end: - return stream; +struct bt_stream *bt_stream_create_with_id(struct bt_stream_class *stream_class, + uint64_t id) +{ + BT_ASSERT_PRE(!stream_class->assigns_automatic_stream_id, + "Stream class automatically assigns stream IDs: " + "%![sc-]+S", stream_class); + return create_stream_with_id(stream_class, id); } struct bt_stream_class *bt_stream_borrow_class(struct bt_stream *stream) { - return BT_FROM_COMMON(bt_stream_common_borrow_class(BT_TO_COMMON(stream))); + BT_ASSERT_PRE_NON_NULL(stream, "Stream"); + return stream->class; } const char *bt_stream_get_name(struct bt_stream *stream) { - return bt_stream_common_get_name(BT_TO_COMMON(stream)); + BT_ASSERT_PRE_NON_NULL(stream, "Stream class"); + return stream->name.value; } -int64_t bt_stream_get_id(struct bt_stream *stream) +int bt_stream_set_name(struct bt_stream *stream, const char *name) { - return bt_stream_common_get_id(BT_TO_COMMON(stream)); + BT_ASSERT_PRE_NON_NULL(stream, "Clock class"); + BT_ASSERT_PRE_NON_NULL(name, "Name"); + BT_ASSERT_PRE_STREAM_HOT(stream); + g_string_assign(stream->name.str, name); + stream->name.value = stream->name.str->str; + BT_LIB_LOGV("Set stream class's name: %!+S", stream); + return 0; } -BT_HIDDEN -void bt_stream_common_add_destroy_listener(struct bt_stream_common *stream, - bt_stream_common_destroy_listener_func func, void *data) +uint64_t bt_stream_get_id(struct bt_stream *stream) { - struct bt_stream_common_destroy_listener listener; - - BT_ASSERT(stream); - BT_ASSERT(func); - listener.func = func; - listener.data = data; - g_array_append_val(stream->destroy_listeners, listener); - BT_LOGV("Added stream destroy listener: stream-addr=%p, " - "stream-name=\"%s\", func=%p, data=%p", - stream, bt_stream_common_get_name(stream), func, data); + BT_ASSERT_PRE_NON_NULL(stream, "Stream class"); + return stream->id; } BT_HIDDEN -void bt_stream_common_remove_destroy_listener(struct bt_stream_common *stream, - bt_stream_common_destroy_listener_func func, void *data) +void _bt_stream_freeze(struct bt_stream *stream) { - size_t i; - + /* The field types and default clock class are already frozen */ BT_ASSERT(stream); - BT_ASSERT(func); - - for (i = 0; i < stream->destroy_listeners->len; i++) { - struct bt_stream_common_destroy_listener *listener = - &g_array_index(stream->destroy_listeners, - struct bt_stream_common_destroy_listener, i); - - if (listener->func == func && listener->data == data) { - g_array_remove_index(stream->destroy_listeners, i); - i--; - BT_LOGV("Removed stream destroy listener: stream-addr=%p, " - "stream-name=\"%s\", func=%p, data=%p", - stream, bt_stream_common_get_name(stream), - func, data); - } - } + BT_LIB_LOGD("Freezing stream: %!+s", stream); + stream->frozen = true; }