X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=formats%2Fctf%2Fir%2Fstream.c;h=74c6f52b5828bcf8b278486b25666cfde0e27628;hb=5c424b9cbac73fe5041ed6d4859e358b64268ae9;hp=56abfcea5f89fe1f78f47241428fcc20d3688361;hpb=37f301682345ca58a078ba6bcd131fd0030fed0c;p=babeltrace.git diff --git a/formats/ctf/ir/stream.c b/formats/ctf/ir/stream.c index 56abfcea..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) { @@ -61,7 +101,7 @@ int set_packet_header_magic(struct bt_ctf_stream *stream) goto end; } - if (!bt_ctf_field_validate(magic_field)) { + if (bt_ctf_field_is_set(magic_field)) { /* Value already set. Not an error, skip. */ goto end; } @@ -113,7 +153,7 @@ int set_packet_header_uuid(struct bt_ctf_stream *stream) goto end; } - if (!bt_ctf_field_validate(uuid_field)) { + if (bt_ctf_field_is_set(uuid_field)) { /* Value already set. Not an error, skip. */ goto end; } @@ -186,7 +226,7 @@ int set_packet_header_stream_id(struct bt_ctf_stream *stream) goto end; } - if (!bt_ctf_field_validate(stream_id_field)) { + if (bt_ctf_field_is_set(stream_id_field)) { /* Value already set. Not an error, skip. */ goto end; } @@ -403,9 +443,6 @@ struct bt_ctf_stream *bt_ctf_stream_create( if (ret) { goto error; } - - stream->clock_values = g_hash_table_new_full(g_direct_hash, - g_direct_equal, NULL, g_free); } /* Add this stream to the trace's streams */ @@ -556,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) { @@ -580,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; } @@ -639,7 +756,7 @@ int bt_ctf_stream_set_packet_context(struct bt_ctf_stream *stream, int ret = 0; struct bt_ctf_field_type *field_type; - if (!stream || !field || stream->pos.fd < 0) { + if (!stream || stream->pos.fd < 0) { ret = -1; goto end; } @@ -652,9 +769,8 @@ int bt_ctf_stream_set_packet_context(struct bt_ctf_stream *stream, } bt_put(field_type); - bt_get(field); bt_put(stream->packet_context); - stream->packet_context = field; + stream->packet_context = bt_get(field); end: return ret; } @@ -683,7 +799,7 @@ int bt_ctf_stream_set_packet_header(struct bt_ctf_stream *stream, struct bt_ctf_trace *trace = NULL; struct bt_ctf_field_type *field_type = NULL; - if (!stream || !field || stream->pos.fd < 0) { + if (!stream || stream->pos.fd < 0) { ret = -1; goto end; } @@ -695,9 +811,8 @@ int bt_ctf_stream_set_packet_header(struct bt_ctf_stream *stream, goto end; } - bt_get(field); bt_put(stream->packet_header); - stream->packet_header = field; + stream->packet_header = bt_get(field); end: BT_PUT(trace); bt_put(field_type); @@ -937,10 +1052,6 @@ void bt_ctf_stream_destroy(struct bt_object *obj) g_string_free(stream->name, TRUE); } - if (stream->clock_values) { - g_hash_table_destroy(stream->clock_values); - } - bt_put(stream->packet_header); bt_put(stream->packet_context); g_free(stream); @@ -966,7 +1077,7 @@ int set_structure_field_integer(struct bt_ctf_field *structure, char *name, } /* Make sure the payload has not already been set. */ - if (!bt_ctf_field_validate(integer)) { + if (bt_ctf_field_is_set(integer)) { /* Payload already set, not an error */ goto end; } @@ -1010,77 +1121,16 @@ end: return name; } -BT_HIDDEN -void bt_ctf_stream_update_clock_value(struct bt_ctf_stream *stream, - struct bt_ctf_field *value_field) +int bt_ctf_stream_is_writer(struct bt_ctf_stream *stream) { - struct bt_ctf_field_type *value_type = NULL; - struct bt_ctf_clock *clock = NULL; - uint64_t requested_new_value; - uint64_t requested_new_value_mask; - uint64_t *cur_value; - uint64_t cur_value_masked; - int requested_new_value_size; - int ret; - - assert(stream); - assert(clock); - assert(value_field); - value_type = bt_ctf_field_get_type(value_field); - assert(value_type); - clock = bt_ctf_field_type_integer_get_mapped_clock(value_type); - assert(clock); - requested_new_value_size = - bt_ctf_field_type_integer_get_size(value_type); - assert(requested_new_value_size > 0); - ret = bt_ctf_field_unsigned_integer_get_value(value_field, - &requested_new_value); - assert(!ret); - cur_value = g_hash_table_lookup(stream->clock_values, clock); - - if (!cur_value) { - /* - * Updating the value of a clock which is not registered - * yet, so register it with the new value as its initial - * value. - */ - uint64_t *requested_new_value_ptr = g_new0(uint64_t, 1); - - *requested_new_value_ptr = requested_new_value; - g_hash_table_insert(stream->clock_values, clock, - requested_new_value_ptr); - goto end; - } + int ret = -1; - /* - * Special case for a 64-bit new value, which is the limit - * of a clock value as of this version: overwrite the - * current value directly. - */ - if (requested_new_value_size == 64) { - *cur_value = requested_new_value; + if (!stream) { goto end; } - requested_new_value_mask = (1ULL << requested_new_value_size) - 1; - cur_value_masked = *cur_value & requested_new_value_mask; - - if (requested_new_value < cur_value_masked) { - /* - * It looks like a wrap happened on the number of bits - * of the requested new value. Assume that the clock - * value wrapped only one time. - */ - *cur_value += requested_new_value_mask + 1; - } - - /* Clear the low bits of the current clock value */ - *cur_value &= ~requested_new_value_mask; - - /* Set the low bits of the current clock value */ - *cur_value |= requested_new_value; + ret = (stream->pos.fd >= 0); end: - bt_put(clock); - bt_put(value_type); + return ret; }