X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=formats%2Fctf%2Fir%2Fstream.c;h=9b0be90b7b2e97ad96f36e670060cb51192e33a9;hp=e618251e577a3d6e5614b475faa8b1d30c926385;hb=12c8a1a3121ed7125e8758065c44658d8eda1333;hpb=9773681407e4e8fce40f247132dc99fabe306bfe diff --git a/formats/ctf/ir/stream.c b/formats/ctf/ir/stream.c index e618251e..9b0be90b 100644 --- a/formats/ctf/ir/stream.c +++ b/formats/ctf/ir/stream.c @@ -48,6 +48,7 @@ BT_HIDDEN struct bt_ctf_stream *bt_ctf_stream_create( struct bt_ctf_stream_class *stream_class) { + int ret; struct bt_ctf_stream *stream = NULL; if (!stream_class) { @@ -60,6 +61,19 @@ struct bt_ctf_stream *bt_ctf_stream_create( } bt_ctf_ref_init(&stream->ref_count); + stream->packet_context = bt_ctf_field_create( + stream_class->packet_context_type); + if (!stream->packet_context) { + goto error_destroy; + } + + /* Initialize events_discarded*/ + ret = set_structure_field_integer(stream->packet_context, + "events_discarded", 0); + if (ret) { + goto error_destroy; + } + stream->pos.fd = -1; stream->id = stream_class->next_stream_id++; stream->stream_class = stream_class; @@ -69,6 +83,9 @@ struct bt_ctf_stream *bt_ctf_stream_create( (GDestroyNotify)bt_ctf_event_put); end: return stream; +error_destroy: + bt_ctf_stream_destroy(&stream->ref_count); + return NULL; } BT_HIDDEN @@ -107,25 +124,127 @@ int bt_ctf_stream_get_discarded_events_count( struct bt_ctf_stream *stream, uint64_t *count) { int64_t ret = 0; + int field_signed; + struct bt_ctf_field *events_discarded_field = NULL; + struct bt_ctf_field_type *events_discarded_field_type = NULL; - if (!stream || !count) { + if (!stream || !count || !stream->packet_context) { ret = -1; goto end; } - *count = stream->events_discarded; + events_discarded_field = bt_ctf_field_structure_get_field( + stream->packet_context, "events_discarded"); + if (!events_discarded_field) { + ret = -1; + goto end; + } + + events_discarded_field_type = bt_ctf_field_get_type( + events_discarded_field); + if (!events_discarded_field_type) { + ret = -1; + goto end; + } + + field_signed = bt_ctf_field_type_integer_get_signed( + events_discarded_field_type); + if (field_signed < 0) { + ret = field_signed; + goto end; + } + + if (field_signed) { + int64_t signed_count; + + ret = bt_ctf_field_signed_integer_get_value( + events_discarded_field, &signed_count); + if (ret) { + goto end; + } + if (signed_count < 0) { + /* Invalid value */ + ret = -1; + goto end; + } + *count = (uint64_t) signed_count; + } else { + ret = bt_ctf_field_unsigned_integer_get_value( + events_discarded_field, count); + if (ret) { + goto end; + } + } end: + if (events_discarded_field) { + bt_ctf_field_put(events_discarded_field); + } + if (events_discarded_field_type) { + bt_ctf_field_type_put(events_discarded_field_type); + } return ret; } void bt_ctf_stream_append_discarded_events(struct bt_ctf_stream *stream, uint64_t event_count) { - if (!stream) { - return; + int ret; + int field_signed; + uint64_t previous_count; + uint64_t new_count; + struct bt_ctf_field *events_discarded_field = NULL; + struct bt_ctf_field_type *events_discarded_field_type = NULL; + + if (!stream || !stream->packet_context) { + goto end; + } + + ret = bt_ctf_stream_get_discarded_events_count(stream, + &previous_count); + if (ret) { + goto end; + } + + events_discarded_field = bt_ctf_field_structure_get_field( + stream->packet_context, "events_discarded"); + if (!events_discarded_field) { + goto end; + } + + events_discarded_field_type = bt_ctf_field_get_type( + events_discarded_field); + if (!events_discarded_field_type) { + goto end; + } + + field_signed = bt_ctf_field_type_integer_get_signed( + events_discarded_field_type); + if (field_signed < 0) { + goto end; } - stream->events_discarded += event_count; + new_count = previous_count + event_count; + if (field_signed) { + ret = bt_ctf_field_signed_integer_set_value( + events_discarded_field, (int64_t) new_count); + if (ret) { + goto end; + } + } else { + ret = bt_ctf_field_unsigned_integer_set_value( + events_discarded_field, new_count); + if (ret) { + goto end; + } + } + +end: + if (events_discarded_field) { + bt_ctf_field_put(events_discarded_field); + } + if (events_discarded_field_type) { + bt_ctf_field_type_put(events_discarded_field_type); + } } int bt_ctf_stream_append_event(struct bt_ctf_stream *stream, @@ -156,11 +275,53 @@ end: return ret; } +struct bt_ctf_field *bt_ctf_stream_get_packet_context( + struct bt_ctf_stream *stream) +{ + struct bt_ctf_field *packet_context = NULL; + + if (!stream) { + goto end; + } + + packet_context = stream->packet_context; +end: + if (packet_context) { + bt_ctf_field_get(packet_context); + } + return packet_context; +} + +int bt_ctf_stream_set_packet_context(struct bt_ctf_stream *stream, + struct bt_ctf_field *field) +{ + int ret = 0; + struct bt_ctf_field_type *field_type; + + if (!stream || !field) { + ret = -1; + goto end; + } + + field_type = bt_ctf_field_get_type(field); + if (field_type != stream->stream_class->packet_context_type) { + ret = -1; + goto end; + } + + bt_ctf_field_type_put(field_type); + bt_ctf_field_get(field); + bt_ctf_field_put(stream->packet_context); + stream->packet_context = field; +end: + return ret; +} + int bt_ctf_stream_flush(struct bt_ctf_stream *stream) { int ret = 0; size_t i; - uint64_t timestamp_begin, timestamp_end; + uint64_t timestamp_begin, timestamp_end, events_discarded; struct bt_ctf_stream_class *stream_class; struct bt_ctf_field *integer = NULL; struct ctf_stream_pos packet_context_pos; @@ -183,31 +344,27 @@ int bt_ctf_stream_flush(struct bt_ctf_stream *stream) stream->events, 0))->timestamp; timestamp_end = ((struct bt_ctf_event *) g_ptr_array_index( stream->events, stream->events->len - 1))->timestamp; - ret = set_structure_field_integer(stream_class->packet_context, + + /* Set the default context attributes if present and unset. */ + ret = set_structure_field_integer(stream->packet_context, "timestamp_begin", timestamp_begin); if (ret) { goto end; } - ret = set_structure_field_integer(stream_class->packet_context, + ret = set_structure_field_integer(stream->packet_context, "timestamp_end", timestamp_end); if (ret) { goto end; } - ret = set_structure_field_integer(stream_class->packet_context, - "events_discarded", stream->events_discarded); - if (ret) { - goto end; - } - - ret = set_structure_field_integer(stream_class->packet_context, + ret = set_structure_field_integer(stream->packet_context, "content_size", UINT64_MAX); if (ret) { goto end; } - ret = set_structure_field_integer(stream_class->packet_context, + ret = set_structure_field_integer(stream->packet_context, "packet_size", UINT64_MAX); if (ret) { goto end; @@ -216,12 +373,31 @@ int bt_ctf_stream_flush(struct bt_ctf_stream *stream) /* Write packet context */ memcpy(&packet_context_pos, &stream->pos, sizeof(struct ctf_stream_pos)); - ret = bt_ctf_field_serialize(stream_class->packet_context, + ret = bt_ctf_field_serialize(stream->packet_context, &stream->pos); if (ret) { goto end; } + ret = bt_ctf_stream_get_discarded_events_count(stream, + &events_discarded); + if (ret) { + goto end; + } + + /* Unset the packet context's fields. */ + ret = bt_ctf_field_reset(stream->packet_context); + if (ret) { + goto end; + } + + /* Set the previous number of discarded events. */ + ret = set_structure_field_integer(stream->packet_context, + "events_discarded", events_discarded); + if (ret) { + goto end; + } + for (i = 0; i < stream->events->len; i++) { struct bt_ctf_event *event = g_ptr_array_index( stream->events, i); @@ -229,6 +405,11 @@ int bt_ctf_stream_flush(struct bt_ctf_stream *stream) event->event_class); uint64_t timestamp = bt_ctf_event_get_timestamp(event); + ret = bt_ctf_field_reset(stream_class->event_header); + if (ret) { + goto end; + } + ret = set_structure_field_integer(stream_class->event_header, "id", event_id); if (ret) { @@ -261,19 +442,19 @@ int bt_ctf_stream_flush(struct bt_ctf_stream *stream) * packet is resized). */ packet_context_pos.base_mma = stream->pos.base_mma; - ret = set_structure_field_integer(stream_class->packet_context, + ret = set_structure_field_integer(stream->packet_context, "content_size", stream->pos.offset); if (ret) { goto end; } - ret = set_structure_field_integer(stream_class->packet_context, + ret = set_structure_field_integer(stream->packet_context, "packet_size", stream->pos.packet_size); if (ret) { goto end; } - ret = bt_ctf_field_serialize(stream_class->packet_context, + ret = bt_ctf_field_serialize(stream->packet_context, &packet_context_pos); if (ret) { goto end; @@ -318,8 +499,16 @@ void bt_ctf_stream_destroy(struct bt_ctf_ref *ref) if (close(stream->pos.fd)) { perror("close"); } - bt_ctf_stream_class_put(stream->stream_class); - g_ptr_array_free(stream->events, TRUE); + + if (stream->stream_class) { + bt_ctf_stream_class_put(stream->stream_class); + } + if (stream->events) { + g_ptr_array_free(stream->events, TRUE); + } + if (stream->packet_context) { + bt_ctf_field_put(stream->packet_context); + } g_free(stream); } @@ -328,14 +517,25 @@ int set_structure_field_integer(struct bt_ctf_field *structure, char *name, uint64_t value) { int ret = 0; - struct bt_ctf_field *integer = bt_ctf_field_structure_get_field(structure, name); - if (!integer) { + + if (!structure || !name) { ret = -1; goto end; } + if (!integer) { + /* Field not found, not an error. */ + goto end; + } + + /* Make sure the payload has not already been set. */ + if (!bt_ctf_field_validate(integer)) { + /* Payload already set, not an error */ + goto end; + } + ret = bt_ctf_field_unsigned_integer_set_value(integer, value); end: bt_ctf_field_put(integer);