static
int bt_ctf_field_sequence_reset(struct bt_ctf_field *field)
{
	size_t i;
	int ret = 0;
	struct bt_ctf_field_sequence *sequence;

	if (!field) {
		ret = -1;
		goto end;
	}

	sequence = container_of(field, struct bt_ctf_field_sequence, parent);
	for (i = 0; i < sequence->elements->len; i++) {
		struct bt_ctf_field *member = sequence->elements->pdata[i];

		if (!member) {
			/*
			 * Sequence elements are lazily initialized; skip if
			 * this member has not been allocated yet.
			 */
			continue;
		}

		ret = bt_ctf_field_reset(member);
		if (ret) {
			goto end;
		}
	}
end:
	return ret;
}
static
int bt_ctf_field_array_reset(struct bt_ctf_field *field)
{
	size_t i;
	int ret = 0;
	struct bt_ctf_field_array *array;

	if (!field) {
		ret = -1;
		goto end;
	}

	array = container_of(field, struct bt_ctf_field_array, parent);
	for (i = 0; i < array->elements->len; i++) {
		struct bt_ctf_field *member = array->elements->pdata[i];

		if (!member) {
			/*
			 * Array elements are lazily initialized; skip if
			 * this member has not been allocated yet.
			 */
			continue;
		}

		ret = bt_ctf_field_reset(member);
		if (ret) {
			goto end;
		}
	}
end:
	return ret;
}
static
int bt_ctf_field_variant_reset(struct bt_ctf_field *field)
{
	int ret = 0;
	struct bt_ctf_field_variant *variant;

	if (!field) {
		ret = -1;
		goto end;
	}

	variant = container_of(field, struct bt_ctf_field_variant, parent);
	if (variant->payload) {
		ret = bt_ctf_field_reset(variant->payload);
	}
end:
	return ret;
}
static
int bt_ctf_field_enumeration_reset(struct bt_ctf_field *field)
{
	int ret = 0;
	struct bt_ctf_field_enumeration *enumeration;

	if (!field) {
		ret = -1;
		goto end;
	}

	enumeration = container_of(field, struct bt_ctf_field_enumeration,
		parent);
	if (!enumeration->payload) {
		goto end;
	}

	ret = bt_ctf_field_reset(enumeration->payload);
end:
	return ret;
}
Exemple #5
0
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, &timestamp_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,
		&timestamp_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;
}