* SOFTWARE.
*/
+#include <stdbool.h>
#include <babeltrace/assert-internal.h>
+#include <babeltrace/ctf-ir/packet.h>
#include <babeltrace/ctf-ir/fields.h>
#include <babeltrace/ctf-ir/stream.h>
#include <babeltrace/ctf-ir/field-wrapper-internal.h>
#include <babeltrace/babeltrace-internal.h>
#include <babeltrace/ctf-ir/clock-value-set-internal.h>
+struct bt_packet_prop_uint64 {
+ enum bt_packet_property_availability avail;
+ uint64_t value;
+};
+
struct bt_packet {
struct bt_object base;
struct bt_field_wrapper *header;
struct bt_stream *stream;
struct bt_clock_value_set begin_cv_set;
struct bt_clock_value_set end_cv_set;
+ struct bt_packet_prop_uint64 discarded_event_counter;
+ struct bt_packet_prop_uint64 seq_num;
+ struct bt_packet_prop_uint64 discarded_event_count;
+ struct bt_packet_prop_uint64 discarded_packet_count;
+ bool props_are_set;
+
+ struct {
+ /*
+ * We keep this here to avoid keeping a reference on the
+ * previous packet object: those properties are
+ * snapshots of the previous packet's properties when
+ * calling bt_packet_create(). We know that the previous
+ * packet's properties do not change afterwards because
+ * we freeze the previous packet when bt_packet_create()
+ * is successful.
+ */
+ enum bt_packet_previous_packet_availability avail;
+ struct bt_packet_prop_uint64 discarded_event_counter;
+ struct bt_packet_prop_uint64 seq_num;
+ struct {
+ enum bt_packet_property_availability avail;
+
+ /* Owned by this (copy of previous packet's or NULL) */
+ struct bt_clock_value *cv;
+ } default_end_cv;
+ } prev_packet_info;
+
int frozen;
};
BT_HIDDEN
void bt_packet_destroy(struct bt_packet *packet);
+/*
+ * Sets a packet's properties using its current context fields and its
+ * previous packet's snapshotted properties (if any). The packet context
+ * field must not be modified until the packet is recycled.
+ *
+ * This function does NOT set the `props_are_set` flag (does not
+ * validate the properties): call bt_packet_validate_properties() to
+ * mark the properties as definitely cached.
+ */
+BT_HIDDEN
+int bt_packet_set_properties(struct bt_packet *packet);
+
+static inline
+void bt_packet_invalidate_properties(struct bt_packet *packet)
+{
+ BT_ASSERT(packet);
+ packet->props_are_set = false;
+}
+
+static inline
+void bt_packet_validate_properties(struct bt_packet *packet)
+{
+ BT_ASSERT(packet);
+ packet->props_are_set = true;
+}
+
#endif /* BABELTRACE_CTF_IR_PACKET_INTERNAL_H */
struct bt_clock_value;
struct bt_clock_class;
+enum bt_packet_previous_packet_availability {
+ BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_ERROR = -1,
+ BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_AVAILABLE,
+ BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_NOT_AVAILABLE,
+ BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_NONE,
+};
+
+enum bt_packet_property_availability {
+ BT_PACKET_PROPERTY_AVAILABILITY_ERROR = -1,
+ BT_PACKET_PROPERTY_AVAILABILITY_AVAILABLE,
+ BT_PACKET_PROPERTY_AVAILABILITY_NOT_AVAILABLE,
+};
+
/**
@name Creation and parent access functions
@{
@prenotnull{stream}
@postsuccessrefcountret1
*/
-extern struct bt_packet *bt_packet_create(struct bt_stream *stream);
+extern struct bt_packet *bt_packet_create(struct bt_stream *stream,
+ enum bt_packet_previous_packet_availability previous_packet_availability,
+ struct bt_packet *previous_packet);
extern struct bt_stream *bt_packet_borrow_stream(struct bt_packet *packet);
/** @} */
-extern int bt_packet_set_beginning_clock_value(struct bt_packet *packet,
- struct bt_clock_class *clock_class, uint64_t raw_value,
- bt_bool is_default);
+extern
+enum bt_packet_property_availability
+bt_packet_borrow_default_beginning_clock_value(struct bt_packet *packet,
+ struct bt_clock_value **clock_value);
-extern struct bt_clock_value *bt_packet_borrow_default_beginning_clock_value(
- struct bt_packet *packet);
+extern
+enum bt_packet_property_availability
+bt_packet_borrow_default_end_clock_value(struct bt_packet *packet,
+ struct bt_clock_value **clock_value);
-extern int bt_packet_set_end_clock_value(struct bt_packet *packet,
- struct bt_clock_class *clock_class, uint64_t raw_value,
- bt_bool is_default);
+extern
+enum bt_packet_previous_packet_availability
+bt_packet_get_previous_packet_availability(struct bt_packet *packet);
-extern struct bt_clock_value *bt_packet_borrow_default_end_clock_value(
- struct bt_packet *packet);
+extern
+enum bt_packet_property_availability
+bt_packet_borrow_previous_packet_default_end_clock_value(
+ struct bt_packet *packet, struct bt_clock_value **clock_value);
+
+extern
+enum bt_packet_property_availability bt_packet_get_discarded_event_counter(
+ struct bt_packet *packet, uint64_t *counter);
+
+extern
+enum bt_packet_property_availability bt_packet_get_sequence_number(
+ struct bt_packet *packet, uint64_t *sequence_number);
+
+extern
+enum bt_packet_property_availability bt_packet_get_discarded_event_count(
+ struct bt_packet *packet, uint64_t *count);
+
+extern
+enum bt_packet_property_availability bt_packet_get_discarded_packet_count(
+ struct bt_packet *packet, uint64_t *count);
/** @} */
packet->frozen = is_frozen;
}
+static inline
+void bt_packet_reset_avail(struct bt_packet *packet)
+{
+ /* Previous packet */
+ packet->prev_packet_info.avail =
+ BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_NOT_AVAILABLE;
+ packet->prev_packet_info.discarded_event_counter.avail =
+ BT_PACKET_PROPERTY_AVAILABILITY_NOT_AVAILABLE;
+ packet->prev_packet_info.seq_num.avail =
+ BT_PACKET_PROPERTY_AVAILABILITY_NOT_AVAILABLE;
+ packet->prev_packet_info.default_end_cv.avail =
+ BT_PACKET_PROPERTY_AVAILABILITY_NOT_AVAILABLE;
+
+ /* Current packet */
+ packet->discarded_event_counter.avail =
+ BT_PACKET_PROPERTY_AVAILABILITY_NOT_AVAILABLE;
+ packet->seq_num.avail =
+ BT_PACKET_PROPERTY_AVAILABILITY_NOT_AVAILABLE;
+
+ /* Computed */
+ packet->discarded_event_count.avail =
+ BT_PACKET_PROPERTY_AVAILABILITY_NOT_AVAILABLE;
+ packet->discarded_packet_count.avail =
+ BT_PACKET_PROPERTY_AVAILABILITY_NOT_AVAILABLE;
+}
+
static inline
void bt_packet_reset(struct bt_packet *packet)
{
bt_clock_value_set_reset(&packet->begin_cv_set);
bt_clock_value_set_reset(&packet->end_cv_set);
+ bt_packet_reset_avail(packet);
+ bt_packet_invalidate_properties(packet);
+
+ if (packet->prev_packet_info.default_end_cv.cv) {
+ bt_clock_value_recycle(packet->prev_packet_info.default_end_cv.cv);
+ packet->prev_packet_info.default_end_cv.cv = NULL;
+ }
}
static
goto end;
}
+ bt_packet_reset_avail(packet);
BT_LOGD("Created packet object: addr=%p", packet);
end:
return packet;
}
-struct bt_packet *bt_packet_create(struct bt_stream *stream)
+static inline
+uint64_t get_uint_field_value(struct bt_field *parent_field, const char *name)
+{
+ uint64_t val = UINT64_C(-1);
+ struct bt_field *field = bt_field_structure_borrow_field_by_name(
+ parent_field, name);
+ int ret;
+
+ if (!field) {
+ goto end;
+ }
+
+ BT_ASSERT(bt_field_is_integer(field));
+ BT_ASSERT(!bt_field_type_integer_is_signed(
+ bt_field_borrow_type(field)));
+ ret = bt_field_integer_unsigned_get_value(field, &val);
+ BT_ASSERT(ret == 0);
+
+end:
+ return val;
+}
+
+static inline
+void set_packet_prop_uint64(struct bt_packet_prop_uint64 *prop, uint64_t val)
+{
+ BT_ASSERT(prop);
+ prop->value = val;
+ prop->avail = BT_PACKET_PROPERTY_AVAILABILITY_AVAILABLE;
+}
+
+static inline
+int set_packet_default_clock_value(struct bt_field *pkt_ctx_field,
+ const char *field_name, struct bt_clock_value_set *cv_set)
+{
+ int ret = 0;
+ uint64_t val = UINT64_C(-1);
+ struct bt_field *field = bt_field_structure_borrow_field_by_name(
+ pkt_ctx_field, field_name);
+ struct bt_clock_class *clock_class;
+
+ if (!field) {
+ goto end;
+ }
+
+ BT_ASSERT(bt_field_is_integer(field));
+ BT_ASSERT(!bt_field_type_integer_is_signed(
+ bt_field_borrow_type(field)));
+ clock_class = bt_field_type_integer_borrow_mapped_clock_class(
+ bt_field_borrow_type(field));
+ if (!clock_class) {
+ goto end;
+ }
+
+ ret = bt_field_integer_unsigned_get_value(field, &val);
+ BT_ASSERT(ret == 0);
+ ret = bt_clock_value_set_set_clock_value(cv_set, clock_class,
+ val, true);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_packet_set_properties(struct bt_packet *packet)
+{
+ struct bt_field *pkt_context_field;
+ uint64_t val;
+ int ret = 0;
+
+ BT_ASSERT(!packet->props_are_set);
+
+ pkt_context_field = bt_packet_borrow_context(packet);
+ if (!pkt_context_field) {
+ goto end;
+ }
+
+ /* Discarded event counter */
+ val = get_uint_field_value(pkt_context_field, "events_discarded");
+ if (val != UINT64_C(-1)) {
+ set_packet_prop_uint64(&packet->discarded_event_counter, val);
+ }
+
+ /* Sequence number */
+ val = get_uint_field_value(pkt_context_field, "packet_seq_num");
+ if (val != UINT64_C(-1)) {
+ set_packet_prop_uint64(&packet->seq_num, val);
+ }
+
+ /* Beginning and end times */
+ ret = set_packet_default_clock_value(pkt_context_field,
+ "timestamp_begin", &packet->begin_cv_set);
+ if (ret) {
+ goto end;
+ }
+
+ ret = set_packet_default_clock_value(pkt_context_field,
+ "timestamp_end", &packet->end_cv_set);
+ if (ret) {
+ goto end;
+ }
+
+ /* Information from previous packet */
+ if (packet->prev_packet_info.avail ==
+ BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_AVAILABLE) {
+ /* Discarded event count */
+ if (packet->prev_packet_info.discarded_event_counter.avail ==
+ BT_PACKET_PROPERTY_AVAILABILITY_AVAILABLE) {
+ BT_ASSERT(packet->discarded_event_counter.avail ==
+ BT_PACKET_PROPERTY_AVAILABILITY_AVAILABLE);
+ set_packet_prop_uint64(&packet->discarded_event_count,
+ packet->discarded_event_counter.value -
+ packet->prev_packet_info.discarded_event_counter.value);
+ }
+
+ /* Discarded packet count */
+ if (packet->prev_packet_info.seq_num.avail ==
+ BT_PACKET_PROPERTY_AVAILABILITY_AVAILABLE) {
+ BT_ASSERT(packet->seq_num.avail ==
+ BT_PACKET_PROPERTY_AVAILABILITY_AVAILABLE);
+ set_packet_prop_uint64(&packet->discarded_packet_count,
+ packet->seq_num.value -
+ packet->prev_packet_info.seq_num.value - 1);
+ }
+ }
+
+end:
+ return ret;
+}
+
+static
+int snapshot_prev_packet_properties(struct bt_packet *packet,
+ enum bt_packet_previous_packet_availability prev_packet_avail,
+ struct bt_packet *prev_packet)
+{
+ int ret = 0;
+ struct bt_clock_value *prev_packet_default_end_cv;
+
+ if (!prev_packet) {
+ goto end;
+ }
+
+ if (!prev_packet->props_are_set) {
+ ret = bt_packet_set_properties(prev_packet);
+ if (ret) {
+ BT_LIB_LOGE("Cannot update previous packet's properties: "
+ "%![prev-packet-]+a", prev_packet);
+ goto end;
+ }
+ }
+
+ packet->prev_packet_info.avail = prev_packet_avail;
+ prev_packet_default_end_cv = prev_packet->end_cv_set.default_cv;
+
+ /* End time */
+ if (prev_packet_default_end_cv) {
+ /* Copy clock value */
+ packet->prev_packet_info.default_end_cv.cv =
+ bt_clock_value_create(
+ prev_packet_default_end_cv->clock_class);
+ if (!packet->prev_packet_info.default_end_cv.cv) {
+ BT_LIB_LOGE("Cannot create a clock value from a clock class: "
+ "%![cc-]+K",
+ prev_packet_default_end_cv->clock_class);
+ ret = -1;
+ goto end;
+ }
+
+ bt_clock_value_set_raw_value(
+ packet->prev_packet_info.default_end_cv.cv,
+ prev_packet_default_end_cv->value);
+ packet->prev_packet_info.default_end_cv.avail =
+ BT_PACKET_PROPERTY_AVAILABILITY_AVAILABLE;
+ }
+
+ /* Discarded event counter */
+ packet->prev_packet_info.discarded_event_counter =
+ prev_packet->discarded_event_counter;
+
+ /* Sequence number */
+ packet->prev_packet_info.seq_num = prev_packet->seq_num;
+
+end:
+ return ret;
+}
+
+struct bt_packet *bt_packet_create(struct bt_stream *stream,
+ enum bt_packet_previous_packet_availability prev_packet_avail,
+ struct bt_packet *prev_packet)
{
struct bt_packet *packet = NULL;
+ int ret;
BT_ASSERT_PRE_NON_NULL(stream, "Stream");
+ BT_ASSERT_PRE(!prev_packet || prev_packet->stream == stream,
+ "New packet's and previous packet's stream are not the same: "
+ "%![new-packet-stream-]+s, %![prev-packet]+a, "
+ "%![prev-packet-stream]+s", stream, prev_packet,
+ prev_packet->stream);
+ BT_ASSERT_PRE(
+ prev_packet_avail == BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_AVAILABLE ||
+ prev_packet_avail == BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_NOT_AVAILABLE ||
+ prev_packet_avail == BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_NONE,
+ "Invalid previous packet availability value: val=%d",
+ prev_packet_avail);
+ BT_ASSERT_PRE(!prev_packet ||
+ prev_packet_avail == BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_AVAILABLE,
+ "Previous packet is available, but previous packet is NULL.");
packet = bt_object_pool_create_object(&stream->packet_pool);
if (unlikely(!packet)) {
BT_LIB_LOGE("Cannot allocate one packet from stream's packet pool: "
&packet->stream->common.base);
}
+ ret = snapshot_prev_packet_properties(packet, prev_packet_avail,
+ prev_packet);
+ if (ret) {
+ /* Recycle */
+ BT_PUT(packet);
+ goto end;
+ }
+
+ if (prev_packet) {
+ bt_packet_validate_properties(prev_packet);
+ bt_packet_set_is_frozen(prev_packet, true);
+ }
+
goto end;
end:
return 0;
}
-int bt_packet_set_beginning_clock_value(struct bt_packet *packet,
- struct bt_clock_class *clock_class, uint64_t raw_value,
- bt_bool is_default)
+enum bt_packet_property_availability
+bt_packet_borrow_default_beginning_clock_value(struct bt_packet *packet,
+ struct bt_clock_value **clock_value)
{
+ enum bt_packet_property_availability avail =
+ BT_PACKET_PROPERTY_AVAILABILITY_AVAILABLE;
+
BT_ASSERT_PRE_NON_NULL(packet, "Packet");
- BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
- BT_ASSERT_PRE_HOT(packet, "Packet", ": %!+a", packet);
- BT_ASSERT_PRE(is_default,
- "You can only set a default clock value as of this version.");
- return bt_clock_value_set_set_clock_value(&packet->begin_cv_set,
- clock_class, raw_value, is_default);
+ BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value");
+ *clock_value = packet->begin_cv_set.default_cv;
+ if (!*clock_value) {
+ avail = BT_PACKET_PROPERTY_AVAILABILITY_NOT_AVAILABLE;
+ }
+
+ return avail;
}
-struct bt_clock_value *bt_packet_borrow_default_begin_clock_value(
- struct bt_packet *packet)
+enum bt_packet_property_availability
+bt_packet_borrow_default_end_clock_value(struct bt_packet *packet,
+ struct bt_clock_value **clock_value)
{
- struct bt_clock_value *clock_value = NULL;
+ enum bt_packet_property_availability avail =
+ BT_PACKET_PROPERTY_AVAILABILITY_AVAILABLE;
BT_ASSERT_PRE_NON_NULL(packet, "Packet");
- clock_value = packet->begin_cv_set.default_cv;
- if (!clock_value) {
- BT_LIB_LOGV("No default clock value: %![packet-]+a", packet);
+ BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value");
+ *clock_value = packet->end_cv_set.default_cv;
+ if (!*clock_value) {
+ avail = BT_PACKET_PROPERTY_AVAILABILITY_NOT_AVAILABLE;
}
- return clock_value;
+ return avail;
}
-int bt_packet_set_end_clock_value(struct bt_packet *packet,
- struct bt_clock_class *clock_class, uint64_t raw_value,
- bt_bool is_default)
+enum bt_packet_previous_packet_availability
+bt_packet_get_previous_packet_availability(struct bt_packet *packet)
{
BT_ASSERT_PRE_NON_NULL(packet, "Packet");
- BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
- BT_ASSERT_PRE_HOT(packet, "Packet", ": %!+a", packet);
- BT_ASSERT_PRE(is_default,
- "You can only set a default clock value as of this version.");
- return bt_clock_value_set_set_clock_value(&packet->end_cv_set,
- clock_class, raw_value, is_default);
+ return packet->prev_packet_info.avail;
+}
+
+enum bt_packet_property_availability
+bt_packet_borrow_previous_packet_default_end_clock_value(
+ struct bt_packet *packet, struct bt_clock_value **clock_value)
+{
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value");
+ *clock_value = packet->prev_packet_info.default_end_cv.cv;
+ return packet->prev_packet_info.default_end_cv.avail;
}
-struct bt_clock_value *bt_packet_borrow_default_end_clock_value(
- struct bt_packet *packet)
+enum bt_packet_property_availability bt_packet_get_discarded_event_counter(
+ struct bt_packet *packet, uint64_t *counter)
{
- struct bt_clock_value *clock_value = NULL;
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ BT_ASSERT_PRE_NON_NULL(counter, "Counter");
+ *counter = packet->discarded_event_counter.value;
+ return packet->discarded_event_counter.avail;
+}
+enum bt_packet_property_availability bt_packet_get_sequence_number(
+ struct bt_packet *packet, uint64_t *sequence_number)
+{
BT_ASSERT_PRE_NON_NULL(packet, "Packet");
- clock_value = packet->end_cv_set.default_cv;
- if (!clock_value) {
- BT_LIB_LOGV("No default clock value: %![packet-]+a", packet);
- }
+ BT_ASSERT_PRE_NON_NULL(sequence_number, "Sequence number");
+ *sequence_number = packet->seq_num.value;
+ return packet->seq_num.avail;
+}
- return clock_value;
+enum bt_packet_property_availability bt_packet_get_discarded_event_count(
+ struct bt_packet *packet, uint64_t *count)
+{
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ BT_ASSERT_PRE_NON_NULL(count, "Count");
+ *count = packet->discarded_event_count.value;
+ return packet->discarded_event_count.avail;
+}
+
+enum bt_packet_property_availability bt_packet_get_discarded_packet_count(
+ struct bt_packet *packet, uint64_t *count)
+{
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ BT_ASSERT_PRE_NON_NULL(count, "Count");
+ *count = packet->discarded_packet_count.value;
+ return packet->discarded_packet_count.avail;
}
+
struct bt_notification_event *notification = NULL;
struct bt_event *event;
struct bt_graph *graph;
+ int ret;
BT_ASSERT_PRE_NON_NULL(notif_iter, "Notification iterator");
BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
goto error;
}
+ /*
+ * Set packet's properties. This can fail so it happens before
+ * creating the notification below. We freeze it after we know
+ * this function succeeds.
+ */
+ if (unlikely(!packet->props_are_set)) {
+ ret = bt_packet_set_properties(packet);
+ if (ret) {
+ BT_LIB_LOGE("Cannot update packet's properties: "
+ "%![prev-packet-]+a", packet);
+ goto error;
+ }
+ }
+
/*
* Create notification from pool _after_ we have everything
* (in this case, a valid event object) so that we never have an
BT_ASSERT(!notification->event);
notification->event = event;
+ bt_packet_set_is_frozen(packet, true);
+ bt_packet_validate_properties(packet);
BT_LOGD("Created event notification object: "
"event-addr=%p, event-class-addr=%p, "
"event-class-name=\"%s\", event-class-id=%" PRId64 ", "
struct bt_private_connection_private_notification_iterator *notif_iter,
struct bt_packet *packet)
{
- struct bt_notification_packet_begin *notification;
+ struct bt_notification_packet_begin *notification = NULL;
struct bt_stream *stream;
struct bt_stream_class *stream_class;
struct bt_graph *graph;
+ int ret;
BT_ASSERT_PRE_NON_NULL(notif_iter, "Notification iterator");
BT_ASSERT_PRE_NON_NULL(packet, "Packet");
stream_class,
bt_stream_class_get_name(stream_class),
bt_stream_class_get_id(stream_class));
+
+ if (likely(!packet->props_are_set)) {
+ ret = bt_packet_set_properties(packet);
+ if (ret) {
+ BT_LIB_LOGE("Cannot update packet's properties: "
+ "%![prev-packet-]+a", packet);
+ goto end;
+ }
+ }
+
graph = bt_private_connection_private_notification_iterator_borrow_graph(
notif_iter);
notification = (void *) bt_notification_create_from_pool(
notification->packet = packet;
bt_object_get_no_null_check_no_parent_check(
¬ification->packet->base);
+ bt_packet_set_is_frozen(packet, true);
+ bt_packet_validate_properties(packet);
BT_LOGD("Created packet beginning notification object: "
"packet-addr=%p, stream-addr=%p, stream-name=\"%s\", "
"stream-class-addr=%p, stream-class-name=\"%s\", "
struct bt_private_connection_private_notification_iterator *notif_iter,
struct bt_packet *packet)
{
- struct bt_notification_packet_end *notification;
+ struct bt_notification_packet_end *notification = NULL;
struct bt_stream *stream;
struct bt_stream_class *stream_class;
struct bt_graph *graph;
+ int ret;
BT_ASSERT_PRE_NON_NULL(notif_iter, "Notification iterator");
BT_ASSERT_PRE_NON_NULL(packet, "Packet");
stream_class,
bt_stream_class_get_name(stream_class),
bt_stream_class_get_id(stream_class));
+
+ if (unlikely(!packet->props_are_set)) {
+ ret = bt_packet_set_properties(packet);
+ if (ret) {
+ BT_LIB_LOGE("Cannot update packet's properties: "
+ "%![prev-packet-]+a", packet);
+ goto end;
+ }
+ }
+
graph = bt_private_connection_private_notification_iterator_borrow_graph(
notif_iter);
notification = (void *) bt_notification_create_from_pool(
notification->packet = packet;
bt_object_get_no_null_check_no_parent_check(
¬ification->packet->base);
+ bt_packet_set_is_frozen(packet, true);
+ bt_packet_validate_properties(packet);
BT_LOGD("Created packet end notification object: "
"packet-addr=%p, stream-addr=%p, stream-name=\"%s\", "
"stream-class-addr=%p, stream-class-name=\"%s\", "
/* Current packet (NULL if not created yet) */
struct bt_packet *packet;
+ /* Previous packet availability */
+ enum bt_packet_previous_packet_availability prev_packet_avail;
+
+ /* Previous packet (NULL if not available) */
+ struct bt_packet *prev_packet;
+
/* Current stream (NULL if not set yet) */
struct bt_stream *stream;
/* Current content size (bits) (-1 if unknown) */
int64_t cur_content_size;
- /* Current packet default beginning and end clock values */
- struct clock_value cur_packet_begin_cv;
- struct clock_value cur_packet_end_cv;
-
/*
* Offset, in the underlying media, of the current packet's start
* (-1 if unknown).
/* Create packet */
BT_ASSERT(notit->stream);
- packet = bt_packet_create(notit->stream);
+ packet = bt_packet_create(notit->stream, notit->prev_packet_avail,
+ notit->prev_packet);
if (!packet) {
BT_LOGE("Cannot create packet from stream: "
"notit-addr=%p, stream-addr=%p, "
return val;
}
-static
-void set_current_packet_begin_end(struct bt_notif_iter *notit)
-{
- struct bt_clock_class *clock_class;
- uint64_t val;
-
- if (!notit->dscopes.stream_packet_context) {
- goto end;
- }
-
- val = get_field_raw_clock_value(notit->dscopes.stream_packet_context,
- "timestamp_begin", &clock_class);
- notit->cur_packet_begin_cv.clock_class = clock_class;
- notit->cur_packet_begin_cv.raw_value = val;
- val = get_field_raw_clock_value(notit->dscopes.stream_packet_context,
- "timestamp_end", &clock_class);
- notit->cur_packet_end_cv.clock_class = clock_class;
- notit->cur_packet_end_cv.raw_value = val;
-
-end:
- return;
-}
-
static
enum bt_notif_iter_status set_current_packet_content_sizes(
struct bt_notif_iter *notit)
goto end;
}
- set_current_packet_begin_end(notit);
-
if (notit->stream_begin_emitted) {
notit->state = STATE_EMIT_NOTIF_NEW_PACKET;
} else {
notit->meta.stream_class = NULL;
notit->meta.event_class = NULL;
BT_PUT(notit->packet);
+ notit->prev_packet_avail = BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_NONE;
+ BT_PUT(notit->prev_packet);
BT_PUT(notit->stream);
BT_PUT(notit->event_notif);
release_all_dscopes(notit);
notit->cur_content_size = -1;
notit->cur_packet_size = -1;
notit->cur_packet_offset = -1;
- reset_clock_value(¬it->cur_packet_begin_cv);
- reset_clock_value(¬it->cur_packet_end_cv);
notit->stream_begin_emitted = false;
notit->cur_timestamp_end = NULL;
}
notit->cur_content_size = -1;
notit->cur_packet_size = -1;
- reset_clock_value(¬it->cur_packet_begin_cv);
- reset_clock_value(¬it->cur_packet_end_cv);
notit->cur_sc_field_path_cache = NULL;
end:
notit->dscopes.stream_packet_context);
}
- if (notit->cur_packet_begin_cv.clock_class) {
- ret = bt_packet_set_beginning_clock_value(notit->packet,
- notit->cur_packet_begin_cv.clock_class,
- notit->cur_packet_begin_cv.raw_value, BT_TRUE);
- if (ret) {
- BT_LOGE("Cannot set packet's default beginning clock value: "
- "notit-addr=%p, packet-addr=%p",
- notit, notit->packet);
- goto end;
- }
- }
-
- if (notit->cur_packet_end_cv.clock_class) {
- ret = bt_packet_set_end_clock_value(notit->packet,
- notit->cur_packet_end_cv.clock_class,
- notit->cur_packet_end_cv.raw_value, BT_TRUE);
- if (ret) {
- BT_LOGE("Cannot set packet's default end clock value: "
- "notit-addr=%p, packet-addr=%p",
- notit, notit->packet);
- goto end;
- }
- }
-
BT_ASSERT(notit->notif_iter);
notif = bt_notification_packet_begin_create(notit->notif_iter,
notit->packet);
"notit-addr=%p, packet-addr=%p",
notit, notit->packet);
return;
+
}
- BT_PUT(notit->packet);
+ BT_MOVE(notit->prev_packet, notit->packet);
+ notit->prev_packet_avail =
+ BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_AVAILABLE;
*notification = notif;
}
void bt_notif_iter_destroy(struct bt_notif_iter *notit)
{
BT_PUT(notit->packet);
+ BT_PUT(notit->prev_packet);
BT_PUT(notit->stream);
release_all_dscopes(notit);
goto error;
}
- dmesg_comp->packet = bt_packet_create(dmesg_comp->stream);
+ dmesg_comp->packet = bt_packet_create(dmesg_comp->stream,
+ BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_NONE, NULL);
if (!dmesg_comp->packet) {
BT_LOGE_STR("Cannot create packet object.");
goto error;
BT_ASSERT(src_stream1);
src_stream2 = bt_stream_create(src_stream_class, "stream-2", 1);
BT_ASSERT(src_stream2);
- src_stream1_packet1 = bt_packet_create(src_stream1);
+ src_stream1_packet1 = bt_packet_create(src_stream1,
+ BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_NONE, NULL);
BT_ASSERT(src_stream1_packet1);
- src_stream1_packet2 = bt_packet_create(src_stream1);
+ src_stream1_packet2 = bt_packet_create(src_stream1,
+ BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_NONE, NULL);
BT_ASSERT(src_stream1_packet2);
- src_stream2_packet1 = bt_packet_create(src_stream2);
+ src_stream2_packet1 = bt_packet_create(src_stream2,
+ BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_NONE, NULL);
BT_ASSERT(src_stream2_packet1);
- src_stream2_packet2 = bt_packet_create(src_stream2);
+ src_stream2_packet2 = bt_packet_create(src_stream2,
+ BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_NONE, NULL);
BT_ASSERT(src_stream2_packet2);
if (debug) {
BT_ASSERT(ret == 0);
stream = bt_stream_create(src_stream_class, "stream0", 0);
BT_ASSERT(stream);
- src_packet0 = bt_packet_create(stream);
+ src_packet0 = bt_packet_create(stream,
+ BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_NONE, NULL);
BT_ASSERT(src_packet0);
bt_put(stream);
stream = bt_stream_create(src_stream_class, "stream1", 1);
BT_ASSERT(stream);
- src_packet1 = bt_packet_create(stream);
+ src_packet1 = bt_packet_create(stream,
+ BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_NONE, NULL);
BT_ASSERT(src_packet0);
bt_put(stream);
stream = bt_stream_create(src_stream_class, "stream2", 2);
BT_ASSERT(stream);
- src_packet2 = bt_packet_create(stream);
+ src_packet2 = bt_packet_create(stream,
+ BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_NONE, NULL);
BT_ASSERT(src_packet0);
bt_put(stream);
stream = bt_stream_create(src_stream_class, "stream3", 3);
BT_ASSERT(stream);
- src_packet3 = bt_packet_create(stream);
+ src_packet3 = bt_packet_create(stream,
+ BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_NONE, NULL);
BT_ASSERT(src_packet0);
bt_put(stream);