X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=lib%2Fctf-ir%2Fstream-class.c;h=c414f79d96c808be2ba5433adfd043d39009fc72;hp=fe33b61d59af38f7335e14d737dfea851a8c05cd;hb=312c056ae3d374b253fa0cfe5ed576c0b0e5e569;hpb=8cd07f2c188a204dc61cebde12d5207ae99b1255 diff --git a/lib/ctf-ir/stream-class.c b/lib/ctf-ir/stream-class.c index fe33b61d..c414f79d 100644 --- a/lib/ctf-ir/stream-class.c +++ b/lib/ctf-ir/stream-class.c @@ -29,81 +29,33 @@ #define BT_LOG_TAG "STREAM-CLASS" #include -#include -#include +#include #include -#include #include -#include #include #include -#include #include #include #include -#include #include #include +#include #include #include #include #include +#include #include #include #include -static -void bt_stream_class_destroy(struct bt_object *obj); -static -int init_event_header(struct bt_stream_class *stream_class); -static -int init_packet_context(struct bt_stream_class *stream_class); - -struct bt_stream_class *bt_stream_class_create(const char *name) -{ - struct bt_stream_class *stream_class; - int ret; - - BT_LOGD("Creating default stream class object: name=\"%s\"", name); - stream_class = bt_stream_class_create_empty(name); - if (!stream_class) { - BT_LOGD_STR("Cannot create empty stream class."); - goto error; - } - - ret = init_event_header(stream_class); - if (ret) { - BT_LOGE_STR("Cannot initialize stream class's event header field type."); - goto error; - } - - ret = init_packet_context(stream_class); - if (ret) { - BT_LOGE_STR("Cannot initialize stream class's packet context field type."); - goto error; - } - - BT_LOGD("Created default stream class object: addr=%p, name=\"%s\"", - stream_class, name); - return stream_class; - -error: - BT_PUT(stream_class); - return stream_class; -} - -struct bt_stream_class *bt_stream_class_create_empty(const char *name) +BT_HIDDEN +int bt_stream_class_common_initialize(struct bt_stream_class_common *stream_class, + const char *name, bt_object_release_func release_func) { - struct bt_stream_class *stream_class = NULL; - - BT_LOGD("Creating empty stream class object: name=\"%s\"", name); - - stream_class = g_new0(struct bt_stream_class, 1); - if (!stream_class) { - BT_LOGE_STR("Failed to allocate one stream class."); - goto error; - } + BT_LOGD("Initializing common stream class object: name=\"%s\"", name); + bt_object_init(stream_class, release_func); stream_class->name = g_string_new(name); stream_class->event_classes = g_ptr_array_new_with_free_func( (GDestroyNotify) bt_object_release); @@ -119,239 +71,229 @@ struct bt_stream_class *bt_stream_class_create_empty(const char *name) goto error; } - bt_object_init(stream_class, bt_stream_class_destroy); - BT_LOGD("Created empty stream class object: addr=%p, name=\"%s\"", + BT_LOGD("Initialized common stream class object: addr=%p, name=\"%s\"", stream_class, name); - return stream_class; + return 0; error: - BT_PUT(stream_class); - return stream_class; + return -1; } -struct bt_trace *bt_stream_class_get_trace( - struct bt_stream_class *stream_class) -{ - return stream_class ? - bt_get(bt_stream_class_borrow_trace(stream_class)) : - NULL; -} - -const char *bt_stream_class_get_name( - struct bt_stream_class *stream_class) +BT_HIDDEN +void bt_stream_class_common_finalize(struct bt_stream_class_common *stream_class) { - const char *name = NULL; + BT_LOGD("Finalizing common stream class: addr=%p, name=\"%s\", id=%" PRId64, + stream_class, bt_stream_class_common_get_name(stream_class), + bt_stream_class_common_get_id(stream_class)); + bt_put(stream_class->clock_class); - if (!stream_class) { - BT_LOGW_STR("Invalid parameter: stream class is NULL."); - goto end; + if (stream_class->event_classes_ht) { + g_hash_table_destroy(stream_class->event_classes_ht); } - - name = stream_class->name->len > 0 ? stream_class->name->str : NULL; -end: - return name; -} - -int bt_stream_class_set_name(struct bt_stream_class *stream_class, - const char *name) -{ - int ret = 0; - - if (!stream_class) { - BT_LOGW_STR("Invalid parameter: stream class is NULL."); - ret = -1; - goto end; + if (stream_class->event_classes) { + BT_LOGD_STR("Destroying event classes."); + g_ptr_array_free(stream_class->event_classes, TRUE); } - if (stream_class->frozen) { - BT_LOGW("Invalid parameter: stream class is frozen: " - "addr=%p, name=\"%s\", id=%" PRId64, - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class)); - ret = -1; - goto end; + if (stream_class->name) { + g_string_free(stream_class->name, TRUE); } - if (!name) { - g_string_assign(stream_class->name, ""); - } else { - if (strlen(name) == 0) { - BT_LOGW("Invalid parameter: name is empty."); - ret = -1; - goto end; - } + BT_LOGD_STR("Putting event header field type."); + bt_put(stream_class->event_header_field_type); + BT_LOGD_STR("Putting packet context field type."); + bt_put(stream_class->packet_context_field_type); + BT_LOGD_STR("Putting event context field type."); + bt_put(stream_class->event_context_field_type); +} - g_string_assign(stream_class->name, name); - } +static +void bt_stream_class_destroy(struct bt_object *obj) +{ + struct bt_stream_class *stream_class; - BT_LOGV("Set stream class's name: " - "addr=%p, name=\"%s\", id=%" PRId64, + stream_class = (void *) 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)); -end: - return ret; + + /* + * 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); } -struct bt_ctf_clock *bt_stream_class_get_clock( +static +void free_field_wrapper(struct bt_field_wrapper *field_wrapper, struct bt_stream_class *stream_class) { - struct bt_ctf_clock *clock = NULL; + 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; + int ret; + BT_LOGD("Creating stream class object: name=\"%s\"", name); + stream_class = g_new0(struct bt_stream_class, 1); if (!stream_class) { - BT_LOGW_STR("Invalid parameter: stream class is NULL."); - goto end; + BT_LOGE_STR("Failed to allocate one stream class."); + goto error; } - if (!stream_class->clock) { - BT_LOGV("Stream class has no clock: " - "addr=%p, name=\"%s\", id=%" PRId64, - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class)); - goto end; + ret = bt_stream_class_common_initialize(BT_TO_COMMON(stream_class), + name, bt_stream_class_destroy); + if (ret) { + /* bt_stream_class_common_initialize() logs errors */ + goto error; } - clock = bt_get(stream_class->clock); -end: - return clock; + 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; + +error: + bt_put(stream_class); + return NULL; } -int bt_stream_class_set_clock(struct bt_stream_class *stream_class, - struct bt_ctf_clock *clock) +struct bt_event_header_field *bt_stream_class_create_event_header_field( + struct bt_stream_class *stream_class) { - int ret = 0; - struct bt_field_type *timestamp_field = NULL; - - if (!stream_class || !clock) { - BT_LOGW("Invalid parameter: stream class or clock is NULL: " - "stream-class-addr=%p, clock-addr=%p", - stream_class, clock); - ret = -1; - goto end; + 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; } - if (stream_class->frozen) { - BT_LOGW("Invalid parameter: stream class is frozen: " - "addr=%p, name=\"%s\", id=%" PRId64, - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class)); - ret = -1; - goto end; - } + BT_ASSERT(field_wrapper->field); + goto end; - /* Replace the current clock of this stream class. */ - bt_put(stream_class->clock); - stream_class->clock = bt_get(clock); - BT_LOGV("Set stream class's clock: " - "addr=%p, name=\"%s\", id=%" PRId64 ", " - "clock-addr=%p, clock-name=\"%s\"", - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class), - stream_class->clock, - bt_ctf_clock_get_name(stream_class->clock)); +error: + if (field_wrapper) { + bt_field_wrapper_destroy(field_wrapper); + field_wrapper = NULL; + } end: - bt_put(timestamp_field); - return ret; + return (void *) field_wrapper; } -int64_t bt_stream_class_get_id(struct bt_stream_class *stream_class) +struct bt_packet_context_field *bt_stream_class_create_packet_context_field( + struct bt_stream_class *stream_class) { - int64_t ret; - - if (!stream_class) { - BT_LOGW_STR("Invalid parameter: stream class is NULL."); - ret = (int64_t) -1; - goto end; + 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; } - if (!stream_class->id_set) { - BT_LOGV("Stream class's ID is not set: addr=%p, name=\"%s\"", - stream_class, - bt_stream_class_get_name(stream_class)); - ret = (int64_t) -1; - goto end; + BT_ASSERT(field_wrapper->field); + goto end; + +error: + if (field_wrapper) { + bt_field_wrapper_destroy(field_wrapper); + field_wrapper = NULL; } - ret = stream_class->id; end: - return ret; + return (void *) field_wrapper; } -BT_HIDDEN -void _bt_stream_class_set_id( - struct bt_stream_class *stream_class, int64_t id) +struct bt_trace *bt_stream_class_borrow_trace(struct bt_stream_class *stream_class) { - assert(stream_class); - stream_class->id = id; - stream_class->id_set = 1; - BT_LOGV("Set stream class's ID (internal): " - "addr=%p, name=\"%s\", id=%" PRId64, - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class)); + return BT_FROM_COMMON(bt_stream_class_common_borrow_trace( + BT_TO_COMMON(stream_class))); } -struct event_class_set_stream_class_id_data { - int64_t stream_class_id; - int ret; -}; - -BT_HIDDEN -int bt_stream_class_set_id_no_check( - struct bt_stream_class *stream_class, int64_t id) +const char *bt_stream_class_get_name(struct bt_stream_class *stream_class) { - _bt_stream_class_set_id(stream_class, id); - return 0; + return bt_stream_class_common_get_name(BT_TO_COMMON(stream_class)); } -int bt_stream_class_set_id(struct bt_stream_class *stream_class, - uint64_t id_param) +int bt_stream_class_set_name(struct bt_stream_class *stream_class, + const char *name) { - int ret = 0; - int64_t id = (int64_t) id_param; - - if (!stream_class) { - BT_LOGW_STR("Invalid parameter: stream class is NULL."); - ret = -1; - goto end; - } - - if (stream_class->frozen) { - BT_LOGW("Invalid parameter: stream class is frozen: " - "addr=%p, name=\"%s\", id=%" PRId64, - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class)); - ret = -1; - goto end; - } + return bt_stream_class_common_set_name(BT_TO_COMMON(stream_class), + name); +} - if (id < 0) { - BT_LOGW("Invalid parameter: invalid stream class's ID: " - "stream-class-addr=%p, stream-class-name=\"%s\", " - "stream-class-id=%" PRId64 ", id=%" PRIu64, - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class), - id_param); - ret = -1; - goto end; - } +int64_t bt_stream_class_get_id(struct bt_stream_class *stream_class) +{ + return bt_stream_class_common_get_id(BT_TO_COMMON(stream_class)); +} - ret = bt_stream_class_set_id_no_check(stream_class, id); - if (ret == 0) { - BT_LOGV("Set stream class's ID: " - "addr=%p, name=\"%s\", id=%" PRId64, - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class)); - } -end: - return ret; +int bt_stream_class_set_id(struct bt_stream_class *stream_class, uint64_t id) +{ + return bt_stream_class_common_set_id(BT_TO_COMMON(stream_class), id); } static void event_class_exists(gpointer element, gpointer query) { - struct bt_event_class *event_class_a = element; + struct bt_event_class_common *event_class_a = element; struct search_query *search_query = query; - struct bt_event_class *event_class_b = search_query->value; + struct bt_event_class_common *event_class_b = search_query->value; int64_t id_a, id_b; if (search_query->value == element) { @@ -363,8 +305,8 @@ void event_class_exists(gpointer element, gpointer query) * Two event classes cannot share the same ID in a given * stream class. */ - id_a = bt_event_class_get_id(event_class_a); - id_b = bt_event_class_get_id(event_class_b); + id_a = bt_event_class_common_get_id(event_class_a); + id_b = bt_event_class_common_get_id(event_class_b); if (id_a < 0 || id_b < 0) { /* at least one ID is not set: will be automatically set later */ @@ -374,7 +316,7 @@ void event_class_exists(gpointer element, gpointer query) if (id_a == id_b) { BT_LOGW("Event class with this ID already exists in the stream class: " "id=%" PRId64 ", name=\"%s\"", - id_a, bt_event_class_get_name(event_class_a)); + id_a, bt_event_class_common_get_name(event_class_a)); search_query->found = 1; goto end; } @@ -383,25 +325,29 @@ end: return; } -int bt_stream_class_add_event_class( - struct bt_stream_class *stream_class, - struct bt_event_class *event_class) +BT_HIDDEN +int bt_stream_class_common_add_event_class( + struct bt_stream_class_common *stream_class, + struct bt_event_class_common *event_class, + bt_validation_flag_copy_field_type_func copy_field_type_func) { int ret = 0; int64_t *event_id = NULL; - struct bt_trace *trace = NULL; - struct bt_stream_class *old_stream_class = NULL; + struct bt_trace_common *trace = NULL; + struct bt_stream_class_common *old_stream_class = NULL; struct bt_validation_output validation_output = { 0 }; - struct bt_field_type *packet_header_type = NULL; - struct bt_field_type *packet_context_type = NULL; - struct bt_field_type *event_header_type = NULL; - struct bt_field_type *stream_event_ctx_type = NULL; - struct bt_field_type *event_context_type = NULL; - struct bt_field_type *event_payload_type = NULL; + struct bt_field_type_common *packet_header_type = NULL; + struct bt_field_type_common *packet_context_type = NULL; + struct bt_field_type_common *event_header_type = NULL; + struct bt_field_type_common *stream_event_ctx_type = NULL; + struct bt_field_type_common *event_context_type = NULL; + struct bt_field_type_common *event_payload_type = NULL; const enum bt_validation_flag validation_flags = BT_VALIDATION_FLAG_EVENT; struct bt_clock_class *expected_clock_class = NULL; + BT_ASSERT(copy_field_type_func); + if (!stream_class || !event_class) { BT_LOGW("Invalid parameter: stream class or event class is NULL: " "stream-class-addr=%p, event-class-addr=%p", @@ -414,20 +360,12 @@ int bt_stream_class_add_event_class( "stream-class-addr=%p, stream-class-name=\"%s\", " "stream-class-id=%" PRId64 ", event-class-addr=%p, " "event-class-name=\"%s\", event-class-id=%" PRId64, - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class), + stream_class, bt_stream_class_common_get_name(stream_class), + bt_stream_class_common_get_id(stream_class), event_class, - bt_event_class_get_name(event_class), - bt_event_class_get_id(event_class)); - - trace = bt_stream_class_get_trace(stream_class); - if (trace && trace->is_static) { - BT_LOGW("Invalid parameter: stream class's trace is static: " - "trace-addr=%p, trace-name=\"%s\"", - trace, bt_trace_get_name(trace)); - ret = -1; - goto end; - } + bt_event_class_common_get_name(event_class), + bt_event_class_common_get_id(event_class)); + trace = bt_stream_class_common_borrow_trace(stream_class); if (stream_class->frozen) { /* @@ -449,7 +387,7 @@ int bt_stream_class_add_event_class( * and bt_event_class_validate_single_clock_class() * below can set it. */ - ret = bt_event_class_validate_single_clock_class( + ret = bt_event_class_common_validate_single_clock_class( event_class, &expected_clock_class); if (ret) { BT_LOGW("Event class contains a field type which is not " @@ -461,8 +399,8 @@ int bt_stream_class_add_event_class( "expected-clock-class-addr=%p, " "expected-clock-class-name=\"%s\"", stream_class, - bt_stream_class_get_id(stream_class), - bt_stream_class_get_name(stream_class), + bt_stream_class_common_get_id(stream_class), + bt_stream_class_common_get_name(stream_class), expected_clock_class, expected_clock_class ? bt_clock_class_get_name(expected_clock_class) : @@ -488,7 +426,7 @@ int bt_stream_class_add_event_class( goto end; } - old_stream_class = bt_event_class_get_stream_class(event_class); + old_stream_class = bt_event_class_common_borrow_stream_class(event_class); if (old_stream_class) { /* Event class is already associated to a stream class. */ BT_LOGW("Event class is already part of another stream class: " @@ -496,8 +434,8 @@ int bt_stream_class_add_event_class( "event-class-stream-class-name=\"%s\", " "event-class-stream-class-id=%" PRId64, old_stream_class, - bt_stream_class_get_name(old_stream_class), - bt_stream_class_get_id(old_stream_class)); + bt_stream_class_common_get_name(old_stream_class), + bt_stream_class_common_get_id(old_stream_class)); ret = -1; goto end; } @@ -512,35 +450,33 @@ int bt_stream_class_add_event_class( * The trace and stream class should be valid at this * point. */ - assert(trace->valid); - assert(stream_class->valid); + BT_ASSERT(trace->valid); + BT_ASSERT(stream_class->valid); packet_header_type = - bt_trace_get_packet_header_type(trace); + bt_trace_common_borrow_packet_header_field_type(trace); packet_context_type = - bt_stream_class_get_packet_context_type( + bt_stream_class_common_borrow_packet_context_field_type( stream_class); event_header_type = - bt_stream_class_get_event_header_type(stream_class); + bt_stream_class_common_borrow_event_header_field_type( + stream_class); stream_event_ctx_type = - bt_stream_class_get_event_context_type( + bt_stream_class_common_borrow_event_context_field_type( stream_class); event_context_type = - bt_event_class_get_context_type(event_class); + bt_event_class_common_borrow_context_field_type( + event_class); event_payload_type = - bt_event_class_get_payload_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, stream_event_ctx_type, event_context_type, event_payload_type, trace->valid, stream_class->valid, event_class->valid, - &validation_output, validation_flags); - 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); + &validation_output, validation_flags, + copy_field_type_func); if (ret) { /* @@ -564,12 +500,12 @@ int bt_stream_class_add_event_class( } /* Only set an event ID if none was explicitly set before */ - *event_id = bt_event_class_get_id(event_class); + *event_id = bt_event_class_common_get_id(event_class); if (*event_id < 0) { BT_LOGV("Event class has no ID: automatically setting it: " "id=%" PRId64, stream_class->next_event_id); - if (bt_event_class_set_id(event_class, + if (bt_event_class_common_set_id(event_class, stream_class->next_event_id)) { BT_LOGE("Cannot set event class's ID: id=%" PRId64, stream_class->next_event_id); @@ -607,341 +543,167 @@ int bt_stream_class_add_event_class( event_id = NULL; /* Freeze the event class */ - bt_event_class_freeze(event_class); + bt_event_class_common_freeze(event_class); /* * It is safe to set the stream class's unique clock class * now if the stream class is frozen. */ if (stream_class->frozen && expected_clock_class) { - assert(!stream_class->clock_class || + BT_ASSERT(!stream_class->clock_class || stream_class->clock_class == expected_clock_class); BT_MOVE(stream_class->clock_class, expected_clock_class); } - /* Notifiy listeners of the trace's schema modification. */ - if (trace) { - struct bt_visitor_object obj = { .object = event_class, - .type = BT_VISITOR_OBJECT_TYPE_EVENT_CLASS }; - - (void) bt_trace_object_modification(&obj, trace); - } - BT_LOGD("Added event class to stream class: " "stream-class-addr=%p, stream-class-name=\"%s\", " "stream-class-id=%" PRId64 ", event-class-addr=%p, " "event-class-name=\"%s\", event-class-id=%" PRId64, - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class), + stream_class, bt_stream_class_common_get_name(stream_class), + bt_stream_class_common_get_id(stream_class), event_class, - bt_event_class_get_name(event_class), - bt_event_class_get_id(event_class)); + bt_event_class_common_get_name(event_class), + bt_event_class_common_get_id(event_class)); end: - BT_PUT(trace); - BT_PUT(old_stream_class); bt_validation_output_put_types(&validation_output); bt_put(expected_clock_class); - assert(!packet_header_type); - assert(!packet_context_type); - assert(!event_header_type); - assert(!stream_event_ctx_type); - assert(!event_context_type); - assert(!event_payload_type); g_free(event_id); - return ret; } -int64_t bt_stream_class_get_event_class_count( - struct bt_stream_class *stream_class) +int bt_stream_class_add_event_class( + struct bt_stream_class *stream_class, + struct bt_event_class *event_class) { - int64_t ret; + struct bt_trace *trace; + int ret = 0; + uint64_t i; + struct bt_clock_class *old_clock_class; if (!stream_class) { - BT_LOGW_STR("Invalid parameter: stream class is NULL."); - ret = (int64_t) -1; + BT_LOGW("Invalid parameter: stream class is NULL: " + "stream-class-addr=%p", stream_class); + ret = -1; goto end; } - ret = (int64_t) stream_class->event_classes->len; -end: - return ret; -} - -struct bt_event_class *bt_stream_class_get_event_class_by_index( - struct bt_stream_class *stream_class, uint64_t index) -{ - struct bt_event_class *event_class = NULL; - - if (!stream_class) { - BT_LOGW_STR("Invalid parameter: stream class is NULL."); + 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) { + BT_LOGW("Invalid parameter: stream class's trace is static: " + "trace-addr=%p, trace-name=\"%s\"", + trace, bt_trace_get_name(trace)); + ret = -1; goto end; } - if (index >= stream_class->event_classes->len) { - BT_LOGW("Invalid parameter: index is out of bounds: " - "addr=%p, name=\"%s\", id=%" PRId64 ", " - "index=%" PRIu64 ", count=%u", - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class), - index, stream_class->event_classes->len); + ret = bt_stream_class_common_add_event_class( + BT_TO_COMMON(stream_class), BT_TO_COMMON(event_class), + (bt_validation_flag_copy_field_type_func) bt_field_type_copy); + if (ret) { goto end; } - event_class = g_ptr_array_index(stream_class->event_classes, index); - bt_get(event_class); -end: - return event_class; -} - -struct bt_event_class *bt_stream_class_get_event_class_by_id( - struct bt_stream_class *stream_class, uint64_t id) -{ - int64_t id_key = (int64_t) id; - struct bt_event_class *event_class = NULL; + /* Notifiy listeners of the trace's schema modification. */ + if (trace) { + struct bt_visitor_object obj = { .object = event_class, + .type = BT_VISITOR_OBJECT_TYPE_EVENT_CLASS }; - if (!stream_class) { - BT_LOGW_STR("Invalid parameter: stream class is NULL."); - goto end; + (void) bt_trace_object_modification(&obj, trace); } - if (id_key < 0) { - BT_LOGW("Invalid parameter: invalid event class's ID: " - "stream-class-addr=%p, stream-class-name=\"%s\", " - "stream-class-id=%" PRId64 ", event-class-id=%" PRIu64, - stream_class, - bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class), id); - goto end; + 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; + } + } } - event_class = g_hash_table_lookup(stream_class->event_classes_ht, - &id_key); - bt_get(event_class); end: - return event_class; + return ret; } -struct bt_field_type *bt_stream_class_get_packet_context_type( +int64_t bt_stream_class_get_event_class_count( struct bt_stream_class *stream_class) { - struct bt_field_type *ret = NULL; - - if (!stream_class) { - BT_LOGW_STR("Invalid parameter: stream class is NULL."); - goto end; - } + return bt_stream_class_common_get_event_class_count( + BT_TO_COMMON(stream_class)); +} - bt_get(stream_class->packet_context_type); - ret = stream_class->packet_context_type; -end: - return ret; +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_borrow_event_class_by_index( + BT_TO_COMMON(stream_class), index)); } -int bt_stream_class_set_packet_context_type( - struct bt_stream_class *stream_class, - struct bt_field_type *packet_context_type) +struct bt_event_class *bt_stream_class_borrow_event_class_by_id( + struct bt_stream_class *stream_class, uint64_t id) { - int ret = 0; + return BT_FROM_COMMON(bt_stream_class_common_borrow_event_class_by_id( + BT_TO_COMMON(stream_class), id)); +} - if (!stream_class) { - BT_LOGW_STR("Invalid parameter: stream class is NULL."); - ret = -1; - goto end; - } - - if (stream_class->frozen) { - BT_LOGW("Invalid parameter: stream class is frozen: " - "addr=%p, name=\"%s\", id=%" PRId64, - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class)); - ret = -1; - goto end; - } - - if (packet_context_type && - bt_field_type_get_type_id(packet_context_type) != - BT_FIELD_TYPE_ID_STRUCT) { - /* A packet context must be a structure. */ - BT_LOGW("Invalid parameter: stream class's packet context field type must be a structure: " - "addr=%p, name=\"%s\", id=%" PRId64 ", " - "packet-context-ft-addr=%p, packet-context-ft-id=%s", - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class), - packet_context_type, - bt_field_type_id_string( - bt_field_type_get_type_id(packet_context_type))); - ret = -1; - goto end; - } - - bt_put(stream_class->packet_context_type); - bt_get(packet_context_type); - stream_class->packet_context_type = packet_context_type; - BT_LOGV("Set stream class's packet context field type: " - "addr=%p, name=\"%s\", id=%" PRId64 ", " - "packet-context-ft-addr=%p", - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class), - packet_context_type); - -end: - return ret; -} - -struct bt_field_type *bt_stream_class_get_event_header_type( +struct bt_field_type *bt_stream_class_borrow_packet_context_field_type( struct bt_stream_class *stream_class) { - struct bt_field_type *ret = NULL; - - if (!stream_class) { - BT_LOGW_STR("Invalid parameter: stream class is NULL."); - goto end; - } - - if (!stream_class->event_header_type) { - BT_LOGV("Stream class has no event header field type: " - "addr=%p, name=\"%s\", id=%" PRId64, - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class)); - goto end; - } - - bt_get(stream_class->event_header_type); - ret = stream_class->event_header_type; -end: - return ret; + return BT_FROM_COMMON(bt_stream_class_common_borrow_packet_context_field_type( + BT_TO_COMMON(stream_class))); } -int bt_stream_class_set_event_header_type( +int bt_stream_class_set_packet_context_field_type( struct bt_stream_class *stream_class, - struct bt_field_type *event_header_type) + struct bt_field_type *packet_context_type) { - int ret = 0; - - if (!stream_class) { - BT_LOGW_STR("Invalid parameter: stream class is NULL."); - ret = -1; - goto end; - } - - if (stream_class->frozen) { - BT_LOGW("Invalid parameter: stream class is frozen: " - "addr=%p, name=\"%s\", id=%" PRId64, - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class)); - ret = -1; - goto end; - } - - if (event_header_type && - bt_field_type_get_type_id(event_header_type) != - BT_FIELD_TYPE_ID_STRUCT) { - /* An event header must be a structure. */ - BT_LOGW("Invalid parameter: stream class's event header field type must be a structure: " - "addr=%p, name=\"%s\", id=%" PRId64 ", " - "event-header-ft-addr=%p, event-header-ft-id=%s", - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class), - event_header_type, - bt_field_type_id_string( - bt_field_type_get_type_id(event_header_type))); - ret = -1; - goto end; - } - - bt_put(stream_class->event_header_type); - stream_class->event_header_type = bt_get(event_header_type); - BT_LOGV("Set stream class's event header field type: " - "addr=%p, name=\"%s\", id=%" PRId64 ", " - "event-header-ft-addr=%p", - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class), - event_header_type); -end: - return ret; + return bt_stream_class_common_set_packet_context_field_type( + BT_TO_COMMON(stream_class), (void *) packet_context_type); } -struct bt_field_type *bt_stream_class_get_event_context_type( +struct bt_field_type *bt_stream_class_borrow_event_header_field_type( struct bt_stream_class *stream_class) { - struct bt_field_type *ret = NULL; - - if (!stream_class) { - BT_LOGW_STR("Invalid parameter: stream class is NULL."); - goto end; - } - - if (!stream_class->event_context_type) { - goto end; - } - - bt_get(stream_class->event_context_type); - ret = stream_class->event_context_type; -end: - return ret; + return BT_FROM_COMMON(bt_stream_class_common_borrow_event_header_field_type( + BT_TO_COMMON(stream_class))); } -int bt_stream_class_set_event_context_type( +int bt_stream_class_set_event_header_field_type( struct bt_stream_class *stream_class, - struct bt_field_type *event_context_type) + struct bt_field_type *event_header_type) { - int ret = 0; - - if (!stream_class) { - BT_LOGW_STR("Invalid parameter: stream class is NULL."); - ret = -1; - goto end; - } - - if (stream_class->frozen) { - BT_LOGW("Invalid parameter: stream class is frozen: " - "addr=%p, name=\"%s\", id=%" PRId64, - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class)); - ret = -1; - goto end; - } - - if (event_context_type && - bt_field_type_get_type_id(event_context_type) != - BT_FIELD_TYPE_ID_STRUCT) { - /* A packet context must be a structure. */ - BT_LOGW("Invalid parameter: stream class's event context field type must be a structure: " - "addr=%p, name=\"%s\", id=%" PRId64 ", " - "event-context-ft-addr=%p, event-context-ft-id=%s", - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class), - event_context_type, - bt_field_type_id_string( - bt_field_type_get_type_id(event_context_type))); - ret = -1; - goto end; - } - - bt_put(stream_class->event_context_type); - stream_class->event_context_type = bt_get(event_context_type); - BT_LOGV("Set stream class's event context field type: " - "addr=%p, name=\"%s\", id=%" PRId64 ", " - "event-context-ft-addr=%p", - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class), - event_context_type); -end: - return ret; + return bt_stream_class_common_set_event_header_field_type( + BT_TO_COMMON(stream_class), (void *) event_header_type); } -/* Pre-2.0 CTF writer backward compatibility */ -void bt_ctf_stream_class_get(struct bt_stream_class *stream_class) +struct bt_field_type *bt_stream_class_borrow_event_context_field_type( + struct bt_stream_class *stream_class) { - bt_get(stream_class); + return BT_FROM_COMMON(bt_stream_class_common_borrow_event_context_field_type( + BT_TO_COMMON(stream_class))); } -/* Pre-2.0 CTF writer backward compatibility */ -void bt_ctf_stream_class_put(struct bt_stream_class *stream_class) +int bt_stream_class_set_event_context_field_type( + struct bt_stream_class *stream_class, + struct bt_field_type *event_context_type) { - bt_put(stream_class); + return bt_stream_class_common_set_event_context_field_type( + BT_TO_COMMON(stream_class), (void *) event_context_type); } static @@ -961,20 +723,23 @@ void *get_event_class(void *element, int i) static int visit_event_class(void *object, bt_visitor visitor,void *data) { - struct bt_visitor_object obj = - { .object = object, - .type = BT_VISITOR_OBJECT_TYPE_EVENT_CLASS }; + struct bt_visitor_object obj = { + .object = object, + .type = BT_VISITOR_OBJECT_TYPE_EVENT_CLASS + }; return visitor(&obj, data); } -int bt_stream_class_visit(struct bt_stream_class *stream_class, +BT_HIDDEN +int bt_stream_class_common_visit(struct bt_stream_class_common *stream_class, bt_visitor visitor, void *data) { int ret; - struct bt_visitor_object obj = - { .object = stream_class, - .type = BT_VISITOR_OBJECT_TYPE_STREAM_CLASS }; + struct bt_visitor_object obj = { + .object = stream_class, + .type = BT_VISITOR_OBJECT_TYPE_STREAM_CLASS + }; if (!stream_class || !visitor) { BT_LOGW("Invalid parameter: stream class or visitor is NULL: " @@ -988,410 +753,52 @@ int bt_stream_class_visit(struct bt_stream_class *stream_class, get_event_class, visit_event_class, visitor, data); BT_LOGV("visitor_helper() returned: ret=%d", ret); + end: return ret; } +int bt_stream_class_visit(struct bt_stream_class *stream_class, + bt_visitor visitor, void *data) +{ + return bt_stream_class_common_visit(BT_FROM_COMMON(stream_class), + visitor, data); +} + BT_HIDDEN -void bt_stream_class_freeze(struct bt_stream_class *stream_class) +void bt_stream_class_common_freeze(struct bt_stream_class_common *stream_class) { if (!stream_class || stream_class->frozen) { return; } BT_LOGD("Freezing stream class: addr=%p, name=\"%s\", id=%" PRId64, - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class)); + stream_class, bt_stream_class_common_get_name(stream_class), + bt_stream_class_common_get_id(stream_class)); stream_class->frozen = 1; - bt_field_type_freeze(stream_class->event_header_type); - bt_field_type_freeze(stream_class->packet_context_type); - bt_field_type_freeze(stream_class->event_context_type); - - if (stream_class->clock) { - bt_clock_class_freeze(stream_class->clock->clock_class); - } -} - -BT_HIDDEN -int bt_stream_class_serialize(struct bt_stream_class *stream_class, - struct metadata_context *context) -{ - int ret = 0; - size_t i; - struct bt_trace *trace; - struct bt_field_type *packet_header_type = NULL; - - BT_LOGD("Serializing stream class's metadata: " - "stream-class-addr=%p, stream-class-name=\"%s\", " - "stream-class-id=%" PRId64 ", metadata-context-addr=%p", - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class), context); - g_string_assign(context->field_name, ""); - context->current_indentation_level = 1; - if (!stream_class->id_set) { - BT_LOGW_STR("Stream class's ID is not set."); - ret = -1; - goto end; - } - - g_string_append(context->string, "stream {\n"); - - /* - * The reference to the trace is only borrowed since the - * serialization of the stream class might have been triggered - * by the trace's destruction. In such a case, the trace's - * reference count would, unexepectedly, go through the sequence - * 1 -> 0 -> 1 -> 0 -> ..., provoking an endless loop of destruction - * and serialization. - */ - trace = bt_stream_class_borrow_trace(stream_class); - assert(trace); - packet_header_type = bt_trace_get_packet_header_type(trace); - trace = NULL; - if (packet_header_type) { - struct bt_field_type *stream_id_type; - - stream_id_type = - bt_field_type_structure_get_field_type_by_name( - packet_header_type, "stream_id"); - if (stream_id_type) { - /* - * Only set the stream's id if the trace's packet header - * contains a stream_id field. This field is only - * needed if the trace contains only one stream - * class. - */ - g_string_append_printf(context->string, - "\tid = %" PRId64 ";\n", stream_class->id); - } - bt_put(stream_id_type); - } - if (stream_class->event_header_type) { - BT_LOGD_STR("Serializing stream class's event header field type's metadata."); - g_string_append(context->string, "\tevent.header := "); - ret = bt_field_type_serialize(stream_class->event_header_type, - context); - if (ret) { - BT_LOGW("Cannot serialize stream class's event header field type's metadata: " - "ret=%d", ret); - goto end; - } - g_string_append(context->string, ";"); - } - - - if (stream_class->packet_context_type) { - BT_LOGD_STR("Serializing stream class's packet context field type's metadata."); - g_string_append(context->string, "\n\n\tpacket.context := "); - ret = bt_field_type_serialize(stream_class->packet_context_type, - context); - if (ret) { - BT_LOGW("Cannot serialize stream class's packet context field type's metadata: " - "ret=%d", ret); - goto end; - } - g_string_append(context->string, ";"); - } - - if (stream_class->event_context_type) { - BT_LOGD_STR("Serializing stream class's event context field type's metadata."); - g_string_append(context->string, "\n\n\tevent.context := "); - ret = bt_field_type_serialize( - stream_class->event_context_type, context); - if (ret) { - BT_LOGW("Cannot serialize stream class's event context field type's metadata: " - "ret=%d", ret); - goto end; - } - g_string_append(context->string, ";"); - } - - g_string_append(context->string, "\n};\n\n"); - - for (i = 0; i < stream_class->event_classes->len; i++) { - struct bt_event_class *event_class = - stream_class->event_classes->pdata[i]; - - ret = bt_event_class_serialize(event_class, context); - if (ret) { - BT_LOGW("Cannot serialize event class's metadata: " - "event-class-addr=%p, event-class-name=\"%s\", " - "event-class-id=%" PRId64, - event_class, - bt_event_class_get_name(event_class), - bt_event_class_get_id(event_class)); - goto end; - } - } -end: - bt_put(packet_header_type); - context->current_indentation_level = 0; - return ret; -} - -static -void bt_stream_class_destroy(struct bt_object *obj) -{ - struct bt_stream_class *stream_class; - - stream_class = container_of(obj, struct bt_stream_class, base); - 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)); - bt_put(stream_class->clock); - bt_put(stream_class->clock_class); - - if (stream_class->event_classes_ht) { - g_hash_table_destroy(stream_class->event_classes_ht); - } - if (stream_class->event_classes) { - BT_LOGD_STR("Destroying event classes."); - g_ptr_array_free(stream_class->event_classes, TRUE); - } - - if (stream_class->name) { - g_string_free(stream_class->name, TRUE); - } - - BT_LOGD_STR("Putting event header field type."); - bt_put(stream_class->event_header_type); - BT_LOGD_STR("Putting packet context field type."); - bt_put(stream_class->packet_context_type); - BT_LOGD_STR("Putting event context field type."); - bt_put(stream_class->event_context_type); - g_free(stream_class); + bt_field_type_common_freeze(stream_class->event_header_field_type); + bt_field_type_common_freeze(stream_class->packet_context_field_type); + bt_field_type_common_freeze(stream_class->event_context_field_type); + bt_clock_class_freeze(stream_class->clock_class); } -static -int init_event_header(struct bt_stream_class *stream_class) -{ - int ret = 0; - struct bt_field_type *event_header_type = - bt_field_type_structure_create(); - struct bt_field_type *_uint32_t = - get_field_type(FIELD_TYPE_ALIAS_UINT32_T); - struct bt_field_type *_uint64_t = - get_field_type(FIELD_TYPE_ALIAS_UINT64_T); - - if (!event_header_type) { - BT_LOGE_STR("Cannot create empty structure field type."); - ret = -1; - goto end; - } - - ret = bt_field_type_structure_add_field(event_header_type, - _uint32_t, "id"); - if (ret) { - BT_LOGE_STR("Cannot add `id` field to event header field type."); - goto end; - } - - ret = bt_field_type_structure_add_field(event_header_type, - _uint64_t, "timestamp"); - if (ret) { - BT_LOGE_STR("Cannot add `timestamp` field to event header field type."); - goto end; - } - - BT_MOVE(stream_class->event_header_type, event_header_type); -end: - if (ret) { - bt_put(event_header_type); - } - - bt_put(_uint32_t); - bt_put(_uint64_t); - return ret; -} - -static -int init_packet_context(struct bt_stream_class *stream_class) -{ - int ret = 0; - struct bt_field_type *packet_context_type = - bt_field_type_structure_create(); - struct bt_field_type *_uint64_t = - get_field_type(FIELD_TYPE_ALIAS_UINT64_T); - struct bt_field_type *ts_begin_end_uint64_t; - - if (!packet_context_type) { - BT_LOGE_STR("Cannot create empty structure field type."); - ret = -1; - goto end; - } - - ts_begin_end_uint64_t = bt_field_type_copy(_uint64_t); - if (!ts_begin_end_uint64_t) { - BT_LOGE_STR("Cannot copy integer field type for `timestamp_begin` and `timestamp_end` fields."); - ret = -1; - goto end; - } - - /* - * We create a stream packet context as proposed in the CTF - * specification. - */ - ret = bt_field_type_structure_add_field(packet_context_type, - ts_begin_end_uint64_t, "timestamp_begin"); - if (ret) { - BT_LOGE_STR("Cannot add `timestamp_begin` field to event header field type."); - goto end; - } - - ret = bt_field_type_structure_add_field(packet_context_type, - ts_begin_end_uint64_t, "timestamp_end"); - if (ret) { - BT_LOGE_STR("Cannot add `timestamp_end` field to event header field type."); - goto end; - } - - ret = bt_field_type_structure_add_field(packet_context_type, - _uint64_t, "content_size"); - if (ret) { - BT_LOGE_STR("Cannot add `content_size` field to event header field type."); - goto end; - } - - ret = bt_field_type_structure_add_field(packet_context_type, - _uint64_t, "packet_size"); - if (ret) { - BT_LOGE_STR("Cannot add `packet_size` field to event header field type."); - goto end; - } - - ret = bt_field_type_structure_add_field(packet_context_type, - _uint64_t, "events_discarded"); - if (ret) { - BT_LOGE_STR("Cannot add `events_discarded` field to event header field type."); - goto end; - } - - BT_MOVE(stream_class->packet_context_type, packet_context_type); -end: - if (ret) { - bt_put(packet_context_type); - goto end; - } - - bt_put(_uint64_t); - bt_put(ts_begin_end_uint64_t); - return ret; -} - -static -int try_map_clock_class(struct bt_stream_class *stream_class, - struct bt_field_type *parent_ft, const char *field_name) -{ - struct bt_clock_class *mapped_clock_class = NULL; - int ret = 0; - struct bt_field_type *ft = - bt_field_type_structure_get_field_type_by_name(parent_ft, - field_name); - - assert(stream_class->clock); - - if (!ft) { - /* Field does not exist: not an error */ - goto end; - } - - assert(bt_field_type_is_integer(ft)); - mapped_clock_class = - bt_field_type_integer_get_mapped_clock_class(ft); - if (!mapped_clock_class) { - struct bt_field_type *ft_copy; - - if (!stream_class->clock) { - BT_LOGW("Cannot automatically set field's type mapped clock class: stream class's clock is not set: " - "stream-class-addr=%p, stream-class-name=\"%s\", " - "stream-class-id=%" PRId64 ", ft-addr=%p", - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class), ft); - ret = -1; - goto end; - } - - ft_copy = bt_field_type_copy(ft); - if (!ft_copy) { - BT_LOGE("Failed to copy integer field type: ft-addr=%p", - ft); - } - - ret = bt_field_type_integer_set_mapped_clock_class_no_check( - ft_copy, stream_class->clock->clock_class); - assert(ret == 0); - ret = bt_field_type_structure_replace_field(parent_ft, - field_name, ft_copy); - bt_put(ft_copy); - BT_LOGV("Automatically mapped field type to stream class's clock class: " - "stream-class-addr=%p, stream-class-name=\"%s\", " - "stream-class-id=%" PRId64 ", ft-addr=%p, " - "ft-copy-addr=%p", - stream_class, bt_stream_class_get_name(stream_class), - bt_stream_class_get_id(stream_class), ft, ft_copy); - } - -end: - bt_put(ft); - bt_put(mapped_clock_class); - return ret; -} - -BT_HIDDEN -int bt_stream_class_map_clock_class( - struct bt_stream_class *stream_class, - struct bt_field_type *packet_context_type, - struct bt_field_type *event_header_type) +void bt_stream_class_freeze(struct bt_stream_class *stream_class) { - int ret = 0; - - assert(stream_class); - - if (!stream_class->clock) { - /* No clock class to map to */ - goto end; - } - - if (packet_context_type) { - if (try_map_clock_class(stream_class, packet_context_type, - "timestamp_begin")) { - BT_LOGE_STR("Cannot automatically set stream class's packet context field type's `timestamp_begin` field's mapped clock class."); - ret = -1; - goto end; - } - - if (try_map_clock_class(stream_class, packet_context_type, - "timestamp_end")) { - BT_LOGE_STR("Cannot automatically set stream class's packet context field type's `timestamp_end` field's mapped clock class."); - ret = -1; - goto end; - } - } - - if (event_header_type) { - if (try_map_clock_class(stream_class, event_header_type, - "timestamp")) { - BT_LOGE_STR("Cannot automatically set stream class's event header field type's `timestamp` field's mapped clock class."); - ret = -1; - goto end; - } - } - -end: - return ret; + bt_stream_class_common_freeze(BT_TO_COMMON(stream_class)); } BT_HIDDEN -int bt_stream_class_validate_single_clock_class( - struct bt_stream_class *stream_class, +int bt_stream_class_common_validate_single_clock_class( + struct bt_stream_class_common *stream_class, struct bt_clock_class **expected_clock_class) { int ret; uint64_t i; - assert(stream_class); - assert(expected_clock_class); - ret = bt_validate_single_clock_class(stream_class->packet_context_type, + BT_ASSERT(stream_class); + BT_ASSERT(expected_clock_class); + ret = bt_field_type_common_validate_single_clock_class( + stream_class->packet_context_field_type, expected_clock_class); if (ret) { BT_LOGW("Stream class's packet context field type " @@ -1402,13 +809,14 @@ int bt_stream_class_validate_single_clock_class( "stream-class-id=%" PRId64 ", " "ft-addr=%p", stream_class, - bt_stream_class_get_name(stream_class), + bt_stream_class_common_get_name(stream_class), stream_class->id, - stream_class->packet_context_type); + stream_class->packet_context_field_type); goto end; } - ret = bt_validate_single_clock_class(stream_class->event_header_type, + ret = bt_field_type_common_validate_single_clock_class( + stream_class->event_header_field_type, expected_clock_class); if (ret) { BT_LOGW("Stream class's event header field type " @@ -1419,13 +827,14 @@ int bt_stream_class_validate_single_clock_class( "stream-class-id=%" PRId64 ", " "ft-addr=%p", stream_class, - bt_stream_class_get_name(stream_class), + bt_stream_class_common_get_name(stream_class), stream_class->id, - stream_class->event_header_type); + stream_class->event_header_field_type); goto end; } - ret = bt_validate_single_clock_class(stream_class->event_context_type, + ret = bt_field_type_common_validate_single_clock_class( + stream_class->event_context_field_type, expected_clock_class); if (ret) { BT_LOGW("Stream class's event context field type " @@ -1436,19 +845,19 @@ int bt_stream_class_validate_single_clock_class( "stream-class-id=%" PRId64 ", " "ft-addr=%p", stream_class, - bt_stream_class_get_name(stream_class), + bt_stream_class_common_get_name(stream_class), stream_class->id, - stream_class->event_context_type); + stream_class->event_context_field_type); goto end; } for (i = 0; i < stream_class->event_classes->len; i++) { - struct bt_event_class *event_class = + struct bt_event_class_common *event_class = g_ptr_array_index(stream_class->event_classes, i); - assert(event_class); - ret = bt_event_class_validate_single_clock_class(event_class, - expected_clock_class); + BT_ASSERT(event_class); + ret = bt_event_class_common_validate_single_clock_class( + event_class, expected_clock_class); if (ret) { BT_LOGW("Stream class's event class contains a " "field type which is not recursively mapped to " @@ -1457,7 +866,7 @@ int bt_stream_class_validate_single_clock_class( "stream-class-name=\"%s\", " "stream-class-id=%" PRId64, stream_class, - bt_stream_class_get_name(stream_class), + bt_stream_class_common_get_name(stream_class), stream_class->id); goto end; }