From ac0c6bddcdde51dcbb46fc73c61d4f2330774451 Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Mon, 16 Jan 2017 15:02:23 -0500 Subject: [PATCH] ir: add bt_ctf_clock_class object, modify bt_ctf_clock object MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit In an attempt to isolate the CTF writer API from the general API (sometimes called the non-writer API), let's make the clock object a compound object made of: 1. A clock class object, a new object which holds all the static properties of a clock. 2. A single value. You can only use the clock object with the functions of the CTF writer API: * bt_ctf_writer_add_clock() * bt_ctf_stream_class_set_clock() * bt_ctf_stream_class_get_clock() The purpose of a clock object is to automate the setting of the `timestamp` field in event headers part of a CTF writer object. The clock object has nothing to do with the non-writer part of the API, that is, the one you use to write BT component classes and plugins. The functions above do this from now on: * bt_ctf_writer_add_clock(): Calls bt_ctf_trace_add_clock_class() on the clock class of the clock object parameter. * bt_ctf_stream_class_set_clock(): Registers the clock object as the current stream class's clock and maps the field named `timestamp` in the current event header field type to this same clock class. NOTE: If you set a custom event header field type after having called bt_ctf_stream_class_set_clock(), this mapping is LOST. When you call bt_ctf_stream_append_event(), the `timestamp` field of the event header is automatically set (from the stream class's clock's current value) if, and only if all the following conditions are satisfied: 1. The event header field `timestamp` exists and is an integer field. 2. The stream's class has a registered clock (set with bt_ctf_stream_class_set_clock()). 3. The event header field `timestamp` has its type mapped to a clock class which is also the clock class of the stream's class's registered clock. 4. The event header field `timestamp` is NOT set. From now on you cannot set a stream class's clock and add this stream class to a trace which was not created by a CTF writer. This enforces the fact that bt_ctf_stream_class_set_clock() and bt_ctf_stream_class_get_clock() are only part of the CTF writer API. A clock _class_ has no value, although you can create individual clock value objects linked to a specific clock class with bt_ctf_clock_value_create(). Note that everything related to clock value objects has zero effects on the CTF writer API. What would be named bt_ctf_clock_class_*_offset() after this massive renaming operation is named bt_ctf_clock_class_*_offset_cycles() for those functions to be self-documented, and for them to have names that are parallel with bt_ctf_clock_class_*_offset_s(). bt_ctf_field_type_integer_*_mapped_clock() functions are renamed to bt_ctf_field_type_integer_*_mapped_clock_class(). Component classes must now include `babeltrace/ctf-ir/clock-class.h` to deal with clock class objects. Programs which use the CTF writer API must still include `babeltrace/ctf-writer/clock.h`. Signed-off-by: Philippe Proulx Signed-off-by: Jérémie Galarneau --- formats/ctf/ir/Makefile.am | 2 +- formats/ctf/ir/{clock.c => clock-class.c} | 285 +++++++--------- formats/ctf/ir/event.c | 136 +------- formats/ctf/ir/field-types.c | 27 +- formats/ctf/ir/stream-class.c | 56 ++-- formats/ctf/ir/stream.c | 126 ++++++- formats/ctf/ir/trace.c | 119 ++++--- formats/ctf/writer/Makefile.am | 1 + formats/ctf/writer/clock.c | 307 ++++++++++++++++++ formats/ctf/writer/writer.c | 4 +- include/Makefile.am | 5 +- ...lock-internal.h => clock-class-internal.h} | 31 +- include/babeltrace/ctf-ir/clock-class.h | 88 +++++ include/babeltrace/ctf-ir/clock.h | 266 --------------- include/babeltrace/ctf-ir/event-internal.h | 12 - include/babeltrace/ctf-ir/event.h | 5 +- .../babeltrace/ctf-ir/field-types-internal.h | 3 +- include/babeltrace/ctf-ir/field-types.h | 16 +- include/babeltrace/ctf-ir/stream-class.h | 4 - include/babeltrace/ctf-ir/trace-internal.h | 2 +- include/babeltrace/ctf-ir/trace.h | 40 +-- .../babeltrace/ctf-writer/clock-internal.h | 45 +++ include/babeltrace/ctf-writer/clock.h | 204 +++++++++++- include/babeltrace/ctf-writer/stream-class.h | 3 + .../ctf/common/metadata/visitor-generate-ir.c | 34 +- plugins/ctf/common/notif-iter/notif-iter.c | 56 ++-- plugins/ctf/fs/fs.c | 12 +- plugins/text/print.c | 22 +- plugins/trimmer/iterator.c | 23 +- plugins/writer/write.c | 68 ++-- tests/lib/test_ctf_writer.c | 181 +++++------ 31 files changed, 1226 insertions(+), 957 deletions(-) rename formats/ctf/ir/{clock.c => clock-class.c} (51%) create mode 100644 formats/ctf/writer/clock.c rename include/babeltrace/ctf-ir/{clock-internal.h => clock-class-internal.h} (70%) create mode 100644 include/babeltrace/ctf-ir/clock-class.h delete mode 100644 include/babeltrace/ctf-ir/clock.h create mode 100644 include/babeltrace/ctf-writer/clock-internal.h diff --git a/formats/ctf/ir/Makefile.am b/formats/ctf/ir/Makefile.am index 4a8c5344..b22fa80a 100644 --- a/formats/ctf/ir/Makefile.am +++ b/formats/ctf/ir/Makefile.am @@ -4,7 +4,7 @@ noinst_LTLIBRARIES = libctf-ir.la libctf_ir_la_SOURCES = \ attributes.c \ - clock.c \ + clock-class.c \ event.c \ event-class.c \ fields.c \ diff --git a/formats/ctf/ir/clock.c b/formats/ctf/ir/clock-class.c similarity index 51% rename from formats/ctf/ir/clock.c rename to formats/ctf/ir/clock-class.c index e24b864b..c51b5aab 100644 --- a/formats/ctf/ir/clock.c +++ b/formats/ctf/ir/clock-class.c @@ -1,7 +1,7 @@ /* - * clock.c + * clock-class.c * - * Babeltrace CTF IR - Clock + * Babeltrace CTF IR - Clock class * * Copyright 2013, 2014 Jérémie Galarneau * @@ -26,29 +26,28 @@ * SOFTWARE. */ -#include +#include #include #include -#include #include #include #include static -void bt_ctf_clock_destroy(struct bt_object *obj); +void bt_ctf_clock_class_destroy(struct bt_object *obj); BT_HIDDEN -bool bt_ctf_clock_is_valid(struct bt_ctf_clock *clock) +bool bt_ctf_clock_class_is_valid(struct bt_ctf_clock_class *clock_class) { - return clock && clock->name; + return clock_class && clock_class->name; } -int bt_ctf_clock_set_name(struct bt_ctf_clock *clock, +int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class *clock_class, const char *name) { int ret = 0; - if (!clock || clock->frozen) { + if (!clock_class || clock_class->frozen) { ret = -1; goto end; } @@ -58,11 +57,11 @@ int bt_ctf_clock_set_name(struct bt_ctf_clock *clock, goto end; } - if (clock->name) { - g_string_assign(clock->name, name); + if (clock_class->name) { + g_string_assign(clock_class->name, name); } else { - clock->name = g_string_new(name); - if (!clock->name) { + clock_class->name = g_string_new(name); + if (!clock_class->name) { ret = -1; goto end; } @@ -72,258 +71,264 @@ end: return ret; } -struct bt_ctf_clock *bt_ctf_clock_create(const char *name) +struct bt_ctf_clock_class *bt_ctf_clock_class_create(const char *name) { int ret; - struct bt_ctf_clock *clock = g_new0(struct bt_ctf_clock, 1); + struct bt_ctf_clock_class *clock_class = + g_new0(struct bt_ctf_clock_class, 1); - if (!clock) { + if (!clock_class) { goto error; } - clock->precision = 1; - clock->frequency = 1000000000; - bt_object_init(clock, bt_ctf_clock_destroy); + clock_class->precision = 1; + clock_class->frequency = 1000000000; + bt_object_init(clock_class, bt_ctf_clock_class_destroy); if (name) { - ret = bt_ctf_clock_set_name(clock, name); + ret = bt_ctf_clock_class_set_name(clock_class, name); if (ret) { goto error; } } - ret = bt_uuid_generate(clock->uuid); + ret = bt_uuid_generate(clock_class->uuid); if (ret) { goto error; } - /* - * For backward compatibility reasons, a fresh clock can have - * a value because it could be added to a trace created by a - * CTF writer. As soon as this clock is added to a non-writer - * trace, then its value/time functions will be disabled. - */ - clock->has_value = 1; - clock->uuid_set = 1; - return clock; + clock_class->uuid_set = 1; + return clock_class; error: - BT_PUT(clock); - return clock; + BT_PUT(clock_class); + return clock_class; } -const char *bt_ctf_clock_get_name(struct bt_ctf_clock *clock) +const char *bt_ctf_clock_class_get_name(struct bt_ctf_clock_class *clock_class) { const char *ret = NULL; - if (!clock) { + if (!clock_class) { goto end; } - if (clock->name) { - ret = clock->name->str; + if (clock_class->name) { + ret = clock_class->name->str; } end: return ret; } -const char *bt_ctf_clock_get_description(struct bt_ctf_clock *clock) +const char *bt_ctf_clock_class_get_description( + struct bt_ctf_clock_class *clock_class) { const char *ret = NULL; - if (!clock) { + if (!clock_class) { goto end; } - if (clock->description) { - ret = clock->description->str; + if (clock_class->description) { + ret = clock_class->description->str; } end: return ret; } -int bt_ctf_clock_set_description(struct bt_ctf_clock *clock, const char *desc) +int bt_ctf_clock_class_set_description(struct bt_ctf_clock_class *clock_class, + const char *desc) { int ret = 0; - if (!clock || !desc || clock->frozen) { + if (!clock_class || !desc || clock_class->frozen) { ret = -1; goto end; } - clock->description = g_string_new(desc); - ret = clock->description ? 0 : -1; + clock_class->description = g_string_new(desc); + ret = clock_class->description ? 0 : -1; end: return ret; } -uint64_t bt_ctf_clock_get_frequency(struct bt_ctf_clock *clock) +uint64_t bt_ctf_clock_class_get_frequency( + struct bt_ctf_clock_class *clock_class) { uint64_t ret = -1ULL; - if (!clock) { + if (!clock_class) { goto end; } - ret = clock->frequency; + ret = clock_class->frequency; end: return ret; } -int bt_ctf_clock_set_frequency(struct bt_ctf_clock *clock, uint64_t freq) +int bt_ctf_clock_class_set_frequency(struct bt_ctf_clock_class *clock_class, + uint64_t freq) { int ret = 0; - if (!clock || clock->frozen) { + if (!clock_class || clock_class->frozen) { ret = -1; goto end; } - clock->frequency = freq; + clock_class->frequency = freq; end: return ret; } -uint64_t bt_ctf_clock_get_precision(struct bt_ctf_clock *clock) +uint64_t bt_ctf_clock_class_get_precision(struct bt_ctf_clock_class *clock_class) { uint64_t ret = -1ULL; - if (!clock) { + if (!clock_class) { goto end; } - ret = clock->precision; + ret = clock_class->precision; end: return ret; } -int bt_ctf_clock_set_precision(struct bt_ctf_clock *clock, uint64_t precision) +int bt_ctf_clock_class_set_precision(struct bt_ctf_clock_class *clock_class, + uint64_t precision) { int ret = 0; - if (!clock || clock->frozen) { + if (!clock_class || clock_class->frozen) { ret = -1; goto end; } - clock->precision = precision; + clock_class->precision = precision; end: return ret; } -int bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock, int64_t *offset_s) +int bt_ctf_clock_class_get_offset_s(struct bt_ctf_clock_class *clock_class, + int64_t *offset_s) { int ret = 0; - if (!clock || !offset_s) { + if (!clock_class || !offset_s) { ret = -1; goto end; } - *offset_s = clock->offset_s; + *offset_s = clock_class->offset_s; end: return ret; } -int bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock, int64_t offset_s) +int bt_ctf_clock_class_set_offset_s(struct bt_ctf_clock_class *clock_class, + int64_t offset_s) { int ret = 0; - if (!clock || clock->frozen) { + if (!clock_class || clock_class->frozen) { ret = -1; goto end; } - clock->offset_s = offset_s; + clock_class->offset_s = offset_s; end: return ret; } -int bt_ctf_clock_get_offset(struct bt_ctf_clock *clock, int64_t *offset) +int bt_ctf_clock_class_get_offset_cycles(struct bt_ctf_clock_class *clock_class, + int64_t *offset) { int ret = 0; - if (!clock || !offset) { + if (!clock_class || !offset) { ret = -1; goto end; } - *offset = clock->offset; + *offset = clock_class->offset; end: return ret; } -int bt_ctf_clock_set_offset(struct bt_ctf_clock *clock, int64_t offset) +int bt_ctf_clock_class_set_offset_cycles(struct bt_ctf_clock_class *clock_class, + int64_t offset) { int ret = 0; - if (!clock || clock->frozen) { + if (!clock_class || clock_class->frozen) { ret = -1; goto end; } - clock->offset = offset; + clock_class->offset = offset; end: return ret; } -int bt_ctf_clock_get_is_absolute(struct bt_ctf_clock *clock) +int bt_ctf_clock_class_get_is_absolute(struct bt_ctf_clock_class *clock_class) { int ret = -1; - if (!clock) { + if (!clock_class) { goto end; } - ret = clock->absolute; + ret = clock_class->absolute; end: return ret; } -int bt_ctf_clock_set_is_absolute(struct bt_ctf_clock *clock, int is_absolute) +int bt_ctf_clock_class_set_is_absolute(struct bt_ctf_clock_class *clock_class, + int is_absolute) { int ret = 0; - if (!clock || clock->frozen) { + if (!clock_class || clock_class->frozen) { ret = -1; goto end; } - clock->absolute = !!is_absolute; + clock_class->absolute = !!is_absolute; end: return ret; } -const unsigned char *bt_ctf_clock_get_uuid(struct bt_ctf_clock *clock) +const unsigned char *bt_ctf_clock_class_get_uuid( + struct bt_ctf_clock_class *clock_class) { const unsigned char *ret; - if (!clock || !clock->uuid_set) { + if (!clock_class || !clock_class->uuid_set) { ret = NULL; goto end; } - ret = clock->uuid; + ret = clock_class->uuid; end: return ret; } -int bt_ctf_clock_set_uuid(struct bt_ctf_clock *clock, const unsigned char *uuid) +int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class *clock_class, + const unsigned char *uuid) { int ret = 0; - if (!clock || !uuid || clock->frozen) { + if (!clock_class || !uuid || clock_class->frozen) { ret = -1; goto end; } - memcpy(clock->uuid, uuid, sizeof(uuid_t)); - clock->uuid_set = 1; + memcpy(clock_class->uuid, uuid, sizeof(uuid_t)); + clock_class->uuid_set = 1; end: return ret; } -uint64_t ns_from_value(uint64_t frequency, uint64_t value) +static uint64_t ns_from_value(uint64_t frequency, uint64_t value) { uint64_t ns; @@ -336,134 +341,68 @@ uint64_t ns_from_value(uint64_t frequency, uint64_t value) return ns; } -int bt_ctf_clock_set_time(struct bt_ctf_clock *clock, int64_t time) -{ - int ret = 0; - int64_t value; - - /* Timestamps are strictly monotonic */ - if (!clock) { - ret = -1; - goto end; - } - - - if (!clock->has_value) { - /* - * Clock belongs to a non-writer mode trace and thus - * this function is disabled. - */ - ret = -1; - goto end; - } - - /* Common case where cycles are actually nanoseconds */ - if (clock->frequency == 1000000000) { - value = time; - } else { - value = (uint64_t) (((double) time * - (double) clock->frequency) / 1e9); - } - - if (clock->value > value) { - /* Timestamps must be strictly monotonic. */ - ret = -1; - goto end; - } - - clock->value = value; -end: - return ret; -} - -void bt_ctf_clock_get(struct bt_ctf_clock *clock) -{ - bt_get(clock); -} - -void bt_ctf_clock_put(struct bt_ctf_clock *clock) -{ - bt_put(clock); -} - BT_HIDDEN -void bt_ctf_clock_freeze(struct bt_ctf_clock *clock) +void bt_ctf_clock_class_freeze(struct bt_ctf_clock_class *clock_class) { - if (!clock) { + if (!clock_class) { return; } - clock->frozen = 1; + clock_class->frozen = 1; } BT_HIDDEN -void bt_ctf_clock_serialize(struct bt_ctf_clock *clock, +void bt_ctf_clock_class_serialize(struct bt_ctf_clock_class *clock_class, struct metadata_context *context) { unsigned char *uuid; - if (!clock || !context) { + if (!clock_class || !context) { return; } - uuid = clock->uuid; + uuid = clock_class->uuid; g_string_append(context->string, "clock {\n"); g_string_append_printf(context->string, "\tname = %s;\n", - clock->name->str); + clock_class->name->str); g_string_append_printf(context->string, "\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n", uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]); - if (clock->description) { + if (clock_class->description) { g_string_append_printf(context->string, "\tdescription = \"%s\";\n", - clock->description->str); + clock_class->description->str); } g_string_append_printf(context->string, "\tfreq = %" PRIu64 ";\n", - clock->frequency); + clock_class->frequency); g_string_append_printf(context->string, "\tprecision = %" PRIu64 ";\n", - clock->precision); + clock_class->precision); g_string_append_printf(context->string, "\toffset_s = %" PRIu64 ";\n", - clock->offset_s); + clock_class->offset_s); g_string_append_printf(context->string, "\toffset = %" PRIu64 ";\n", - clock->offset); + clock_class->offset); g_string_append_printf(context->string, "\tabsolute = %s;\n", - clock->absolute ? "TRUE" : "FALSE"); + clock_class->absolute ? "TRUE" : "FALSE"); g_string_append(context->string, "};\n\n"); } -BT_HIDDEN -int bt_ctf_clock_get_value(struct bt_ctf_clock *clock, uint64_t *value) -{ - int ret = 0; - - if (!clock || !value) { - ret = -1; - goto end; - } - - *value = clock->value; -end: - return ret; -} - static -void bt_ctf_clock_destroy(struct bt_object *obj) +void bt_ctf_clock_class_destroy(struct bt_object *obj) { - struct bt_ctf_clock *clock; + struct bt_ctf_clock_class *clock_class; - clock = container_of(obj, struct bt_ctf_clock, base); - if (clock->name) { - g_string_free(clock->name, TRUE); + clock_class = container_of(obj, struct bt_ctf_clock_class, base); + if (clock_class->name) { + g_string_free(clock_class->name, TRUE); } - - if (clock->description) { - g_string_free(clock->description, TRUE); + if (clock_class->description) { + g_string_free(clock_class->description, TRUE); } - g_free(clock); + g_free(clock_class); } static @@ -481,11 +420,11 @@ void bt_ctf_clock_value_destroy(struct bt_object *obj) } struct bt_ctf_clock_value *bt_ctf_clock_value_create( - struct bt_ctf_clock *clock, uint64_t value) + struct bt_ctf_clock_class *clock_class, uint64_t value) { struct bt_ctf_clock_value *ret = NULL; - if (!clock) { + if (!clock_class) { goto end; } @@ -495,7 +434,7 @@ struct bt_ctf_clock_value *bt_ctf_clock_value_create( } bt_object_init(ret, bt_ctf_clock_value_destroy); - ret->clock_class = bt_get(clock); + ret->clock_class = bt_get(clock_class); ret->value = value; end: return ret; diff --git a/formats/ctf/ir/event.c b/formats/ctf/ir/event.c index c2178cdb..95168a57 100644 --- a/formats/ctf/ir/event.c +++ b/formats/ctf/ir/event.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include #include @@ -47,8 +47,6 @@ static void bt_ctf_event_destroy(struct bt_object *obj); -static -int set_integer_field_value(struct bt_ctf_field *field, uint64_t value); struct bt_ctf_event *bt_ctf_event_create(struct bt_ctf_event_class *event_class) { @@ -565,15 +563,15 @@ void bt_ctf_event_destroy(struct bt_object *obj) } struct bt_ctf_clock_value *bt_ctf_event_get_clock_value( - struct bt_ctf_event *event, struct bt_ctf_clock *clock) + struct bt_ctf_event *event, struct bt_ctf_clock_class *clock_class) { struct bt_ctf_clock_value *clock_value = NULL; - if (!event || !clock) { + if (!event || !clock_class) { goto end; } - clock_value = g_hash_table_lookup(event->clock_values, clock); + clock_value = g_hash_table_lookup(event->clock_values, clock_class); if (!clock_value) { goto end; } @@ -584,56 +582,19 @@ end: } int bt_ctf_event_set_clock_value(struct bt_ctf_event *event, - struct bt_ctf_clock *clock, struct bt_ctf_clock_value *value) -{ - int ret = 0; - - if (!event || !clock || !value || event->frozen) { - ret = -1; - goto end; - } - - g_hash_table_insert(event->clock_values, bt_get(clock), bt_get(value)); -end: - return ret; -} - -static -int set_integer_field_value(struct bt_ctf_field* field, uint64_t value) + struct bt_ctf_clock_class *clock_class, + struct bt_ctf_clock_value *value) { int ret = 0; - struct bt_ctf_field_type *field_type = NULL; - - if (!field) { - ret = -1; - goto end; - } - field_type = bt_ctf_field_get_type(field); - assert(field_type); - - if (bt_ctf_field_type_get_type_id(field_type) != - BT_CTF_TYPE_ID_INTEGER) { - /* Not an integer and the value is unset, error. */ + if (!event || !clock_class || !value || event->frozen) { ret = -1; goto end; } - if (bt_ctf_field_type_integer_get_signed(field_type)) { - ret = bt_ctf_field_signed_integer_set_value(field, (int64_t) value); - if (ret) { - /* Value is out of range, error. */ - goto end; - } - } else { - ret = bt_ctf_field_unsigned_integer_set_value(field, value); - if (ret) { - /* Value is out of range, error. */ - goto end; - } - } + g_hash_table_insert(event->clock_values, bt_get(clock_class), + bt_get(value)); end: - bt_put(field_type); return ret; } @@ -701,85 +662,6 @@ end: return ret; } -BT_HIDDEN -int bt_ctf_event_populate_event_header(struct bt_ctf_event *event) -{ - int ret = 0; - struct bt_ctf_field *id_field = NULL, *timestamp_field = NULL; - struct bt_ctf_clock *mapped_clock = NULL; - - if (!event || event->frozen) { - ret = -1; - goto end; - } - - id_field = bt_ctf_field_structure_get_field(event->event_header, "id"); - if (id_field && !bt_ctf_field_is_set(id_field)) { - ret = set_integer_field_value(id_field, - (uint64_t) bt_ctf_event_class_get_id( - event->event_class)); - if (ret) { - goto end; - } - } - - timestamp_field = bt_ctf_field_structure_get_field(event->event_header, - "timestamp"); - if (timestamp_field && !bt_ctf_field_is_set(timestamp_field)) { - struct bt_ctf_field_type *timestamp_field_type = - bt_ctf_field_get_type(timestamp_field); - - assert(timestamp_field_type); - mapped_clock = bt_ctf_field_type_integer_get_mapped_clock( - timestamp_field_type); - bt_put(timestamp_field_type); - if (mapped_clock) { - /* - * Babeltrace 2.0 introduced a notion of per-event clock - * values which can be queried using a "clock" instance. - * - * However, the original CTF-Writer (BT 1.x) had a - * notion of per-stream clock which is sampled on - * a call to append an event to a stream. - * - * If the event has a clock value associated with the - * mapped clock, we ignore the pre-2.0 behaviour and - * populate the timestamp field using the clock value. - */ - uint64_t timestamp = 0; - struct bt_ctf_clock_value *clock_value; - - clock_value = bt_ctf_event_get_clock_value(event, - mapped_clock); - if (clock_value) { - ret = bt_ctf_clock_value_get_value(clock_value, - ×tamp); - bt_put(clock_value); - if (ret) { - goto end; - } - } else { - ret = bt_ctf_clock_get_value(mapped_clock, - ×tamp); - if (ret) { - goto end; - } - } - - ret = set_integer_field_value(timestamp_field, - timestamp); - if (ret) { - goto end; - } - } - } -end: - bt_put(id_field); - bt_put(timestamp_field); - bt_put(mapped_clock); - return ret; -} - struct bt_ctf_packet *bt_ctf_event_get_packet(struct bt_ctf_event *event) { struct bt_ctf_packet *packet = NULL; diff --git a/formats/ctf/ir/field-types.c b/formats/ctf/ir/field-types.c index c9c424ea..ad34a86f 100644 --- a/formats/ctf/ir/field-types.c +++ b/formats/ctf/ir/field-types.c @@ -30,8 +30,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -820,39 +820,38 @@ end: return ret; } -struct bt_ctf_clock *bt_ctf_field_type_integer_get_mapped_clock( +struct bt_ctf_clock_class *bt_ctf_field_type_integer_get_mapped_clock_class( struct bt_ctf_field_type *type) { struct bt_ctf_field_type_integer *integer; - struct bt_ctf_clock *clock = NULL; + struct bt_ctf_clock_class *clock_class = NULL; if (!type) { goto end; } integer = container_of(type, struct bt_ctf_field_type_integer, parent); - clock = integer->mapped_clock; - bt_get(clock); + clock_class = integer->mapped_clock; + bt_get(clock_class); end: - return clock; + return clock_class; } -int bt_ctf_field_type_integer_set_mapped_clock( +int bt_ctf_field_type_integer_set_mapped_clock_class( struct bt_ctf_field_type *type, - struct bt_ctf_clock *clock) + struct bt_ctf_clock_class *clock_class) { struct bt_ctf_field_type_integer *integer; int ret = 0; - if (!type || type->frozen || !bt_ctf_clock_is_valid(clock)) { + if (!type || type->frozen || !bt_ctf_clock_class_is_valid(clock_class)) { ret = -1; goto end; } integer = container_of(type, struct bt_ctf_field_type_integer, parent); bt_put(integer->mapped_clock); - bt_get(clock); - integer->mapped_clock = clock; + integer->mapped_clock = bt_get(clock_class); end: return ret; } @@ -2726,7 +2725,7 @@ void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *type) type, struct bt_ctf_field_type_integer, parent); if (integer_type->mapped_clock) { - bt_ctf_clock_freeze(integer_type->mapped_clock); + bt_ctf_clock_class_freeze(integer_type->mapped_clock); } generic_field_type_freeze(type); @@ -2861,7 +2860,7 @@ int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type, get_integer_base_string(integer->declaration.base), get_byte_order_string(integer->declaration.byte_order)); if (integer->mapped_clock) { - const char *clock_name = bt_ctf_clock_get_name( + const char *clock_name = bt_ctf_clock_class_get_name( integer->mapped_clock); if (!clock_name) { diff --git a/formats/ctf/ir/stream-class.c b/formats/ctf/ir/stream-class.c index 313d51bc..5c5db665 100644 --- a/formats/ctf/ir/stream-class.c +++ b/formats/ctf/ir/stream-class.c @@ -27,7 +27,8 @@ */ #include -#include +#include +#include #include #include #include @@ -138,8 +139,7 @@ struct bt_ctf_clock *bt_ctf_stream_class_get_clock( goto end; } - clock = stream_class->clock; - bt_get(clock); + clock = bt_get(stream_class->clock); end: return clock; } @@ -150,46 +150,41 @@ int bt_ctf_stream_class_set_clock(struct bt_ctf_stream_class *stream_class, int ret = 0; struct bt_ctf_field_type *timestamp_field = NULL; - if (!stream_class || stream_class->frozen || - !bt_ctf_clock_is_valid(clock)) { + if (!stream_class || !clock || stream_class->frozen) { ret = -1; goto end; } /* - * Look for a "timestamp" field in the stream class' event header type - * and map the stream's clock to that field if no current mapping is - * currently set. + * Look for a "timestamp" integer field type in the stream + * class's event header field type and map the stream class's + * clock's class to that field type if there's no current + * mapping. */ timestamp_field = bt_ctf_field_type_structure_get_field_type_by_name( stream_class->event_header_type, "timestamp"); if (timestamp_field) { - struct bt_ctf_clock *mapped_clock; - - mapped_clock = bt_ctf_field_type_integer_get_mapped_clock( - timestamp_field); - if (mapped_clock) { - bt_put(mapped_clock); - goto end; + struct bt_ctf_clock_class *mapped_clock_class = + bt_ctf_field_type_integer_get_mapped_clock_class( + timestamp_field); + + if (!mapped_clock_class) { + ret = bt_ctf_field_type_integer_set_mapped_clock_class( + timestamp_field, clock->clock_class); + if (ret) { + goto end; + } } - ret = bt_ctf_field_type_integer_set_mapped_clock( - timestamp_field, clock); - if (ret) { - goto end; - } + BT_PUT(mapped_clock_class); } - if (stream_class->clock) { - bt_put(stream_class->clock); - } + /* Replace the current clock of this stream class. */ + bt_put(stream_class->clock); + stream_class->clock = bt_get(clock); - stream_class->clock = clock; - bt_get(clock); end: - if (timestamp_field) { - bt_put(timestamp_field); - } + bt_put(timestamp_field); return ret; } @@ -758,7 +753,10 @@ void bt_ctf_stream_class_freeze(struct bt_ctf_stream_class *stream_class) bt_ctf_field_type_freeze(stream_class->event_header_type); bt_ctf_field_type_freeze(stream_class->packet_context_type); bt_ctf_field_type_freeze(stream_class->event_context_type); - bt_ctf_clock_freeze(stream_class->clock); + + if (stream_class->clock) { + bt_ctf_clock_class_freeze(stream_class->clock->clock_class); + } } BT_HIDDEN diff --git a/formats/ctf/ir/stream.c b/formats/ctf/ir/stream.c index 5e9e1337..74c6f52b 100644 --- a/formats/ctf/ir/stream.c +++ b/formats/ctf/ir/stream.c @@ -26,8 +26,9 @@ * SOFTWARE. */ -#include -#include +#include +#include +#include #include #include #include @@ -48,6 +49,45 @@ void bt_ctf_stream_destroy(struct bt_object *obj); static int set_structure_field_integer(struct bt_ctf_field *, char *, uint64_t); +static +int set_integer_field_value(struct bt_ctf_field* field, uint64_t value) +{ + int ret = 0; + struct bt_ctf_field_type *field_type = NULL; + + if (!field) { + ret = -1; + goto end; + } + + field_type = bt_ctf_field_get_type(field); + assert(field_type); + + if (bt_ctf_field_type_get_type_id(field_type) != + BT_CTF_TYPE_ID_INTEGER) { + /* Not an integer and the value is unset, error. */ + ret = -1; + goto end; + } + + if (bt_ctf_field_type_integer_get_signed(field_type)) { + ret = bt_ctf_field_signed_integer_set_value(field, (int64_t) value); + if (ret) { + /* Value is out of range, error. */ + goto end; + } + } else { + ret = bt_ctf_field_unsigned_integer_set_value(field, value); + if (ret) { + /* Value is out of range, error. */ + goto end; + } + } +end: + bt_put(field_type); + return ret; +} + static int set_packet_header_magic(struct bt_ctf_stream *stream) { @@ -553,6 +593,86 @@ end: bt_put(events_discarded_field_type); } +static int auto_populate_event_header(struct bt_ctf_stream *stream, + struct bt_ctf_event *event) +{ + int ret = 0; + struct bt_ctf_field *id_field = NULL, *timestamp_field = NULL; + struct bt_ctf_clock_class *mapped_clock_class = NULL; + + if (!event || event->frozen) { + ret = -1; + goto end; + } + + /* + * The condition to automatically set the ID are: + * + * 1. The event header field "id" exists and is an integer + * field. + * 2. The event header field "id" is NOT set. + */ + id_field = bt_ctf_field_structure_get_field(event->event_header, "id"); + if (id_field && !bt_ctf_field_is_set(id_field)) { + ret = set_integer_field_value(id_field, + (uint64_t) bt_ctf_event_class_get_id( + event->event_class)); + if (ret) { + goto end; + } + } + + /* + * The conditions to automatically set the timestamp are: + * + * 1. The event header field "timestamp" exists and is an + * integer field. + * 2. This stream's class has a registered clock (set with + * bt_ctf_stream_class_set_clock()). + * 3. The event header field "timestamp" has its type mapped to + * a clock class which is also the clock class of this + * stream's class's registered clock. + * 4. The event header field "timestamp" is NOT set. + */ + timestamp_field = bt_ctf_field_structure_get_field(event->event_header, + "timestamp"); + if (timestamp_field && !bt_ctf_field_is_set(timestamp_field) && + stream->stream_class->clock) { + struct bt_ctf_clock_class *stream_class_clock_class = + stream->stream_class->clock->clock_class; + struct bt_ctf_field_type *timestamp_field_type = + bt_ctf_field_get_type(timestamp_field); + + assert(timestamp_field_type); + mapped_clock_class = + bt_ctf_field_type_integer_get_mapped_clock_class( + timestamp_field_type); + BT_PUT(timestamp_field_type); + if (mapped_clock_class == stream_class_clock_class) { + uint64_t timestamp; + + ret = bt_ctf_clock_get_value( + stream->stream_class->clock, + ×tamp); + if (ret) { + goto end; + } + + ret = set_integer_field_value(timestamp_field, + timestamp); + if (ret) { + goto end; + } + } + } + +end: + bt_put(id_field); + bt_put(timestamp_field); + bt_put(mapped_clock_class); + return ret; +} + int bt_ctf_stream_append_event(struct bt_ctf_stream *stream, struct bt_ctf_event *event) { @@ -577,7 +697,7 @@ int bt_ctf_stream_append_event(struct bt_ctf_stream *stream, } bt_object_set_parent(event, stream); - ret = bt_ctf_event_populate_event_header(event); + ret = auto_populate_event_header(stream, event); if (ret) { goto error; } diff --git a/formats/ctf/ir/trace.c b/formats/ctf/ir/trace.c index dfb81551..9c314fe1 100644 --- a/formats/ctf/ir/trace.c +++ b/formats/ctf/ir/trace.c @@ -27,13 +27,14 @@ */ #include -#include +#include #include #include #include #include #include #include +#include #include #include #include @@ -383,44 +384,35 @@ end: return ret; } -int bt_ctf_trace_add_clock(struct bt_ctf_trace *trace, - struct bt_ctf_clock *clock) +int bt_ctf_trace_add_clock_class(struct bt_ctf_trace *trace, + struct bt_ctf_clock_class *clock_class) { int ret = 0; - struct search_query query = { .value = clock, .found = 0 }; + struct search_query query = { .value = clock_class, .found = 0 }; - if (!trace || !bt_ctf_clock_is_valid(clock)) { + if (!trace || !bt_ctf_clock_class_is_valid(clock_class)) { ret = -1; goto end; } - /* Check for duplicate clocks */ + /* Check for duplicate clock classes */ g_ptr_array_foreach(trace->clocks, value_exists, &query); if (query.found) { ret = -1; goto end; } - bt_get(clock); - g_ptr_array_add(trace->clocks, clock); - - if (!trace->is_created_by_writer) { - /* - * Non-writer mode trace: disable clock value functions - * because clock values are per-stream in that - * situation. - */ - clock->has_value = 0; - } + bt_get(clock_class); + g_ptr_array_add(trace->clocks, clock_class); if (trace->frozen) { - bt_ctf_clock_freeze(clock); + bt_ctf_clock_class_freeze(clock_class); } end: return ret; } -int bt_ctf_trace_get_clock_count(struct bt_ctf_trace *trace) +int bt_ctf_trace_get_clock_class_count(struct bt_ctf_trace *trace) { int ret = -1; @@ -433,19 +425,19 @@ end: return ret; } -struct bt_ctf_clock *bt_ctf_trace_get_clock(struct bt_ctf_trace *trace, - int index) +struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class( + struct bt_ctf_trace *trace, int index) { - struct bt_ctf_clock *clock = NULL; + struct bt_ctf_clock_class *clock_class = NULL; if (!trace || index < 0 || index >= trace->clocks->len) { goto end; } - clock = g_ptr_array_index(trace->clocks, index); - bt_get(clock); + clock_class = g_ptr_array_index(trace->clocks, index); + bt_get(clock_class); end: - return clock; + return clock_class; } int bt_ctf_trace_add_stream_class(struct bt_ctf_trace *trace, @@ -465,7 +457,6 @@ int bt_ctf_trace_add_stream_class(struct bt_ctf_trace *trace, struct bt_ctf_field_type *event_header_type = NULL; struct bt_ctf_field_type *stream_event_ctx_type = NULL; int event_class_count; - struct bt_ctf_clock *clock_to_add_to_trace = NULL; struct bt_ctf_trace *current_parent_trace = NULL; if (!trace || !stream_class) { @@ -493,29 +484,41 @@ int bt_ctf_trace_add_stream_class(struct bt_ctf_trace *trace, } } - /* - * If the stream class has a clock, register this clock to this - * trace if not already done. - */ if (stream_class->clock) { - const char *clock_name = - bt_ctf_clock_get_name(stream_class->clock); - struct bt_ctf_clock *trace_clock; - - assert(clock_name); - trace_clock = bt_ctf_trace_get_clock_by_name(trace, clock_name); - bt_put(trace_clock); - if (trace_clock) { - if (trace_clock != stream_class->clock) { - /* - * Error: two different clocks in the - * trace would share the same name. - */ + struct bt_ctf_clock_class *stream_clock_class = + stream_class->clock->clock_class; + + if (trace->is_created_by_writer) { + /* + * Make sure this clock was also added to the + * trace (potentially through its CTF writer + * owner). + */ + size_t i; + + for (i = 0; i < trace->clocks->len; i++) { + if (trace->clocks->pdata[i] == + stream_clock_class) { + /* Found! */ + break; + } + } + + if (i == trace->clocks->len) { + /* Not found */ ret = -1; goto end; } } else { - clock_to_add_to_trace = bt_get(stream_class->clock); + /* + * This trace was NOT created by a CTF writer, + * thus do not allow the stream class to add to + * have a clock at all. Those are two + * independent APIs (non-writer and writer + * APIs), and isolating them simplifies things. + */ + ret = -1; + goto end; } } @@ -681,13 +684,6 @@ int bt_ctf_trace_add_stream_class(struct bt_ctf_trace *trace, trace->byte_order); bt_ctf_stream_class_set_byte_order(stream_class, trace->byte_order); - /* Add stream class's clock if it exists */ - if (clock_to_add_to_trace) { - int add_clock_ret = - bt_ctf_trace_add_clock(trace, clock_to_add_to_trace); - assert(add_clock_ret == 0); - } - /* * Freeze the trace and the stream class. */ @@ -711,7 +707,6 @@ end: g_free(ec_validation_outputs); bt_ctf_validation_output_put_types(&trace_sc_validation_output); - BT_PUT(clock_to_add_to_trace); bt_put(current_parent_trace); assert(!packet_header_type); assert(!packet_context_type); @@ -778,34 +773,34 @@ end: return stream_class; } -struct bt_ctf_clock *bt_ctf_trace_get_clock_by_name( +struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class_by_name( struct bt_ctf_trace *trace, const char *name) { size_t i; - struct bt_ctf_clock *clock = NULL; + struct bt_ctf_clock_class *clock_class = NULL; if (!trace || !name) { goto end; } for (i = 0; i < trace->clocks->len; i++) { - struct bt_ctf_clock *cur_clk = + struct bt_ctf_clock_class *cur_clk = g_ptr_array_index(trace->clocks, i); - const char *cur_clk_name = bt_ctf_clock_get_name(cur_clk); + const char *cur_clk_name = bt_ctf_clock_class_get_name(cur_clk); if (!cur_clk_name) { goto end; } if (!strcmp(cur_clk_name, name)) { - clock = cur_clk; - bt_get(clock); + clock_class = cur_clk; + bt_get(clock_class); goto end; } } end: - return clock; + return clock_class; } BT_HIDDEN @@ -970,7 +965,7 @@ char *bt_ctf_trace_get_metadata_string(struct bt_ctf_trace *trace) } append_env_metadata(trace, context); g_ptr_array_foreach(trace->clocks, - (GFunc)bt_ctf_clock_serialize, context); + (GFunc)bt_ctf_clock_class_serialize, context); for (i = 0; i < trace->stream_classes->len; i++) { err = bt_ctf_stream_class_serialize( @@ -1226,10 +1221,10 @@ void bt_ctf_trace_freeze(struct bt_ctf_trace *trace) bt_ctf_attributes_freeze(trace->environment); for (i = 0; i < trace->clocks->len; i++) { - struct bt_ctf_clock *clock = + struct bt_ctf_clock_class *clock_class = g_ptr_array_index(trace->clocks, i); - bt_ctf_clock_freeze(clock); + bt_ctf_clock_class_freeze(clock_class); } trace->frozen = 1; diff --git a/formats/ctf/writer/Makefile.am b/formats/ctf/writer/Makefile.am index 1f06c1af..1fa1fbcf 100644 --- a/formats/ctf/writer/Makefile.am +++ b/formats/ctf/writer/Makefile.am @@ -3,6 +3,7 @@ AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include noinst_LTLIBRARIES = libctf-writer.la libctf_writer_la_SOURCES = \ + clock.c \ writer.c \ functor.c diff --git a/formats/ctf/writer/clock.c b/formats/ctf/writer/clock.c new file mode 100644 index 00000000..84125f22 --- /dev/null +++ b/formats/ctf/writer/clock.c @@ -0,0 +1,307 @@ +/* + * clock.c + * + * Babeltrace CTF IR - Clock + * + * Copyright 2013, 2014 Jérémie Galarneau + * Copyright 2017 Philippe Proulx + * + * Author: Jérémie Galarneau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static +void bt_ctf_clock_destroy(struct bt_object *obj); + +struct bt_ctf_clock *bt_ctf_clock_create(const char *name) +{ + struct bt_ctf_clock *clock = NULL; + + if (!name) { + goto error; + } + + clock = g_new0(struct bt_ctf_clock, 1); + + if (!clock) { + goto error; + } + + bt_object_init(clock, bt_ctf_clock_destroy); + clock->value = 0; + clock->clock_class = bt_ctf_clock_class_create(name); + if (!clock->clock_class) { + goto error; + } + return clock; + +error: + BT_PUT(clock); + return clock; +} + +const char *bt_ctf_clock_get_name(struct bt_ctf_clock *clock) +{ + const char *name = NULL; + + if (clock) { + name = bt_ctf_clock_class_get_name(clock->clock_class); + } + + return name; +} + +const char *bt_ctf_clock_get_description(struct bt_ctf_clock *clock) +{ + const char *description = NULL; + + if (clock) { + description = bt_ctf_clock_class_get_description( + clock->clock_class); + } + + return description; +} + +int bt_ctf_clock_set_description(struct bt_ctf_clock *clock, const char *desc) +{ + int ret = -1; + + if (clock) { + ret = bt_ctf_clock_class_set_description(clock->clock_class, + desc); + } + + return ret; +} + +uint64_t bt_ctf_clock_get_frequency(struct bt_ctf_clock *clock) +{ + uint64_t freq = -1ULL; + + if (clock) { + freq = bt_ctf_clock_class_get_frequency(clock->clock_class); + } + + return freq; +} + +int bt_ctf_clock_set_frequency(struct bt_ctf_clock *clock, uint64_t freq) +{ + int ret = -1; + + if (clock) { + ret = bt_ctf_clock_class_set_frequency(clock->clock_class, + freq); + } + + return ret; +} + +uint64_t bt_ctf_clock_get_precision(struct bt_ctf_clock *clock) +{ + uint64_t precision = -1ULL; + + if (clock) { + precision = bt_ctf_clock_class_get_precision( + clock->clock_class); + } + + return precision; +} + +int bt_ctf_clock_set_precision(struct bt_ctf_clock *clock, uint64_t precision) +{ + int ret = -1; + + if (clock) { + ret = bt_ctf_clock_class_set_precision(clock->clock_class, + precision); + } + + return ret; +} + +int bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock, int64_t *offset_s) +{ + int ret = -1; + + if (clock) { + ret = bt_ctf_clock_class_get_offset_s(clock->clock_class, + offset_s); + } + + return ret; +} + +int bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock, int64_t offset_s) +{ + int ret = -1; + + if (clock) { + ret = bt_ctf_clock_class_set_offset_s(clock->clock_class, + offset_s); + } + + return ret; +} + +int bt_ctf_clock_get_offset(struct bt_ctf_clock *clock, int64_t *offset) +{ + int ret = -1; + + if (clock) { + ret = bt_ctf_clock_class_get_offset_cycles(clock->clock_class, + offset); + } + + return ret; +} + +int bt_ctf_clock_set_offset(struct bt_ctf_clock *clock, int64_t offset) +{ + int ret = -1; + + if (clock) { + ret = bt_ctf_clock_class_set_offset_cycles(clock->clock_class, + offset); + } + + return ret; +} + +int bt_ctf_clock_get_is_absolute(struct bt_ctf_clock *clock) +{ + int is_absolute = -1; + + if (clock) { + is_absolute = bt_ctf_clock_class_get_is_absolute( + clock->clock_class); + } + + return is_absolute; +} + +int bt_ctf_clock_set_is_absolute(struct bt_ctf_clock *clock, int is_absolute) +{ + int ret = -1; + + if (clock) { + ret = bt_ctf_clock_class_set_is_absolute(clock->clock_class, + is_absolute); + } + + return ret; +} + +const unsigned char *bt_ctf_clock_get_uuid(struct bt_ctf_clock *clock) +{ + const unsigned char *uuid = NULL; + + if (clock) { + uuid = bt_ctf_clock_class_get_uuid(clock->clock_class); + } + + return uuid; +} + +int bt_ctf_clock_set_uuid(struct bt_ctf_clock *clock, const unsigned char *uuid) +{ + int ret = -1; + + if (clock) { + ret = bt_ctf_clock_class_set_uuid(clock->clock_class, uuid); + } + + return ret; +} + +int bt_ctf_clock_set_time(struct bt_ctf_clock *clock, int64_t time) +{ + int ret = 0; + int64_t value; + + if (!clock) { + ret = -1; + goto end; + } + + /* Common case where cycles are actually nanoseconds */ + if (clock->clock_class->frequency == 1000000000) { + value = time; + } else { + value = (uint64_t) (((double) time * + (double) clock->clock_class->frequency) / 1e9); + } + + if (clock->value > value) { + /* Timestamps must be strictly monotonic. */ + ret = -1; + goto end; + } + + clock->value = value; +end: + return ret; +} + +void bt_ctf_clock_get(struct bt_ctf_clock *clock) +{ + bt_get(clock); +} + +void bt_ctf_clock_put(struct bt_ctf_clock *clock) +{ + bt_put(clock); +} + +BT_HIDDEN +int bt_ctf_clock_get_value(struct bt_ctf_clock *clock, uint64_t *value) +{ + int ret = 0; + + if (!clock || !value) { + ret = -1; + goto end; + } + + *value = clock->value; +end: + return ret; +} + +static +void bt_ctf_clock_destroy(struct bt_object *obj) +{ + struct bt_ctf_clock *clock; + + clock = container_of(obj, struct bt_ctf_clock, base); + bt_put(clock->clock_class); + g_free(clock); +} diff --git a/formats/ctf/writer/writer.c b/formats/ctf/writer/writer.c index 012b3ef0..854de432 100644 --- a/formats/ctf/writer/writer.c +++ b/formats/ctf/writer/writer.c @@ -26,7 +26,7 @@ * SOFTWARE. */ -#include +#include #include #include #include @@ -234,7 +234,7 @@ int bt_ctf_writer_add_clock(struct bt_ctf_writer *writer, goto end; } - ret = bt_ctf_trace_add_clock(writer->trace, clock); + ret = bt_ctf_trace_add_clock_class(writer->trace, clock->clock_class); end: return ret; } diff --git a/include/Makefile.am b/include/Makefile.am index 121d6a8b..a463dba4 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -24,7 +24,7 @@ babeltracectfwriterinclude_HEADERS = \ babeltrace/ctf-writer/stream-class.h babeltracectfirinclude_HEADERS = \ - babeltrace/ctf-ir/clock.h \ + babeltrace/ctf-ir/clock-class.h \ babeltrace/ctf-ir/fields.h \ babeltrace/ctf-ir/field-types.h \ babeltrace/ctf-ir/event.h \ @@ -91,7 +91,7 @@ noinst_HEADERS = \ babeltrace/ctf-ir/event-internal.h \ babeltrace/ctf-ir/event-class-internal.h \ babeltrace/ctf-ir/field-path-internal.h \ - babeltrace/ctf-ir/clock-internal.h \ + babeltrace/ctf-ir/clock-class-internal.h \ babeltrace/ctf-ir/resolve-internal.h \ babeltrace/ctf-ir/stream-class-internal.h \ babeltrace/ctf-ir/stream-internal.h \ @@ -99,6 +99,7 @@ noinst_HEADERS = \ babeltrace/ctf-ir/trace-internal.h \ babeltrace/ctf-ir/validation-internal.h \ babeltrace/ctf-ir/visitor-internal.h \ + babeltrace/ctf-writer/clock-internal.h \ babeltrace/ctf-writer/functor-internal.h \ babeltrace/trace-handle-internal.h \ babeltrace/compat/uuid.h \ diff --git a/include/babeltrace/ctf-ir/clock-internal.h b/include/babeltrace/ctf-ir/clock-class-internal.h similarity index 70% rename from include/babeltrace/ctf-ir/clock-internal.h rename to include/babeltrace/ctf-ir/clock-class-internal.h index 38b0fcf1..c43f7712 100644 --- a/include/babeltrace/ctf-ir/clock-internal.h +++ b/include/babeltrace/ctf-ir/clock-class-internal.h @@ -1,5 +1,5 @@ -#ifndef BABELTRACE_CTF_IR_CLOCK_INTERNAL_H -#define BABELTRACE_CTF_IR_CLOCK_INTERNAL_H +#ifndef BABELTRACE_CTF_IR_CLOCK_CLASS_INTERNAL_H +#define BABELTRACE_CTF_IR_CLOCK_CLASS_INTERNAL_H /* * BabelTrace - CTF IR: Clock internal @@ -27,14 +27,14 @@ * SOFTWARE. */ -#include +#include #include #include #include #include #include -struct bt_ctf_clock { +struct bt_ctf_clock_class { struct bt_object base; GString *name; GString *description; @@ -42,20 +42,10 @@ struct bt_ctf_clock { uint64_t precision; int64_t offset_s; /* Offset in seconds */ int64_t offset; /* Offset in ticks */ - uint64_t value; /* Current clock value */ uuid_t uuid; int uuid_set; int absolute; - /* - * This field is set once a clock is added to a trace. If the - * trace was created by a CTF writer, then the clock's value - * can be set and returned. Otherwise both functions fail - * because, in non-writer mode, clocks do not have global - * values: values are per-stream. - */ - int has_value; - /* * A clock's properties can't be modified once it is added to a stream * class. @@ -65,21 +55,18 @@ struct bt_ctf_clock { struct bt_ctf_clock_value { struct bt_object base; - struct bt_ctf_clock *clock_class; + struct bt_ctf_clock_class *clock_class; uint64_t value; }; BT_HIDDEN -void bt_ctf_clock_freeze(struct bt_ctf_clock *clock); +void bt_ctf_clock_class_freeze(struct bt_ctf_clock_class *clock_class); BT_HIDDEN -void bt_ctf_clock_serialize(struct bt_ctf_clock *clock, +void bt_ctf_clock_class_serialize(struct bt_ctf_clock_class *clock_class, struct metadata_context *context); BT_HIDDEN -bool bt_ctf_clock_is_valid(struct bt_ctf_clock *clock); - -BT_HIDDEN -int bt_ctf_clock_get_value(struct bt_ctf_clock *clock, uint64_t *value); +bool bt_ctf_clock_class_is_valid(struct bt_ctf_clock_class *clock_class); -#endif /* BABELTRACE_CTF_IR_CLOCK_INTERNAL_H */ +#endif /* BABELTRACE_CTF_IR_CLOCK_CLASS_INTERNAL_H */ diff --git a/include/babeltrace/ctf-ir/clock-class.h b/include/babeltrace/ctf-ir/clock-class.h new file mode 100644 index 00000000..c2b90173 --- /dev/null +++ b/include/babeltrace/ctf-ir/clock-class.h @@ -0,0 +1,88 @@ +#ifndef BABELTRACE_CTF_IR_CLOCK_CLASS_H +#define BABELTRACE_CTF_IR_CLOCK_CLASS_H + +/* + * BabelTrace - CTF IR: Clock class + * + * Copyright 2013, 2014 Jérémie Galarneau + * Copyright 2017 Philippe Proulx + * + * Author: Jérémie Galarneau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * The Common Trace Format (CTF) Specification is available at + * http://www.efficios.com/ctf + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct bt_ctf_clock_class; +struct bt_ctf_clock_value; + +extern struct bt_ctf_clock_class *bt_ctf_clock_class_create(const char *name); +extern const char *bt_ctf_clock_class_get_name( + struct bt_ctf_clock_class *clock_class); +extern int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class *clock_class, + const char *name); +extern const char *bt_ctf_clock_class_get_description( + struct bt_ctf_clock_class *clock_class); +extern int bt_ctf_clock_class_set_description( + struct bt_ctf_clock_class *clock_class, + const char *desc); +extern uint64_t bt_ctf_clock_class_get_frequency( + struct bt_ctf_clock_class *clock_class); +extern int bt_ctf_clock_class_set_frequency( + struct bt_ctf_clock_class *clock_class, uint64_t freq); +extern uint64_t bt_ctf_clock_class_get_precision( + struct bt_ctf_clock_class *clock_class); +extern int bt_ctf_clock_class_set_precision( + struct bt_ctf_clock_class *clock_class, uint64_t precision); +extern int bt_ctf_clock_class_get_offset_s( + struct bt_ctf_clock_class *clock_class, int64_t *seconds); +extern int bt_ctf_clock_class_set_offset_s( + struct bt_ctf_clock_class *clock_class, int64_t seconds); +extern int bt_ctf_clock_class_get_offset_cycles( + struct bt_ctf_clock_class *clock_class, int64_t *cycles); +extern int bt_ctf_clock_class_set_offset_cycles( + struct bt_ctf_clock_class *clock_class, int64_t cycles); +extern int bt_ctf_clock_class_get_is_absolute( + struct bt_ctf_clock_class *clock_class); +extern int bt_ctf_clock_class_set_is_absolute( + struct bt_ctf_clock_class *clock_class, int is_absolute); +extern const unsigned char *bt_ctf_clock_class_get_uuid( + struct bt_ctf_clock_class *clock_class); +extern int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class *clock_class, + const unsigned char *uuid); +extern struct bt_ctf_clock_value *bt_ctf_clock_value_create( + struct bt_ctf_clock_class *clock_class, uint64_t value); +extern int bt_ctf_clock_value_get_value( + struct bt_ctf_clock_value *clock_value, uint64_t *raw_value); +extern int bt_ctf_clock_value_get_value_ns_from_epoch( + struct bt_ctf_clock_value *clock_value, int64_t *value_ns); + +#ifdef __cplusplus +} +#endif + +#endif /* BABELTRACE_CTF_IR_CLOCK_CLASS_H */ diff --git a/include/babeltrace/ctf-ir/clock.h b/include/babeltrace/ctf-ir/clock.h deleted file mode 100644 index d9e3eb06..00000000 --- a/include/babeltrace/ctf-ir/clock.h +++ /dev/null @@ -1,266 +0,0 @@ -#ifndef BABELTRACE_CTF_IR_CLOCK_H -#define BABELTRACE_CTF_IR_CLOCK_H - -/* - * BabelTrace - CTF IR: Clock - * - * Copyright 2013, 2014 Jérémie Galarneau - * - * Author: Jérémie Galarneau - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * The Common Trace Format (CTF) Specification is available at - * http://www.efficios.com/ctf - */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct bt_ctf_clock; -struct bt_ctf_clock_value; - -/* - * bt_ctf_clock_create: create a clock. - * - * Allocate a new clock setting its reference count to 1. - * - * @param name Name of the clock (will be copied); can be set to NULL - * for nameless clocks. - * - * Returns an allocated clock on success, NULL on error. - */ -extern struct bt_ctf_clock *bt_ctf_clock_create(const char *name); - -/* - * bt_ctf_clock_get_name: get a clock's name. - * - * Get the clock's name. - * - * @param clock Clock instance. - * - * Returns the clock's name, NULL on error. - */ -extern const char *bt_ctf_clock_get_name(struct bt_ctf_clock *clock); - -/* - * bt_ctf_clock_set_name: set a clock's name. - * - * Set a clock's name. - * - * @param name Name of the clock (will be copied). - * - * Returns 0 on success, a negative value on error. - */ -extern int bt_ctf_clock_set_name(struct bt_ctf_clock *clock, const char *name); - -/* - * bt_ctf_clock_get_description: get a clock's description. - * - * Get the clock's description. - * - * @param clock Clock instance. - * - * Returns the clock's description, NULL if unset. - */ -extern const char *bt_ctf_clock_get_description(struct bt_ctf_clock *clock); - -/* - * bt_ctf_clock_set_description: set a clock's description. - * - * Set the clock's description. The description appears in the clock's TSDL - * meta-data. - * - * @param clock Clock instance. - * @param desc Description of the clock. - * - * Returns 0 on success, a negative value on error. - */ -extern int bt_ctf_clock_set_description(struct bt_ctf_clock *clock, - const char *desc); - -/* - * bt_ctf_clock_get_frequency: get a clock's frequency. - * - * Get the clock's frequency (Hz). - * - * @param clock Clock instance. - * - * Returns the clock's frequency, -1ULL on error. - */ -extern uint64_t bt_ctf_clock_get_frequency(struct bt_ctf_clock *clock); - -/* - * bt_ctf_clock_set_frequency: set a clock's frequency. - * - * Set the clock's frequency (Hz). - * - * @param clock Clock instance. - * @param freq Clock's frequency in Hz, defaults to 1 000 000 000 Hz (1ns). - * - * Returns 0 on success, a negative value on error. - */ -extern int bt_ctf_clock_set_frequency(struct bt_ctf_clock *clock, - uint64_t freq); - -/* - * bt_ctf_clock_get_precision: get a clock's precision. - * - * Get the clock's precision (in clock ticks). - * - * @param clock Clock instance. - * - * Returns the clock's precision, -1ULL on error. - */ -extern uint64_t bt_ctf_clock_get_precision(struct bt_ctf_clock *clock); - -/* - * bt_ctf_clock_set_precision: set a clock's precision. - * - * Set the clock's precision. - * - * @param clock Clock instance. - * @param precision Clock's precision in clock ticks, defaults to 1. - * - * Returns 0 on success, a negative value on error. - */ -extern int bt_ctf_clock_set_precision(struct bt_ctf_clock *clock, - uint64_t precision); - -/* - * bt_ctf_clock_get_offset_s: get a clock's offset in seconds. - * - * Get the clock's offset in seconds from POSIX.1 Epoch, 1970-01-01. - * - * @param clock Clock instance. - * @param offset_s Pointer to clock offset in seconds (output). - * - * Returns 0 on success, a negative value on error. - */ -extern int bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock, - int64_t *offset_s); - -/* - * bt_ctf_clock_set_offset_s: set a clock's offset in seconds. - * - * Set the clock's offset in seconds from POSIX.1 Epoch, 1970-01-01, - * defaults to 0. - * - * @param clock Clock instance. - * @param offset_s Clock's offset in seconds, defaults to 0. - * - * Returns 0 on success, a negative value on error. - */ -extern int bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock, - int64_t offset_s); - -/* - * bt_ctf_clock_get_offset: get a clock's offset in ticks. - * - * Get the clock's offset in ticks from Epoch + offset_t. - * - * @param clock Clock instance. - * @param offset Clock offset in ticks from Epoch + offset_s (output). - * - * Returns 0 on success, a negative value on error. - */ -extern int bt_ctf_clock_get_offset(struct bt_ctf_clock *clock, - int64_t *offset); - -/* - * bt_ctf_clock_set_offset: set a clock's offset in ticks. - * - * Set the clock's offset in ticks from Epoch + offset_s. - * - * @param clock Clock instance. - * @param offset Clock's offset in ticks from Epoch + offset_s, defaults to 0. - * - * Returns 0 on success, a negative value on error. - */ -extern int bt_ctf_clock_set_offset(struct bt_ctf_clock *clock, - int64_t offset); - -/* - * bt_ctf_clock_get_is_absolute: get a clock's absolute attribute. - * - * Get the clock's absolute attribute. A clock is absolute if the clock is a - * global reference across the trace's other clocks. - * - * @param clock Clock instance. - * - * Returns the clock's absolute attribute, a negative value on error. - */ -extern int bt_ctf_clock_get_is_absolute(struct bt_ctf_clock *clock); - -/* - * bt_ctf_clock_set_is_absolute: set a clock's absolute attribute. - * - * Set the clock's absolute attribute. A clock is absolute if the clock is a - * global reference across the trace's other clocks. - * - * @param clock Clock instance. - * @param is_absolute Clock's absolute attribute, defaults to FALSE. - * - * Returns 0 on success, a negative value on error. - */ -extern int bt_ctf_clock_set_is_absolute(struct bt_ctf_clock *clock, - int is_absolute); - -/* - * bt_ctf_clock_get_uuid: get a clock's UUID. - * - * Get the clock's UUID. - * - * @param clock Clock instance. - * - * Returns a pointer to the clock's UUID (16 byte array) on success, - * NULL on error. - */ -extern const unsigned char *bt_ctf_clock_get_uuid(struct bt_ctf_clock *clock); - -/* - * bt_ctf_clock_set_uuid: set a clock's UUID. - * - * Set a clock's UUID. - * - * @param clock Clock instance. - * @param uuid A 16-byte array containing a UUID. - * - * Returns 0 on success, a negative value on error. - */ -extern int bt_ctf_clock_set_uuid(struct bt_ctf_clock *clock, - const unsigned char *uuid); - -extern struct bt_ctf_clock_value *bt_ctf_clock_value_create( - struct bt_ctf_clock *clock, uint64_t value); - -extern int bt_ctf_clock_value_get_value( - struct bt_ctf_clock_value *clock_value, uint64_t *raw_value); - -extern int bt_ctf_clock_value_get_value_ns_from_epoch( - struct bt_ctf_clock_value *clock_value, int64_t *value_ns); - -#ifdef __cplusplus -} -#endif - -#endif /* BABELTRACE_CTF_IR_CLOCK_H */ diff --git a/include/babeltrace/ctf-ir/event-internal.h b/include/babeltrace/ctf-ir/event-internal.h index 2e5175cb..90be6e24 100644 --- a/include/babeltrace/ctf-ir/event-internal.h +++ b/include/babeltrace/ctf-ir/event-internal.h @@ -58,18 +58,6 @@ BT_HIDDEN int bt_ctf_event_serialize(struct bt_ctf_event *event, struct ctf_stream_pos *pos); -/* - * Attempt to populate the "id" and "timestamp" fields of the event header if - * they are present, unset and their types are integers. - * - * Not finding these fields or encountering unexpected types is not an error - * since the user may have defined a different event header layout. In this - * case, it is expected that the fields be manually populated before appending - * an event to a stream. - */ -BT_HIDDEN -int bt_ctf_event_populate_event_header(struct bt_ctf_event *event); - BT_HIDDEN void bt_ctf_event_freeze(struct bt_ctf_event *event); diff --git a/include/babeltrace/ctf-ir/event.h b/include/babeltrace/ctf-ir/event.h index c63311f4..7c46d8bb 100644 --- a/include/babeltrace/ctf-ir/event.h +++ b/include/babeltrace/ctf-ir/event.h @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -535,7 +536,7 @@ extern int bt_ctf_event_set_payload(struct bt_ctf_event *event, @sa bt_ctf_event_set_clock_value(): Sets the clock value of a given event. */ extern struct bt_ctf_clock_value *bt_ctf_event_get_clock_value( - struct bt_ctf_event *event, struct bt_ctf_clock *clock_class); + struct bt_ctf_event *event, struct bt_ctf_clock_class *clock_class); /** @brief Sets the value, as of the CTF IR event \p event, of the @@ -561,7 +562,7 @@ extern struct bt_ctf_clock_value *bt_ctf_event_get_clock_value( a given event. */ extern int bt_ctf_event_set_clock_value( - struct bt_ctf_event *event, struct bt_ctf_clock *clock_class, + struct bt_ctf_event *event, struct bt_ctf_clock_class *clock_class, struct bt_ctf_clock_value *clock_value); /** @} */ diff --git a/include/babeltrace/ctf-ir/field-types-internal.h b/include/babeltrace/ctf-ir/field-types-internal.h index c718a2be..3df8e745 100644 --- a/include/babeltrace/ctf-ir/field-types-internal.h +++ b/include/babeltrace/ctf-ir/field-types-internal.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -63,7 +64,7 @@ struct bt_ctf_field_type { struct bt_ctf_field_type_integer { struct bt_ctf_field_type parent; struct declaration_integer declaration; - struct bt_ctf_clock *mapped_clock; + struct bt_ctf_clock_class *mapped_clock; /* * This is what the user sets and is never modified by internal diff --git a/include/babeltrace/ctf-ir/field-types.h b/include/babeltrace/ctf-ir/field-types.h index 9bca9bc6..f7b47a49 100644 --- a/include/babeltrace/ctf-ir/field-types.h +++ b/include/babeltrace/ctf-ir/field-types.h @@ -721,8 +721,8 @@ An integer field type has the following properties: Mapped \link ctfirclockclass CTF IR clock class\endlink None - bt_ctf_field_type_integer_get_mapped_clock() - bt_ctf_field_type_integer_set_mapped_clock() + bt_ctf_field_type_integer_get_mapped_clock_class() + bt_ctf_field_type_integer_set_mapped_clock_class() @@ -951,15 +951,15 @@ This mapped clock class is only indicative. @postrefcountsame{int_field_type} @postsuccessrefcountretinc -@sa bt_ctf_field_type_integer_set_mapped_clock(): Sets the mapped +@sa bt_ctf_field_type_integer_set_mapped_clock_class(): Sets the mapped clock class of a given integer field type. */ -extern struct bt_ctf_clock *bt_ctf_field_type_integer_get_mapped_clock( +extern struct bt_ctf_clock_class *bt_ctf_field_type_integer_get_mapped_clock_class( struct bt_ctf_field_type *int_field_type); /** @brief Sets the \link ctfirclockclass CTF IR clock class\endlink mapped - to the @intft \p int_field_type to \p mapped_clock. + to the @intft \p int_field_type to \p clock_class. The mapped clock class, if any, indicates the class of the clock which an integer field described by \p int_field_type should sample or update. @@ -977,12 +977,12 @@ This mapped clock class is only indicative. @postrefcountsame{int_field_type} @postsuccessrefcountinc{clock_class} -@sa bt_ctf_field_type_integer_get_mapped_clock(): Returns the mapped +@sa bt_ctf_field_type_integer_get_mapped_clock_class(): Returns the mapped clock class of a given integer field type. */ -extern int bt_ctf_field_type_integer_set_mapped_clock( +extern int bt_ctf_field_type_integer_set_mapped_clock_class( struct bt_ctf_field_type *int_field_type, - struct bt_ctf_clock *clock_class); + struct bt_ctf_clock_class *clock_class); /** @} */ diff --git a/include/babeltrace/ctf-ir/stream-class.h b/include/babeltrace/ctf-ir/stream-class.h index 3d570eaa..80febe3d 100644 --- a/include/babeltrace/ctf-ir/stream-class.h +++ b/include/babeltrace/ctf-ir/stream-class.h @@ -613,10 +613,6 @@ extern int bt_ctf_stream_class_visit(struct bt_ctf_stream_class *stream_class, /** @} */ -// TODO: document for CTF writer -extern struct bt_ctf_clock *bt_ctf_stream_class_get_clock( - struct bt_ctf_stream_class *stream_class); - #ifdef __cplusplus } #endif diff --git a/include/babeltrace/ctf-ir/trace-internal.h b/include/babeltrace/ctf-ir/trace-internal.h index 03a7ebf1..9c0ba851 100644 --- a/include/babeltrace/ctf-ir/trace-internal.h +++ b/include/babeltrace/ctf-ir/trace-internal.h @@ -54,7 +54,7 @@ struct bt_ctf_trace { uuid_t uuid; int byte_order; /* A value defined in Babeltrace's "endian.h" */ struct bt_value *environment; - GPtrArray *clocks; /* Array of pointers to bt_ctf_clock */ + GPtrArray *clocks; /* Array of pointers to bt_ctf_clock_class */ GPtrArray *stream_classes; /* Array of ptrs to bt_ctf_stream_class */ GPtrArray *streams; /* Array of ptrs to bt_ctf_stream */ struct bt_ctf_field_type *packet_header_type; diff --git a/include/babeltrace/ctf-ir/trace.h b/include/babeltrace/ctf-ir/trace.h index 099692f3..a95e206e 100644 --- a/include/babeltrace/ctf-ir/trace.h +++ b/include/babeltrace/ctf-ir/trace.h @@ -116,7 +116,7 @@ except for: - Adding a stream class to it with bt_ctf_trace_add_stream_class(). -- Adding a clock class to it with bt_ctf_trace_add_clock(). +- Adding a clock class to it with bt_ctf_trace_add_clock_class(). - \link refs Reference counting\endlink. You can add a custom listener with bt_ctf_trace_add_listener() to get @@ -144,7 +144,7 @@ or if a clock class is added. struct bt_ctf_trace; struct bt_ctf_stream; struct bt_ctf_stream_class; -struct bt_ctf_clock; +struct bt_ctf_clock_class; /** @name Creation function @@ -544,7 +544,7 @@ extern int bt_ctf_trace_set_packet_header_type(struct bt_ctf_trace *trace_class, @prenotnull{trace_class} @postrefcountsame{trace_class} */ -extern int bt_ctf_trace_get_clock_count(struct bt_ctf_trace *trace_class); +extern int bt_ctf_trace_get_clock_class_count(struct bt_ctf_trace *trace_class); /** @brief Returns the clock class at index \p index in the CTF IR trace @@ -558,14 +558,14 @@ extern int bt_ctf_trace_get_clock_count(struct bt_ctf_trace *trace_class); @prenotnull{trace_class} @pre \p index is lesser than the number of clock classes contained in the trace class \p trace_class (see - bt_ctf_trace_get_clock_count()). + bt_ctf_trace_get_clock_class_count()). @postrefcountsame{trace_class} @postsuccessrefcountretinc -@sa bt_ctf_trace_get_clock_by_name(): Finds a clock class by name. -@sa bt_ctf_trace_add_clock(): Adds a clock class to a trace class. +@sa bt_ctf_trace_get_clock_class_by_name(): Finds a clock class by name. +@sa bt_ctf_trace_add_clock_class(): Adds a clock class to a trace class. */ -extern struct bt_ctf_clock *bt_ctf_trace_get_clock( +extern struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class( struct bt_ctf_trace *trace_class, int index); /** @@ -582,11 +582,11 @@ extern struct bt_ctf_clock *bt_ctf_trace_get_clock( @postrefcountsame{trace_class} @postsuccessrefcountretinc -@sa bt_ctf_trace_get_clock(): Returns the clock class contained in a - given trace class at a given index. -@sa bt_ctf_trace_add_clock(): Adds a clock class to a trace class. +@sa bt_ctf_trace_get_clock_class(): Returns the clock class contained + in a given trace class at a given index. +@sa bt_ctf_trace_add_clock_class(): Adds a clock class to a trace class. */ -extern struct bt_ctf_clock *bt_ctf_trace_get_clock_by_name( +extern struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class_by_name( struct bt_ctf_trace *trace_class, const char *name); /** @@ -608,12 +608,12 @@ You can call this function even if \p trace_class is frozen. @post On success, if \p trace_class is frozen, \p clock_class is frozen. -@sa bt_ctf_trace_get_clock(): Returns the clock class contained in a - given trace class at a given index. -@sa bt_ctf_trace_get_clock_by_name(): Finds a clock class by name. +@sa bt_ctf_trace_get_clock_class(): Returns the clock class contained + in a given trace class at a given index. +@sa bt_ctf_trace_get_clock_class_by_name(): Finds a clock class by name. */ -extern int bt_ctf_trace_add_clock(struct bt_ctf_trace *trace_class, - struct bt_ctf_clock *clock_class); +extern int bt_ctf_trace_add_clock_class(struct bt_ctf_trace *trace_class, + struct bt_ctf_clock_class *clock_class); /** @} */ @@ -672,8 +672,8 @@ extern struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class( @postrefcountsame{trace_class} @postsuccessrefcountretinc -@sa bt_ctf_trace_get_clock(): Returns the stream class contained in a - given trace class at a given index. +@sa bt_ctf_trace_get_stream_class(): Returns the stream class contained + in a given trace class at a given index. @sa bt_ctf_trace_add_stream_class(): Adds a stream class to a trace class. */ extern struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class_by_id( @@ -706,8 +706,8 @@ resolving fails, then this function fails. @postsuccessrefcountinc{stream_class} @postsuccessfrozen{stream_class} -@sa bt_ctf_trace_get_clock(): Returns the stream class contained in a - given trace class at a given index. +@sa bt_ctf_trace_get_stream_class(): Returns the stream class contained + in a given trace class at a given index. @sa bt_ctf_trace_get_stream_class_by_id(): Finds a stream class by ID. */ extern int bt_ctf_trace_add_stream_class(struct bt_ctf_trace *trace_class, diff --git a/include/babeltrace/ctf-writer/clock-internal.h b/include/babeltrace/ctf-writer/clock-internal.h new file mode 100644 index 00000000..967be1aa --- /dev/null +++ b/include/babeltrace/ctf-writer/clock-internal.h @@ -0,0 +1,45 @@ +#ifndef BABELTRACE_CTF_WRITER_CLOCK_INTERNAL_H +#define BABELTRACE_CTF_WRITER_CLOCK_INTERNAL_H + +/* + * BabelTrace - CTF writer: Clock internal + * + * Copyright 2017 Philippe Proulx + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include + +struct bt_ctf_clock { + struct bt_object base; + struct bt_ctf_clock_class *clock_class; + uint64_t value; /* Current clock value */ +}; + +BT_HIDDEN +int bt_ctf_clock_get_value(struct bt_ctf_clock *clock, uint64_t *value); + +#endif /* BABELTRACE_CTF_WRITER_CLOCK_INTERNAL_H */ diff --git a/include/babeltrace/ctf-writer/clock.h b/include/babeltrace/ctf-writer/clock.h index 7ee14c65..7276f451 100644 --- a/include/babeltrace/ctf-writer/clock.h +++ b/include/babeltrace/ctf-writer/clock.h @@ -30,12 +30,214 @@ * http://www.efficios.com/ctf */ -#include +#include #ifdef __cplusplus extern "C" { #endif +struct bt_ctf_clock; + +/* + * bt_ctf_clock_create: create a clock. + * + * Allocate a new clock setting its reference count to 1. + * + * @param name Name of the clock (will be copied); can be set to NULL + * for nameless clocks. + * + * Returns an allocated clock on success, NULL on error. + */ +extern struct bt_ctf_clock *bt_ctf_clock_create(const char *name); + +/* + * bt_ctf_clock_get_name: get a clock's name. + * + * Get the clock's name. + * + * @param clock Clock instance. + * + * Returns the clock's name, NULL on error. + */ +extern const char *bt_ctf_clock_get_name(struct bt_ctf_clock *clock); + +/* + * bt_ctf_clock_get_description: get a clock's description. + * + * Get the clock's description. + * + * @param clock Clock instance. + * + * Returns the clock's description, NULL if unset. + */ +extern const char *bt_ctf_clock_get_description(struct bt_ctf_clock *clock); + +/* + * bt_ctf_clock_set_description: set a clock's description. + * + * Set the clock's description. The description appears in the clock's TSDL + * meta-data. + * + * @param clock Clock instance. + * @param desc Description of the clock. + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_clock_set_description(struct bt_ctf_clock *clock, + const char *desc); + +/* + * bt_ctf_clock_get_frequency: get a clock's frequency. + * + * Get the clock's frequency (Hz). + * + * @param clock Clock instance. + * + * Returns the clock's frequency, -1ULL on error. + */ +extern uint64_t bt_ctf_clock_get_frequency(struct bt_ctf_clock *clock); + +/* + * bt_ctf_clock_set_frequency: set a clock's frequency. + * + * Set the clock's frequency (Hz). + * + * @param clock Clock instance. + * @param freq Clock's frequency in Hz, defaults to 1 000 000 000 Hz (1ns). + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_clock_set_frequency(struct bt_ctf_clock *clock, + uint64_t freq); + +/* + * bt_ctf_clock_get_precision: get a clock's precision. + * + * Get the clock's precision (in clock ticks). + * + * @param clock Clock instance. + * + * Returns the clock's precision, -1ULL on error. + */ +extern uint64_t bt_ctf_clock_get_precision(struct bt_ctf_clock *clock); + +/* + * bt_ctf_clock_set_precision: set a clock's precision. + * + * Set the clock's precision. + * + * @param clock Clock instance. + * @param precision Clock's precision in clock ticks, defaults to 1. + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_clock_set_precision(struct bt_ctf_clock *clock, + uint64_t precision); + +/* + * bt_ctf_clock_get_offset_s: get a clock's offset in seconds. + * + * Get the clock's offset in seconds from POSIX.1 Epoch, 1970-01-01. + * + * @param clock Clock instance. + * @param offset_s Pointer to clock offset in seconds (output). + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock, + int64_t *offset_s); + +/* + * bt_ctf_clock_set_offset_s: set a clock's offset in seconds. + * + * Set the clock's offset in seconds from POSIX.1 Epoch, 1970-01-01, + * defaults to 0. + * + * @param clock Clock instance. + * @param offset_s Clock's offset in seconds, defaults to 0. + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock, + int64_t offset_s); + +/* + * bt_ctf_clock_get_offset: get a clock's offset in ticks. + * + * Get the clock's offset in ticks from Epoch + offset_t. + * + * @param clock Clock instance. + * @param offset Clock offset in ticks from Epoch + offset_s (output). + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_clock_get_offset(struct bt_ctf_clock *clock, + int64_t *offset); + +/* + * bt_ctf_clock_set_offset: set a clock's offset in ticks. + * + * Set the clock's offset in ticks from Epoch + offset_s. + * + * @param clock Clock instance. + * @param offset Clock's offset in ticks from Epoch + offset_s, defaults to 0. + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_clock_set_offset(struct bt_ctf_clock *clock, + int64_t offset); + +/* + * bt_ctf_clock_get_is_absolute: get a clock's absolute attribute. + * + * Get the clock's absolute attribute. A clock is absolute if the clock is a + * global reference across the trace's other clocks. + * + * @param clock Clock instance. + * + * Returns the clock's absolute attribute, a negative value on error. + */ +extern int bt_ctf_clock_get_is_absolute(struct bt_ctf_clock *clock); + +/* + * bt_ctf_clock_set_is_absolute: set a clock's absolute attribute. + * + * Set the clock's absolute attribute. A clock is absolute if the clock is a + * global reference across the trace's other clocks. + * + * @param clock Clock instance. + * @param is_absolute Clock's absolute attribute, defaults to FALSE. + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_clock_set_is_absolute(struct bt_ctf_clock *clock, + int is_absolute); + +/* + * bt_ctf_clock_get_uuid: get a clock's UUID. + * + * Get the clock's UUID. + * + * @param clock Clock instance. + * + * Returns a pointer to the clock's UUID (16 byte array) on success, + * NULL on error. + */ +extern const unsigned char *bt_ctf_clock_get_uuid(struct bt_ctf_clock *clock); + +/* + * bt_ctf_clock_set_uuid: set a clock's UUID. + * + * Set a clock's UUID. + * + * @param clock Clock instance. + * @param uuid A 16-byte array containing a UUID. + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_clock_set_uuid(struct bt_ctf_clock *clock, + const unsigned char *uuid); + /* * bt_ctf_clock_set_time: set a clock's current time value. * diff --git a/include/babeltrace/ctf-writer/stream-class.h b/include/babeltrace/ctf-writer/stream-class.h index 139165a3..09973906 100644 --- a/include/babeltrace/ctf-writer/stream-class.h +++ b/include/babeltrace/ctf-writer/stream-class.h @@ -51,6 +51,9 @@ extern int bt_ctf_stream_class_set_clock( struct bt_ctf_stream_class *stream_class, struct bt_ctf_clock *clock); +extern struct bt_ctf_clock *bt_ctf_stream_class_get_clock( + struct bt_ctf_stream_class *stream_class); + /* * bt_ctf_stream_class_get and bt_ctf_stream_class_put: increment and * decrement the stream class' reference count. diff --git a/plugins/ctf/common/metadata/visitor-generate-ir.c b/plugins/ctf/common/metadata/visitor-generate-ir.c index b1162511..14e9690b 100644 --- a/plugins/ctf/common/metadata/visitor-generate-ir.c +++ b/plugins/ctf/common/metadata/visitor-generate-ir.c @@ -47,7 +47,7 @@ #include #include #include -#include +#include #include "scanner.h" #include "parser.h" @@ -2247,7 +2247,7 @@ int visit_integer_decl(struct ctx *ctx, int signedness = 0; struct ctf_node *expression; uint64_t alignment = 0, size = 0; - struct bt_ctf_clock *mapped_clock = NULL; + struct bt_ctf_clock_class *mapped_clock = NULL; enum bt_ctf_string_encoding encoding = BT_CTF_STRING_ENCODING_NONE; enum bt_ctf_integer_base base = BT_CTF_INTEGER_BASE_DECIMAL; enum bt_ctf_byte_order byte_order = @@ -2514,7 +2514,7 @@ int visit_integer_decl(struct ctx *ctx, continue; } - mapped_clock = bt_ctf_trace_get_clock_by_name( + mapped_clock = bt_ctf_trace_get_clock_class_by_name( ctx->trace, clock_name); if (!mapped_clock) { _PERROR("invalid \"map\" attribute in integer declaration: cannot find clock \"%s\"", @@ -2563,7 +2563,7 @@ int visit_integer_decl(struct ctx *ctx, if (mapped_clock) { /* Move clock */ - ret |= bt_ctf_field_type_integer_set_mapped_clock( + ret |= bt_ctf_field_type_integer_set_mapped_clock_class( *integer_decl, mapped_clock); bt_put(mapped_clock); mapped_clock = NULL; @@ -4155,7 +4155,7 @@ error: static int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node, - struct bt_ctf_clock *clock, int *set) + struct bt_ctf_clock_class *clock, int *set) { int ret = 0; char *left = NULL; @@ -4188,7 +4188,7 @@ int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node, goto error; } - ret = bt_ctf_clock_set_name(clock, right); + ret = bt_ctf_clock_class_set_name(clock, right); if (ret) { _PERROR("%s", "cannot set clock's name"); g_free(right); @@ -4212,7 +4212,7 @@ int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node, goto error; } - ret = bt_ctf_clock_set_uuid(clock, uuid); + ret = bt_ctf_clock_class_set_uuid(clock, uuid); if (ret) { _PERROR("%s", "cannot set clock's UUID"); goto error; @@ -4236,7 +4236,7 @@ int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node, goto error; } - ret = bt_ctf_clock_set_description(clock, right); + ret = bt_ctf_clock_class_set_description(clock, right); if (ret) { _PERROR("%s", "cannot set clock's description"); g_free(right); @@ -4262,7 +4262,7 @@ int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node, goto error; } - ret = bt_ctf_clock_set_frequency(clock, freq); + ret = bt_ctf_clock_class_set_frequency(clock, freq); if (ret) { _PERROR("%s", "cannot set clock's frequency"); goto error; @@ -4286,7 +4286,7 @@ int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node, goto error; } - ret = bt_ctf_clock_set_precision(clock, precision); + ret = bt_ctf_clock_class_set_precision(clock, precision); if (ret) { _PERROR("%s", "cannot set clock's precision"); goto error; @@ -4310,7 +4310,7 @@ int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node, goto error; } - ret = bt_ctf_clock_set_offset_s(clock, offset_s); + ret = bt_ctf_clock_class_set_offset_s(clock, offset_s); if (ret) { _PERROR("%s", "cannot set clock's offset in seconds"); goto error; @@ -4334,7 +4334,7 @@ int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node, goto error; } - ret = bt_ctf_clock_set_offset(clock, offset); + ret = bt_ctf_clock_class_set_offset_cycles(clock, offset); if (ret) { _PERROR("%s", "cannot set clock's offset in cycles"); goto error; @@ -4360,7 +4360,7 @@ int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node, goto error; } - ret = bt_ctf_clock_set_is_absolute(clock, ret); + ret = bt_ctf_clock_class_set_is_absolute(clock, ret); if (ret) { _PERROR("%s", "cannot set clock's absolute option"); goto error; @@ -4388,7 +4388,7 @@ int visit_clock_decl(struct ctx *ctx, struct ctf_node *clock_node) { int ret = 0; int set = 0; - struct bt_ctf_clock *clock; + struct bt_ctf_clock_class *clock; struct ctf_node *entry_node; struct bt_list_head *decl_list = &clock_node->u.clock.declaration_list; @@ -4397,7 +4397,7 @@ int visit_clock_decl(struct ctx *ctx, struct ctf_node *clock_node) } clock_node->visited = TRUE; - clock = bt_ctf_clock_create(NULL); + clock = bt_ctf_clock_class_create(NULL); if (!clock) { _PERROR("%s", "cannot create clock"); ret = -ENOMEM; @@ -4418,13 +4418,13 @@ int visit_clock_decl(struct ctx *ctx, struct ctf_node *clock_node) goto error; } - if (bt_ctf_trace_get_clock_count(ctx->trace) != 0) { + if (bt_ctf_trace_get_clock_class_count(ctx->trace) != 0) { _PERROR("%s", "only CTF traces with a single clock declaration are supported as of this version"); ret = -EINVAL; goto error; } - ret = bt_ctf_trace_add_clock(ctx->trace, clock); + ret = bt_ctf_trace_add_clock_class(ctx->trace, clock); if (ret) { _PERROR("%s", "cannot add clock to trace"); goto error; diff --git a/plugins/ctf/common/notif-iter/notif-iter.c b/plugins/ctf/common/notif-iter/notif-iter.c index 82831dad..823a753f 100644 --- a/plugins/ctf/common/notif-iter/notif-iter.c +++ b/plugins/ctf/common/notif-iter/notif-iter.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include #include @@ -228,7 +228,7 @@ struct bt_ctf_notif_iter { /* Current content size (bits) (-1 if unknown) */ int64_t cur_content_size; - /* bt_ctf_clock to uint64_t. */ + /* bt_ctf_clock_class to uint64_t. */ GHashTable *clock_states; /* @@ -1490,23 +1490,25 @@ enum bt_ctf_btr_status update_clock(struct bt_ctf_notif_iter *notit, struct bt_ctf_field_type *int_field_type, struct bt_ctf_field *int_field) { - gboolean clock_found; + gboolean clock_class_found; uint64_t *clock_state; enum bt_ctf_btr_status ret = BT_CTF_BTR_STATUS_OK; - struct bt_ctf_clock *clock = bt_ctf_field_type_integer_get_mapped_clock( + struct bt_ctf_clock_class *clock_class = + bt_ctf_field_type_integer_get_mapped_clock_class( int_field_type); - if (likely(!clock)) { + if (likely(!clock_class)) { goto end_no_clock; } - clock_found = g_hash_table_lookup_extended(notit->clock_states, - clock, NULL, (gpointer) &clock_state); - if (unlikely(!clock_found)) { - const char *clock_name = bt_ctf_clock_get_name(clock); + clock_class_found = g_hash_table_lookup_extended(notit->clock_states, + clock_class, NULL, (gpointer) &clock_state); + if (unlikely(!clock_class_found)) { + const char *clock_class_name = + bt_ctf_clock_class_get_name(clock_class); - PERR("Unknown clock %s mapped to integer encountered in stream\n", - clock_name ? : "NULL"); + PERR("Unknown clock class %s mapped to integer encountered in stream\n", + clock_class_name ? : "NULL"); ret = BT_CTF_BTR_STATUS_ERROR; goto end; } @@ -1517,14 +1519,14 @@ enum bt_ctf_btr_status update_clock(struct bt_ctf_notif_iter *notit, ret = BT_CTF_BTR_STATUS_ENOMEM; goto end; } - g_hash_table_insert(notit->clock_states, bt_get(clock), + g_hash_table_insert(notit->clock_states, bt_get(clock_class), clock_state); } /* Update the clock's state. */ update_clock_state(clock_state, int_field); end: - bt_put(clock); + bt_put(clock_class); end_no_clock: return ret; } @@ -2017,21 +2019,23 @@ int set_event_clocks(struct bt_ctf_event *event, { int ret; GHashTableIter iter; - struct bt_ctf_clock *clock; + struct bt_ctf_clock_class *clock_class; uint64_t *clock_state; g_hash_table_iter_init(&iter, notit->clock_states); - while (g_hash_table_iter_next(&iter, (gpointer) &clock, + while (g_hash_table_iter_next(&iter, (gpointer) &clock_class, (gpointer) &clock_state)) { struct bt_ctf_clock_value *clock_value; - clock_value = bt_ctf_clock_value_create(clock, *clock_state); + clock_value = bt_ctf_clock_value_create(clock_class, + *clock_state); if (!clock_value) { ret = -1; goto end; } - ret = bt_ctf_event_set_clock_value(event, clock, clock_value); + ret = bt_ctf_event_set_clock_value(event, clock_class, + clock_value); bt_put(clock_value); if (ret) { goto end; @@ -2228,25 +2232,25 @@ end: static int init_clock_states(GHashTable *clock_states, struct bt_ctf_trace *trace) { - int clock_count, i, ret = 0; + int clock_class_count, i, ret = 0; - clock_count = bt_ctf_trace_get_clock_count(trace); - if (clock_count <= 0) { + clock_class_count = bt_ctf_trace_get_clock_class_count(trace); + if (clock_class_count <= 0) { ret = -1; goto end; } - for (i = 0; i < clock_count; i++) { - struct bt_ctf_clock *clock; + for (i = 0; i < clock_class_count; i++) { + struct bt_ctf_clock_class *clock_class; - clock = bt_ctf_trace_get_clock(trace, i); - if (!clock) { + clock_class = bt_ctf_trace_get_clock_class(trace, i); + if (!clock_class) { ret = -1; goto end; } - g_hash_table_insert(clock_states, bt_get(clock), NULL); - bt_put(clock); + g_hash_table_insert(clock_states, bt_get(clock_class), NULL); + bt_put(clock_class); } end: return ret; diff --git a/plugins/ctf/fs/fs.c b/plugins/ctf/fs/fs.c index 6b80d04a..ea9bf562 100644 --- a/plugins/ctf/fs/fs.c +++ b/plugins/ctf/fs/fs.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include #include @@ -377,7 +377,7 @@ bool compare_event_notifications(struct bt_notification *a, struct bt_notification *b) { int ret; - struct bt_ctf_clock *clock; + struct bt_ctf_clock_class *clock_class; struct bt_ctf_clock_value *a_clock_value, *b_clock_value; struct bt_ctf_stream_class *a_stream_class; struct bt_ctf_stream *a_stream; @@ -398,9 +398,9 @@ bool compare_event_notifications(struct bt_notification *a, trace = bt_ctf_stream_class_get_trace(a_stream_class); assert(trace); - clock = bt_ctf_trace_get_clock(trace, 0); - a_clock_value = bt_ctf_event_get_clock_value(a_event, clock); - b_clock_value = bt_ctf_event_get_clock_value(b_event, clock); + clock_class = bt_ctf_trace_get_clock_class(trace, 0); + a_clock_value = bt_ctf_event_get_clock_value(a_event, clock_class); + b_clock_value = bt_ctf_event_get_clock_value(b_event, clock_class); assert(a_clock_value); assert(b_clock_value); @@ -415,7 +415,7 @@ bool compare_event_notifications(struct bt_notification *a, bt_put(b_clock_value); bt_put(a_stream); bt_put(a_stream_class); - bt_put(clock); + bt_put(clock_class); bt_put(trace); return a_ts < b_ts; } diff --git a/plugins/text/print.c b/plugins/text/print.c index df0bea5e..c1ae888b 100644 --- a/plugins/text/print.c +++ b/plugins/text/print.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include @@ -62,14 +62,14 @@ enum bt_component_status print_field(struct text_component *text, static void print_timestamp_cycles(struct text_component *text, - struct bt_ctf_clock *clock, + struct bt_ctf_clock_class *clock_class, struct bt_ctf_event *event) { int ret; struct bt_ctf_clock_value *clock_value; uint64_t cycles; - clock_value = bt_ctf_event_get_clock_value(event, clock); + clock_value = bt_ctf_event_get_clock_value(event, clock_class); if (!clock_value) { fputs("????????????????????", text->out); return; @@ -91,7 +91,7 @@ void print_timestamp_cycles(struct text_component *text, static void print_timestamp_wall(struct text_component *text, - struct bt_ctf_clock *clock, + struct bt_ctf_clock_class *clock_class, struct bt_ctf_event *event) { int ret; @@ -101,7 +101,7 @@ void print_timestamp_wall(struct text_component *text, uint64_t ts_sec_abs, ts_nsec_abs; bool is_negative; - clock_value = bt_ctf_event_get_clock_value(event, clock); + clock_value = bt_ctf_event_get_clock_value(event, clock_class); if (!clock_value) { fputs("??:??:??.?????????", text->out); return; @@ -207,7 +207,7 @@ enum bt_component_status print_event_timestamp(struct text_component *text, struct bt_ctf_stream *stream = NULL; struct bt_ctf_stream_class *stream_class = NULL; struct bt_ctf_trace *trace = NULL; - struct bt_ctf_clock *clock = NULL; + struct bt_ctf_clock_class *clock_class = NULL; FILE *out = text->out; stream = bt_ctf_event_get_stream(event); @@ -226,17 +226,17 @@ enum bt_component_status print_event_timestamp(struct text_component *text, ret = BT_COMPONENT_STATUS_ERROR; goto end; } - clock = bt_ctf_trace_get_clock(trace, 0); - if (!clock) { + clock_class = bt_ctf_trace_get_clock_class(trace, 0); + if (!clock_class) { ret = BT_COMPONENT_STATUS_ERROR; goto end; } fputs(print_names ? "timestamp = " : "[", out); if (text->options.print_timestamp_cycles) { - print_timestamp_cycles(text, clock, event); + print_timestamp_cycles(text, clock_class, event); } else { - print_timestamp_wall(text, clock, event); + print_timestamp_wall(text, clock_class, event); } if (!print_names) @@ -274,7 +274,7 @@ enum bt_component_status print_event_timestamp(struct text_component *text, end: bt_put(stream); - bt_put(clock); + bt_put(clock_class); bt_put(stream_class); bt_put(trace); return ret; diff --git a/plugins/trimmer/iterator.c b/plugins/trimmer/iterator.c index c7e83552..e4213f47 100644 --- a/plugins/trimmer/iterator.c +++ b/plugins/trimmer/iterator.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include #include @@ -199,7 +199,7 @@ evaluate_event_notification(struct bt_notification *notification, int clock_ret; struct bt_ctf_event *event = NULL; bool in_range = true; - struct bt_ctf_clock *clock = NULL; + struct bt_ctf_clock_class *clock_class = NULL; struct bt_ctf_trace *trace = NULL; struct bt_ctf_stream *stream = NULL; struct bt_ctf_stream_class *stream_class = NULL; @@ -221,12 +221,12 @@ evaluate_event_notification(struct bt_notification *notification, assert(trace); /* FIXME multi-clock? */ - clock = bt_ctf_trace_get_clock(trace, 0); - if (!clock) { + clock_class = bt_ctf_trace_get_clock_class(trace, 0); + if (!clock_class) { goto end; } - clock_value = bt_ctf_event_get_clock_value(event, clock); + clock_value = bt_ctf_event_get_clock_value(event, clock_class); if (!clock_value) { printf_error("Failed to retrieve clock value"); ret = BT_NOTIFICATION_ITERATOR_STATUS_ERROR; @@ -263,7 +263,7 @@ evaluate_event_notification(struct bt_notification *notification, } end: bt_put(event); - bt_put(clock); + bt_put(clock_class); bt_put(trace); bt_put(stream); bt_put(stream_class); @@ -279,13 +279,14 @@ int ns_from_integer_field(struct bt_ctf_field *integer, int64_t *ns) int is_signed; uint64_t raw_clock_value; struct bt_ctf_field_type *integer_type = NULL; - struct bt_ctf_clock *clock = NULL; + struct bt_ctf_clock_class *clock_class = NULL; struct bt_ctf_clock_value *clock_value = NULL; integer_type = bt_ctf_field_get_type(integer); assert(integer_type); - clock = bt_ctf_field_type_integer_get_mapped_clock(integer_type); - if (!clock) { + clock_class = bt_ctf_field_type_integer_get_mapped_clock_class( + integer_type); + if (!clock_class) { ret = -1; goto end; } @@ -302,7 +303,7 @@ int ns_from_integer_field(struct bt_ctf_field *integer, int64_t *ns) goto end; } - clock_value = bt_ctf_clock_value_create(clock, raw_clock_value); + clock_value = bt_ctf_clock_value_create(clock_class, raw_clock_value); if (!clock_value) { goto end; } @@ -310,7 +311,7 @@ int ns_from_integer_field(struct bt_ctf_field *integer, int64_t *ns) ret = bt_ctf_clock_value_get_value_ns_from_epoch(clock_value, ns); end: bt_put(integer_type); - bt_put(clock); + bt_put(clock_class); bt_put(clock_value); return ret; } diff --git a/plugins/writer/write.c b/plugins/writer/write.c index d2c07fec..91fcdf1f 100644 --- a/plugins/writer/write.c +++ b/plugins/writer/write.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include @@ -39,18 +39,19 @@ #include "writer.h" static -enum bt_component_status copy_clock(FILE *err, struct bt_ctf_writer *writer, +enum bt_component_status copy_clock_class(FILE *err, struct bt_ctf_writer *writer, struct bt_ctf_stream_class *writer_stream_class, - struct bt_ctf_clock *clock) + struct bt_ctf_clock_class *clock_class) { int64_t offset, offset_s; int int_ret; uint64_t u64_ret; const char *name, *description; - struct bt_ctf_clock *writer_clock = NULL; + struct bt_ctf_clock_class *writer_clock_class = NULL; + struct bt_ctf_trace *trace = NULL; enum bt_component_status ret; - name = bt_ctf_clock_get_name(clock); + name = bt_ctf_clock_class_get_name(clock_class); if (!name) { fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); @@ -58,15 +59,15 @@ enum bt_component_status copy_clock(FILE *err, struct bt_ctf_writer *writer, goto end; } - writer_clock = bt_ctf_clock_create(name); - if (!writer_clock) { + writer_clock_class = bt_ctf_clock_class_create(name); + if (!writer_clock_class) { fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); ret = BT_COMPONENT_STATUS_ERROR; goto end; } - description = bt_ctf_clock_get_description(clock); + description = bt_ctf_clock_class_get_description(clock_class); if (!description) { fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); @@ -74,7 +75,7 @@ enum bt_component_status copy_clock(FILE *err, struct bt_ctf_writer *writer, goto end_destroy; } - int_ret = bt_ctf_clock_set_description(writer_clock, + int_ret = bt_ctf_clock_class_set_description(writer_clock_class, description); if (int_ret != 0) { fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, @@ -83,14 +84,14 @@ enum bt_component_status copy_clock(FILE *err, struct bt_ctf_writer *writer, goto end_destroy; } - u64_ret = bt_ctf_clock_get_frequency(clock); + u64_ret = bt_ctf_clock_class_get_frequency(clock_class); if (u64_ret == -1ULL) { fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); ret = BT_COMPONENT_STATUS_ERROR; goto end_destroy; } - int_ret = bt_ctf_clock_set_frequency(writer_clock, u64_ret); + int_ret = bt_ctf_clock_class_set_frequency(writer_clock_class, u64_ret); if (int_ret != 0) { fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); @@ -98,14 +99,15 @@ enum bt_component_status copy_clock(FILE *err, struct bt_ctf_writer *writer, goto end_destroy; } - u64_ret = bt_ctf_clock_get_precision(clock); + u64_ret = bt_ctf_clock_class_get_precision(clock_class); if (u64_ret == -1ULL) { fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); ret = BT_COMPONENT_STATUS_ERROR; goto end_destroy; } - int_ret = bt_ctf_clock_set_precision(writer_clock, u64_ret); + int_ret = bt_ctf_clock_class_set_precision(writer_clock_class, + u64_ret); if (int_ret != 0) { fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); @@ -113,7 +115,7 @@ enum bt_component_status copy_clock(FILE *err, struct bt_ctf_writer *writer, goto end_destroy; } - int_ret = bt_ctf_clock_get_offset_s(clock, &offset_s); + int_ret = bt_ctf_clock_class_get_offset_s(clock_class, &offset_s); if (int_ret != 0) { fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); @@ -121,7 +123,7 @@ enum bt_component_status copy_clock(FILE *err, struct bt_ctf_writer *writer, goto end_destroy; } - int_ret = bt_ctf_clock_set_offset_s(writer_clock, offset_s); + int_ret = bt_ctf_clock_class_set_offset_s(writer_clock_class, offset_s); if (int_ret != 0) { fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); @@ -129,7 +131,7 @@ enum bt_component_status copy_clock(FILE *err, struct bt_ctf_writer *writer, goto end_destroy; } - int_ret = bt_ctf_clock_get_offset(clock, &offset); + int_ret = bt_ctf_clock_class_get_offset_cycles(clock_class, &offset); if (int_ret != 0) { fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); @@ -137,7 +139,7 @@ enum bt_component_status copy_clock(FILE *err, struct bt_ctf_writer *writer, goto end_destroy; } - int_ret = bt_ctf_clock_set_offset(writer_clock, offset); + int_ret = bt_ctf_clock_class_set_offset_cycles(writer_clock_class, offset); if (int_ret != 0) { fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); @@ -145,7 +147,7 @@ enum bt_component_status copy_clock(FILE *err, struct bt_ctf_writer *writer, goto end_destroy; } - int_ret = bt_ctf_clock_get_is_absolute(clock); + int_ret = bt_ctf_clock_class_get_is_absolute(clock_class); if (int_ret == -1) { fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); @@ -153,7 +155,7 @@ enum bt_component_status copy_clock(FILE *err, struct bt_ctf_writer *writer, goto end_destroy; } - int_ret = bt_ctf_clock_set_is_absolute(writer_clock, int_ret); + int_ret = bt_ctf_clock_class_set_is_absolute(writer_clock_class, int_ret); if (int_ret != 0) { fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); @@ -161,7 +163,13 @@ enum bt_component_status copy_clock(FILE *err, struct bt_ctf_writer *writer, goto end_destroy; } - int_ret = bt_ctf_writer_add_clock(writer, writer_clock); + trace = bt_ctf_writer_get_trace(writer); + if (!trace) { + ret = BT_COMPONENT_STATUS_ERROR; + goto end_destroy; + } + + int_ret = bt_ctf_trace_add_clock_class(trace, writer_clock_class); if (int_ret != 0) { fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); @@ -172,14 +180,15 @@ enum bt_component_status copy_clock(FILE *err, struct bt_ctf_writer *writer, /* * Ownership transferred to the writer and the stream_class. */ - bt_put(writer_clock); + bt_put(writer_clock_class); ret = BT_COMPONENT_STATUS_OK; goto end; end_destroy: - BT_PUT(writer_clock); + BT_PUT(writer_clock_class); end: + BT_PUT(trace); return ret; } @@ -336,7 +345,7 @@ enum bt_component_status copy_stream_class(FILE *err, { enum bt_component_status ret = BT_COMPONENT_STATUS_OK; struct bt_ctf_field_type *type; - int ret_int, clock_count, i; + int ret_int, clock_class_count, i; struct bt_ctf_trace *trace; trace = bt_ctf_stream_class_get_trace(stream_class); @@ -347,20 +356,21 @@ enum bt_component_status copy_stream_class(FILE *err, goto end; } - clock_count = bt_ctf_trace_get_clock_count(trace); + clock_class_count = bt_ctf_trace_get_clock_class_count(trace); - for (i = 0; i < clock_count; i++) { - struct bt_ctf_clock *clock = bt_ctf_trace_get_clock(trace, i); + for (i = 0; i < clock_class_count; i++) { + struct bt_ctf_clock_class *clock_class = + bt_ctf_trace_get_clock_class(trace, i); - if (!clock) { + if (!clock_class) { fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); ret = BT_COMPONENT_STATUS_ERROR; goto end_put_trace; } - ret = copy_clock(err, writer, writer_stream_class, clock); - bt_put(clock); + ret = copy_clock_class(err, writer, writer_stream_class, clock_class); + bt_put(clock_class); if (ret != BT_COMPONENT_STATUS_OK) { fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); diff --git a/tests/lib/test_ctf_writer.c b/tests/lib/test_ctf_writer.c index c8ddd2e6..a16d895b 100644 --- a/tests/lib/test_ctf_writer.c +++ b/tests/lib/test_ctf_writer.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -59,7 +60,7 @@ #define DEFAULT_CLOCK_TIME 0 #define DEFAULT_CLOCK_VALUE 0 -#define NR_TESTS 599 +#define NR_TESTS 596 static int64_t current_time = 42; @@ -2287,11 +2288,10 @@ end: } static -void test_custom_event_header_stream(struct bt_ctf_writer *writer) +void test_custom_event_header_stream(struct bt_ctf_writer *writer, + struct bt_ctf_clock *clock) { int i, ret; - struct bt_ctf_trace *trace = NULL; - struct bt_ctf_clock *clock = NULL; struct bt_ctf_stream_class *stream_class = NULL; struct bt_ctf_stream *stream = NULL; struct bt_ctf_field_type *integer_type = NULL, @@ -2301,18 +2301,6 @@ void test_custom_event_header_stream(struct bt_ctf_writer *writer) struct bt_ctf_event_class *event_class = NULL; struct bt_ctf_event *event = NULL; - trace = bt_ctf_writer_get_trace(writer); - if (!trace) { - fail("Failed to get trace from writer"); - goto end; - } - - clock = bt_ctf_trace_get_clock(trace, 0); - if (!clock) { - fail("Failed to get clock from trace"); - goto end; - } - stream_class = bt_ctf_stream_class_create("custom_event_header_stream"); if (!stream_class) { fail("Failed to create stream class"); @@ -2477,8 +2465,6 @@ void test_custom_event_header_stream(struct bt_ctf_writer *writer) fail("Failed to flush custom_event_header stream"); } end: - bt_put(clock); - bt_put(trace); bt_put(stream); bt_put(stream_class); bt_put(event_class); @@ -2493,11 +2479,10 @@ end: } static -void test_instanciate_event_before_stream(struct bt_ctf_writer *writer) +void test_instanciate_event_before_stream(struct bt_ctf_writer *writer, + struct bt_ctf_clock *clock) { int ret = 0; - struct bt_ctf_trace *trace = NULL; - struct bt_ctf_clock *clock = NULL; struct bt_ctf_stream_class *stream_class = NULL; struct bt_ctf_stream *stream = NULL, *ret_stream = NULL; @@ -2506,20 +2491,6 @@ void test_instanciate_event_before_stream(struct bt_ctf_writer *writer) struct bt_ctf_field_type *integer_type = NULL; struct bt_ctf_field *integer = NULL; - trace = bt_ctf_writer_get_trace(writer); - if (!trace) { - diag("Failed to get trace from writer"); - ret = -1; - goto end; - } - - clock = bt_ctf_trace_get_clock(trace, 0); - if (!clock) { - diag("Failed to get clock from trace"); - ret = -1; - goto end; - } - stream_class = bt_ctf_stream_class_create("event_before_stream_test"); if (!stream_class) { diag("Failed to create stream class"); @@ -2598,7 +2569,6 @@ void test_instanciate_event_before_stream(struct bt_ctf_writer *writer) end: ok(ret == 0, "Create an event before instanciating its associated stream"); - bt_put(trace); bt_put(stream); bt_put(ret_stream); bt_put(stream_class); @@ -2606,7 +2576,6 @@ end: bt_put(event); bt_put(integer_type); bt_put(integer); - bt_put(clock); } static @@ -2628,43 +2597,6 @@ void append_existing_event_class(struct bt_ctf_stream_class *stream_class) bt_put(event_class); } -static -void test_trace_stream_class_clock(void) -{ - struct bt_ctf_trace *trace = NULL; - struct bt_ctf_stream_class *sc1 = NULL; - struct bt_ctf_stream_class *sc2 = NULL; - struct bt_ctf_clock *sc1_clock = NULL; - struct bt_ctf_clock *sc2_clock = NULL; - const char *clock_name = "hello"; - - trace = bt_ctf_trace_create(); - assert(trace); - sc1 = bt_ctf_stream_class_create(NULL); - assert(sc1); - sc2 = bt_ctf_stream_class_create(NULL); - assert(sc2); - sc1_clock = bt_ctf_clock_create(clock_name); - assert(sc1_clock); - sc2_clock = bt_ctf_clock_create(clock_name); - assert(sc2_clock); - - ok(!bt_ctf_stream_class_set_clock(sc1, sc1_clock), - "bt_ctf_stream_class_set_clock() succeeds for sc1"); - ok(!bt_ctf_stream_class_set_clock(sc2, sc2_clock), - "bt_ctf_stream_class_set_clock() succeeds for sc2"); - ok(!bt_ctf_trace_add_stream_class(trace, sc1), - "bt_ctf_trace_add_stream_class() succeeds with sc1"); - ok(bt_ctf_trace_add_stream_class(trace, sc2), - "bt_ctf_trace_add_stream_class() fails with sc2 (different clock, same name)"); - - BT_PUT(trace); - BT_PUT(sc1); - BT_PUT(sc2); - BT_PUT(sc1_clock); - BT_PUT(sc2_clock); -} - static struct bt_ctf_event_class *create_minimal_event_class(void) { @@ -2706,7 +2638,7 @@ void test_create_writer_vs_non_writer_mode(void) struct bt_ctf_field_type *empty_struct_ft = NULL; struct bt_ctf_field *int_field = NULL; struct bt_ctf_clock *writer_clock = NULL; - struct bt_ctf_clock *non_writer_clock = NULL; + struct bt_ctf_clock_class *non_writer_clock_class = NULL; struct bt_ctf_packet *packet = NULL; struct bt_ctf_packet *packet2 = NULL; @@ -2736,7 +2668,7 @@ void test_create_writer_vs_non_writer_mode(void) "bt_ctf_stream_get_name() returns the stream's name"); writer_clock = bt_ctf_clock_create("writer_clock"); assert(writer_clock); - ret = bt_ctf_trace_add_clock(writer_trace, writer_clock); + ret = bt_ctf_writer_add_clock(writer, writer_clock); assert(!ret); /* Create non-writer trace, stream class, stream, and clock */ @@ -2751,9 +2683,11 @@ void test_create_writer_vs_non_writer_mode(void) assert(!ret); non_writer_stream = bt_ctf_stream_create(non_writer_sc, NULL); assert(non_writer_stream); - non_writer_clock = bt_ctf_clock_create("non_writer_clock"); - assert(non_writer_clock); - ret = bt_ctf_trace_add_clock(non_writer_trace, non_writer_clock); + non_writer_clock_class = + bt_ctf_clock_class_create("non_writer_clock_class"); + assert(non_writer_clock_class); + ret = bt_ctf_trace_add_clock_class(non_writer_trace, + non_writer_clock_class); assert(!ret); /* Create event class and event */ @@ -2866,7 +2800,7 @@ void test_create_writer_vs_non_writer_mode(void) bt_put(int_field); bt_put(empty_struct_ft); bt_put(writer_clock); - bt_put(non_writer_clock); + bt_put(non_writer_clock_class); bt_put(packet); bt_put(packet2); recursive_rmdir(trace_path); @@ -2892,6 +2826,34 @@ void test_clock_utils(void) BT_PUT(clock); } +void test_set_clock_non_writer_stream_class(void) +{ + struct bt_ctf_clock *clock; + struct bt_ctf_trace *trace; + struct bt_ctf_stream_class *sc; + int ret; + + clock = bt_ctf_clock_create("the_clock"); + assert(clock); + + trace = bt_ctf_trace_create(); + assert(trace); + + sc = bt_ctf_stream_class_create(NULL); + assert(sc); + + ret = bt_ctf_stream_class_set_clock(sc, clock); + assert(ret == 0); + + ret = bt_ctf_trace_add_stream_class(trace, sc); + ok(ret < 0, + "bt_ctf_trace_add_stream_class() fails with a stream class with a registered clock"); + + bt_put(clock); + bt_put(trace); + bt_put(sc); +} + int main(int argc, char **argv) { char trace_path[] = "/tmp/ctfwriter_XXXXXX"; @@ -2912,6 +2874,7 @@ int main(int argc, char **argv) struct utsname name; char hostname[BABELTRACE_HOST_NAME_MAX]; struct bt_ctf_clock *clock, *ret_clock; + struct bt_ctf_clock_class *ret_clock_class; struct bt_ctf_stream_class *stream_class, *ret_stream_class; struct bt_ctf_stream *stream1; const char *ret_string; @@ -3389,6 +3352,8 @@ int main(int argc, char **argv) bt_put(ret_field_type); /* Instantiate a stream and append events */ + ret = bt_ctf_writer_add_clock(writer, clock); + assert(ret == 0); stream1 = bt_ctf_writer_create_stream(writer, stream_class); ok(stream1, "Instanciate a stream class from writer"); @@ -3397,31 +3362,33 @@ int main(int argc, char **argv) * class to the writer's trace, thus registering the stream * class's clock to the trace. */ - ok(bt_ctf_trace_get_clock_count(NULL) < 0, - "bt_ctf_trace_get_clock_count correctly handles NULL"); - ok(bt_ctf_trace_get_clock_count(trace) == 1, - "bt_ctf_trace_get_clock_count returns the correct number of clocks"); - ok(!bt_ctf_trace_get_clock(NULL, 0), - "bt_ctf_trace_get_clock correctly handles NULL"); - ok(!bt_ctf_trace_get_clock(trace, -1), - "bt_ctf_trace_get_clock correctly handles negative indexes"); - ok(!bt_ctf_trace_get_clock(trace, 1), - "bt_ctf_trace_get_clock correctly handles out of bound accesses"); - ret_clock = bt_ctf_trace_get_clock(trace, 0); - ok(ret_clock == clock, - "bt_ctf_trace_get_clock returns the right clock instance"); - bt_put(ret_clock); - ok(!bt_ctf_trace_get_clock_by_name(trace, NULL), - "bt_ctf_trace_get_clock_by_name correctly handles NULL (trace)"); - ok(!bt_ctf_trace_get_clock_by_name(NULL, clock_name), + ok(bt_ctf_trace_get_clock_class_count(NULL) < 0, + "bt_ctf_trace_get_clock_class_count correctly handles NULL"); + ok(bt_ctf_trace_get_clock_class_count(trace) == 1, + "bt_ctf_trace_get_clock_class_count returns the correct number of clocks"); + ok(!bt_ctf_trace_get_clock_class(NULL, 0), + "bt_ctf_trace_get_clock_class correctly handles NULL"); + ok(!bt_ctf_trace_get_clock_class(trace, -1), + "bt_ctf_trace_get_clock_class correctly handles negative indexes"); + ok(!bt_ctf_trace_get_clock_class(trace, 1), + "bt_ctf_trace_get_clock_class correctly handles out of bound accesses"); + ret_clock_class = bt_ctf_trace_get_clock_class(trace, 0); + ok(strcmp(bt_ctf_clock_class_get_name(ret_clock_class), + bt_ctf_clock_get_name(clock)) == 0, + "bt_ctf_trace_get_clock_class returns the right clock instance"); + bt_put(ret_clock_class); + ok(!bt_ctf_trace_get_clock_class_by_name(trace, NULL), + "bt_ctf_trace_get_clock_class_by_name correctly handles NULL (trace)"); + ok(!bt_ctf_trace_get_clock_class_by_name(NULL, clock_name), "bt_ctf_trace_get_clock_by_name correctly handles NULL (clock name)"); - ok(!bt_ctf_trace_get_clock_by_name(NULL, NULL), + ok(!bt_ctf_trace_get_clock_class_by_name(NULL, NULL), "bt_ctf_trace_get_clock_by_name correctly handles NULL (both)"); - ret_clock = bt_ctf_trace_get_clock_by_name(trace, clock_name); - ok(ret_clock == clock, - "bt_ctf_trace_get_clock_by_name returns the right clock instance"); - bt_put(ret_clock); - ok(!bt_ctf_trace_get_clock_by_name(trace, "random"), + ret_clock_class = bt_ctf_trace_get_clock_class_by_name(trace, clock_name); + ok(strcmp(bt_ctf_clock_class_get_name(ret_clock_class), + bt_ctf_clock_get_name(clock)) == 0, + "bt_ctf_trace_get_clock_class returns the right clock instance"); + bt_put(ret_clock_class); + ok(!bt_ctf_trace_get_clock_class_by_name(trace, "random"), "bt_ctf_trace_get_clock_by_name fails when the requested clock doesn't exist"); ok(bt_ctf_stream_get_class(NULL) == NULL, @@ -3513,11 +3480,11 @@ int main(int argc, char **argv) test_clock_utils(); - test_trace_stream_class_clock(); - test_create_writer_vs_non_writer_mode(); - test_instanciate_event_before_stream(writer); + test_set_clock_non_writer_stream_class(); + + test_instanciate_event_before_stream(writer, clock); append_simple_event(stream_class, stream1, clock); @@ -3529,7 +3496,7 @@ int main(int argc, char **argv) test_empty_stream(writer); - test_custom_event_header_stream(writer); + test_custom_event_header_stream(writer, clock); metadata_string = bt_ctf_writer_get_metadata_string(writer); ok(metadata_string, "Get metadata string"); -- 2.34.1