static int bt_ctf_field_structure_serialize(struct bt_ctf_field *field, struct ctf_stream_pos *pos) { size_t i; int ret = 0; struct bt_ctf_field_structure *structure = container_of( field, struct bt_ctf_field_structure, parent); while (!ctf_pos_access_ok(pos, offset_align(pos->offset, field->type->declaration->alignment))) { ret = increase_packet_size(pos); if (ret) { goto end; } } if (!ctf_align_pos(pos, field->type->declaration->alignment)) { ret = -1; goto end; } for (i = 0; i < structure->fields->len; i++) { struct bt_ctf_field *field = g_ptr_array_index( structure->fields, i); ret = bt_ctf_field_serialize(field, pos); if (ret) { break; } } end: return ret; }
static int bt_ctf_field_variant_serialize(struct bt_ctf_field *field, struct ctf_stream_pos *pos) { struct bt_ctf_field_variant *variant = container_of( field, struct bt_ctf_field_variant, parent); return bt_ctf_field_serialize(variant->payload, pos); }
static int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *field, struct ctf_stream_pos *pos) { struct bt_ctf_field_enumeration *enumeration = container_of( field, struct bt_ctf_field_enumeration, parent); return bt_ctf_field_serialize(enumeration->payload, pos); }
BT_HIDDEN int bt_ctf_event_serialize(struct bt_ctf_event *event, struct ctf_stream_pos *pos) { int ret = 0; assert(event); assert(pos); if (event->context_payload) { ret = bt_ctf_field_serialize(event->context_payload, pos); if (ret) { goto end; } } if (event->fields_payload) { ret = bt_ctf_field_serialize(event->fields_payload, pos); if (ret) { goto end; } } end: return ret; }
static void stream_flush_cb(struct bt_ctf_stream *stream, struct bt_ctf_writer *writer) { struct bt_ctf_field *stream_id; /* Start a new packet in the stream */ if (stream->flushed_packet_count) { /* ctf_init_pos has already initialized the first packet */ ctf_packet_seek(&stream->pos.parent, 0, SEEK_CUR); } stream_id = bt_ctf_field_structure_get_field( writer->trace_packet_header, "stream_id"); bt_ctf_field_unsigned_integer_set_value(stream_id, stream->stream_class->id); bt_ctf_field_put(stream_id); /* Write the trace_packet_header */ bt_ctf_field_serialize(writer->trace_packet_header, &stream->pos); }
static int bt_ctf_field_sequence_serialize(struct bt_ctf_field *field, struct ctf_stream_pos *pos) { size_t i; int ret = 0; struct bt_ctf_field_sequence *sequence = container_of( field, struct bt_ctf_field_sequence, parent); for (i = 0; i < sequence->elements->len; i++) { ret = bt_ctf_field_serialize( g_ptr_array_index(sequence->elements, i), pos); if (ret) { goto end; } } 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, events_discarded; struct bt_ctf_field *integer = NULL; struct ctf_stream_pos packet_context_pos; if (!stream || stream->pos.fd < 0) { /* * Stream does not have an associated fd. It is, * therefore, not a stream being used to write events. */ ret = -1; goto end; } if (!stream->events->len) { goto end; } ret = bt_ctf_field_validate(stream->packet_header); if (ret) { goto end; } /* mmap the next packet */ ctf_packet_seek(&stream->pos.parent, 0, SEEK_CUR); ret = bt_ctf_field_serialize(stream->packet_header, &stream->pos); if (ret) { goto end; } /* Set the default context attributes if present and unset. */ if (!get_event_header_timestamp( ((struct bt_ctf_event *) g_ptr_array_index( stream->events, 0))->event_header, ×tamp_begin)) { ret = set_structure_field_integer(stream->packet_context, "timestamp_begin", timestamp_begin); if (ret) { goto end; } } if (!get_event_header_timestamp( ((struct bt_ctf_event *) g_ptr_array_index( stream->events, stream->events->len - 1))->event_header, ×tamp_end)) { ret = set_structure_field_integer(stream->packet_context, "timestamp_end", timestamp_end); if (ret) { goto end; } } ret = set_structure_field_integer(stream->packet_context, "content_size", UINT64_MAX); if (ret) { goto end; } ret = set_structure_field_integer(stream->packet_context, "packet_size", UINT64_MAX); if (ret) { goto end; } /* Write packet context */ memcpy(&packet_context_pos, &stream->pos, sizeof(struct ctf_stream_pos)); 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); ret = bt_ctf_field_reset(event->event_header); if (ret) { goto end; } /* Write event header */ ret = bt_ctf_field_serialize(event->event_header, &stream->pos); if (ret) { goto end; } /* Write stream event context */ if (stream->event_contexts) { ret = bt_ctf_field_serialize( g_ptr_array_index(stream->event_contexts, i), &stream->pos); if (ret) { goto end; } } /* Write event content */ ret = bt_ctf_event_serialize(event, &stream->pos); if (ret) { goto end; } } /* * Update the packet total size and content size and overwrite the * packet context. * Copy base_mma as the packet may have been remapped (e.g. when a * packet is resized). */ packet_context_pos.base_mma = stream->pos.base_mma; ret = set_structure_field_integer(stream->packet_context, "content_size", stream->pos.offset); if (ret) { goto end; } ret = set_structure_field_integer(stream->packet_context, "packet_size", stream->pos.packet_size); if (ret) { goto end; } ret = bt_ctf_field_serialize(stream->packet_context, &packet_context_pos); if (ret) { goto end; } g_ptr_array_set_size(stream->events, 0); if (stream->event_contexts) { g_ptr_array_set_size(stream->event_contexts, 0); } stream->flushed_packet_count++; end: bt_put(integer); return ret; }