lib: bt_packet_create(): accept previous packet to set properties
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 8 Aug 2018 00:00:52 +0000 (20:00 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Thu, 2 May 2019 04:07:36 +0000 (00:07 -0400)
This patch changes the signature of the bt_packet_create() function
from:

    struct bt_packet *bt_packet_create(struct bt_stream *stream);

to:

    struct bt_packet *bt_packet_create(struct bt_stream *stream,
        enum bt_packet_previous_packet_availability prev_packet_avail,
        struct bt_packet *prev_packet);

bt_packet_create() now accepts the previous packet in the same stream
and its availability to automatically set some properties on the created
packet which depend on the properties of the previous packets. Those
properties are:

* The number of discarded events, by the original tracer, between the
  previous packet's end time and the current packet's end time.
* The number of discarded packets, by the original tracer, between the
  previous packet's end time and the current packet's end time.

"Automatically" here means from the packet's context subfields.

The availability parameter's purpose is to provide a reason for a
missing previous packet:

* Not available (will be used after seeking when this is implemented).
* None (first packet of its data stream).

When the previous packet is passed, you must pass
`BT_PACKET_PREVIOUS_PACKET_AVAILABILITY_AVAILABLE`.

bt_packet_create() does not keep a reference to the passed previous
packet object: this would create a potentially huge reference chain.
Instead, the function keeps snapshots the needed previous packet's
properties.

bt_packet_create() does not automatically set the created packet's
properties right away: this is the purpose of the internal
bt_packet_set_properties() function. This is because you borrow and set
the packet context subfields after you create the packet, so the
automatic setting must happen at the same location the packet would be
frozen in developer mode. Thus bt_notification_event_create(),
bt_notification_packet_begin_create(), and
bt_notification_packet_end_create() call bt_packet_set_properties().

bt_packet_set_properties() sets, from the context subfields, when
available:

* Discarded event _counter_ (free running counter, not the difference)
  from `events_discarded`.
* Sequence number from `packet_seq_num`.
* Default beginning clock value from `timestamp_begin`.
* Default end clock value from `timestamp_end`.

Because bt_notification_event_create() calls bt_packet_set_properties(),
and we don't want to do all this work every time we call
bt_notification_event_create(), there's a "validation" flag for the
property cache. So we can call bt_packet_set_properties() and
eventually, when we're sure that the context field won't change until
the packet is recycled (reset), we call
bt_packet_invalidate_properties().

Each packet property can be available or not: each property getter
returns its availability and the function sets a user variable to the
property's value. The getters are:

    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
    bt_packet_borrow_default_end_clock_value(struct bt_packet *packet,
        struct bt_clock_value **clock_value);

    enum bt_packet_property_availability
    bt_packet_borrow_previous_packet_default_end_clock_value(
        struct bt_packet *packet, struct bt_clock_value **clock_value);

    enum bt_packet_property_availability
    bt_packet_get_discarded_event_counter(
        struct bt_packet *packet, uint64_t *counter);

    enum bt_packet_property_availability
    bt_packet_get_sequence_number(
        struct bt_packet *packet, uint64_t *sequence_number);

    enum bt_packet_property_availability
    bt_packet_get_discarded_event_count(
        struct bt_packet *packet, uint64_t *count);

    enum bt_packet_property_availability
    bt_packet_get_discarded_packet_count(
        struct bt_packet *packet, uint64_t *count);

Source plugins are updated to keep the previous packet's reference when
needed and call bt_packet_create() correctly.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
include/babeltrace/ctf-ir/packet-internal.h
include/babeltrace/ctf-ir/packet.h
lib/ctf-ir/packet.c
lib/graph/notification/event.c
lib/graph/notification/packet.c
plugins/ctf/common/notif-iter/notif-iter.c
plugins/text/dmesg/dmesg.c
tests/lib/test_bt_notification_iterator.c
tests/plugins/test-utils-muxer.c

index 206215bf4ca2eb558ace535d6fcb073da378829e..759c371a38849e023f0c12d72f94c6a9eff6c202 100644 (file)
@@ -25,7 +25,9 @@
  * 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;
@@ -40,6 +47,33 @@ struct bt_packet {
        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;
 };
 
@@ -61,4 +95,30 @@ void bt_packet_recycle(struct bt_packet *packet);
 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 */
index e8ebf87953f6e6a1e5864aa18c974f2ba67e6527..6ff2fba8031a81f1d43a251c6bde5b6c551e9c9f 100644 (file)
@@ -106,6 +106,19 @@ struct bt_stream;
 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
 @{
@@ -125,7 +138,9 @@ bt_packet_set_header() and bt_packet_set_context().
 @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);
 
@@ -172,19 +187,40 @@ int bt_packet_move_context(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);
 
 /** @} */
 
index 9a9653061331b0e5fff9f21c110f6bfcc94cc375..939efa610867709e55a987cae66987ff4c851ae3 100644 (file)
@@ -88,6 +88,32 @@ void _bt_packet_set_is_frozen(struct bt_packet *packet, bool is_frozen)
        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)
 {
@@ -108,6 +134,13 @@ 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
@@ -271,17 +304,220 @@ struct bt_packet *bt_packet_new(struct bt_stream *stream)
                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: "
@@ -295,6 +531,19 @@ struct bt_packet *bt_packet_create(struct bt_stream *stream)
                        &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:
@@ -352,56 +601,90 @@ int bt_packet_move_context(struct bt_packet *packet,
        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;
 }
+
index c31694a625adbc533f14d16096509e4435195a8b..6251979d266a20f845334277302a1ea18077e725 100644 (file)
@@ -84,6 +84,7 @@ struct bt_notification *bt_notification_event_create(
        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");
@@ -103,6 +104,20 @@ struct bt_notification *bt_notification_event_create(
                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
@@ -129,6 +144,8 @@ struct bt_notification *bt_notification_event_create(
 
        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 ", "
index c5c6a6e5afff3e1b3f7da70e8302e909960268e9..552a99f1b1c6ec34c131092f2cfa264d06bcfab9 100644 (file)
@@ -69,10 +69,11 @@ struct bt_notification *bt_notification_packet_begin_create(
                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");
@@ -88,6 +89,16 @@ struct bt_notification *bt_notification_packet_begin_create(
                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(
@@ -101,6 +112,8 @@ struct bt_notification *bt_notification_packet_begin_create(
        notification->packet = packet;
        bt_object_get_no_null_check_no_parent_check(
                &notification->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\", "
@@ -189,10 +202,11 @@ struct bt_notification *bt_notification_packet_end_create(
                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");
@@ -208,6 +222,16 @@ struct bt_notification *bt_notification_packet_end_create(
                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(
@@ -221,6 +245,8 @@ struct bt_notification *bt_notification_packet_end_create(
        notification->packet = packet;
        bt_object_get_no_null_check_no_parent_check(
                &notification->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\", "
index 37317a0176e5f10ba5474c708d87152b4a697dcf..0c1d75728d3201a60c1953170c70a838c266aa8b 100644 (file)
@@ -171,6 +171,12 @@ struct bt_notif_iter {
        /* 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;
 
@@ -253,10 +259,6 @@ struct bt_notif_iter {
        /* 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).
@@ -1143,7 +1145,8 @@ enum bt_notif_iter_status set_current_packet(struct bt_notif_iter *notit)
 
        /* 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, "
@@ -1296,29 +1299,6 @@ end:
        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)
@@ -1406,8 +1386,6 @@ enum bt_notif_iter_status after_packet_context_state(
                goto end;
        }
 
-       set_current_packet_begin_end(notit);
-
        if (notit->stream_begin_emitted) {
                notit->state = STATE_EMIT_NOTIF_NEW_PACKET;
        } else {
@@ -2020,6 +1998,8 @@ void bt_notif_iter_reset(struct bt_notif_iter *notit)
        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);
@@ -2049,8 +2029,6 @@ void bt_notif_iter_reset(struct bt_notif_iter *notit)
        notit->cur_content_size = -1;
        notit->cur_packet_size = -1;
        notit->cur_packet_offset = -1;
-       reset_clock_value(&notit->cur_packet_begin_cv);
-       reset_clock_value(&notit->cur_packet_end_cv);
        notit->stream_begin_emitted = false;
        notit->cur_timestamp_end = NULL;
 }
@@ -2107,8 +2085,6 @@ int bt_notif_iter_switch_packet(struct bt_notif_iter *notit)
 
        notit->cur_content_size = -1;
        notit->cur_packet_size = -1;
-       reset_clock_value(&notit->cur_packet_begin_cv);
-       reset_clock_value(&notit->cur_packet_end_cv);
        notit->cur_sc_field_path_cache = NULL;
 
 end:
@@ -2922,30 +2898,6 @@ void notify_new_packet(struct bt_notif_iter *notit,
                        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);
@@ -2980,9 +2932,12 @@ void notify_end_of_packet(struct bt_notif_iter *notit,
                        "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;
 }
 
@@ -3125,6 +3080,7 @@ error:
 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);
 
index 8cb9539cdbb9bd06d70f2f923964306f7db03d43..ba5546af9a7e97dcfe5a7e27da984eff591616f8 100644 (file)
@@ -432,7 +432,8 @@ int create_packet_and_stream(struct dmesg_component *dmesg_comp)
                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;
index e70e51ea320d2944e2f3ac7346b6d03fd67c9833..f954aa6b0183289ea9eb9a3b60dc81d413b01c03 100644 (file)
@@ -321,13 +321,17 @@ void init_static_data(void)
        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) {
index 73f51e76660fb75d887f61d6e50a0deabc46f4e1..d7c582bba38318275251b5a2be52152b20fa3de6 100644 (file)
@@ -359,22 +359,26 @@ void init_static_data(void)
        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);
 
This page took 0.037936 seconds and 4 git commands to generate.