- struct bt_clock_class *clock_class = clock_value->clock_class;
- int64_t diff;
- int64_t s_ns;
- uint64_t u_ns;
- uint64_t cycles;
-
- /* Initialize nanosecond timestamp to clock's offset in seconds */
- if (clock_class->offset_s <= (INT64_MIN / 1000000000) ||
- clock_class->offset_s >= (INT64_MAX / 1000000000)) {
- /*
- * Overflow: offset in seconds converted to nanoseconds
- * is outside the int64_t range.
- */
- clock_value->ns_from_epoch_overflows = true;
- goto end;
- }
-
- clock_value->ns_from_epoch = clock_class->offset_s * (int64_t) 1000000000;
-
- /* Add offset in cycles */
- if (clock_class->offset < 0) {
- cycles = (uint64_t) (-clock_class->offset);
- } else {
- cycles = (uint64_t) clock_class->offset;
- }
-
- u_ns = ns_from_value(clock_class->frequency, cycles);
-
- if (u_ns == -1ULL || u_ns >= INT64_MAX) {
- /*
- * Overflow: offset in cycles converted to nanoseconds
- * is outside the int64_t range.
- */
- clock_value->ns_from_epoch_overflows = true;
- goto end;
- }
-
- s_ns = (int64_t) u_ns;
- assert(s_ns >= 0);
-
- if (clock_class->offset < 0) {
- if (clock_value->ns_from_epoch >= 0) {
- /*
- * Offset in cycles is negative so it must also
- * be negative once converted to nanoseconds.
- */
- s_ns = -s_ns;
- goto offset_ok;
- }
-
- diff = clock_value->ns_from_epoch - INT64_MIN;
-
- if (s_ns >= diff) {
- /*
- * Overflow: current timestamp in nanoseconds
- * plus the offset in cycles converted to
- * nanoseconds is outside the int64_t range.
- */
- clock_value->ns_from_epoch_overflows = true;
- goto end;
- }
-
- /*
- * Offset in cycles is negative so it must also be
- * negative once converted to nanoseconds.
- */
- s_ns = -s_ns;
- } else {
- if (clock_value->ns_from_epoch <= 0) {
- goto offset_ok;
- }
-
- diff = INT64_MAX - clock_value->ns_from_epoch;
-
- if (s_ns >= diff) {
- /*
- * Overflow: current timestamp in nanoseconds
- * plus the offset in cycles converted to
- * nanoseconds is outside the int64_t range.
- */
- clock_value->ns_from_epoch_overflows = true;
- goto end;
- }
- }
-
-offset_ok:
- clock_value->ns_from_epoch += s_ns;
-
- /* Add clock value (cycles) */
- u_ns = ns_from_value(clock_class->frequency, clock_value->value);
-
- if (u_ns == -1ULL || u_ns >= INT64_MAX) {
- /*
- * Overflow: value converted to nanoseconds is outside
- * the int64_t range.
- */
- clock_value->ns_from_epoch_overflows = true;
- goto end;
- }
-
- s_ns = (int64_t) u_ns;
- assert(s_ns >= 0);
-
- /* Clock value (cycles) is always positive */
- if (clock_value->ns_from_epoch <= 0) {
- goto value_ok;
- }
-
- diff = INT64_MAX - clock_value->ns_from_epoch;
-
- if (s_ns >= diff) {
- /*
- * Overflow: current timestamp in nanoseconds plus the
- * clock value converted to nanoseconds is outside the
- * int64_t range.
- */
- clock_value->ns_from_epoch_overflows = true;
- goto end;
- }
-
-value_ok:
- clock_value->ns_from_epoch += s_ns;
-
-end:
- if (clock_value->ns_from_epoch_overflows) {
- clock_value->ns_from_epoch = 0;
- }
-}
-
-struct bt_clock_value *bt_clock_value_create(
- struct bt_clock_class *clock_class, uint64_t value)
-{
- struct bt_clock_value *ret = NULL;
-
- BT_LOGD("Creating clock value object: clock-class-addr=%p, "
- "clock-class-name=\"%s\", value=%" PRIu64, clock_class,
- bt_clock_class_get_name(clock_class), value);
-
- if (!clock_class) {
- BT_LOGW_STR("Invalid parameter: clock class is NULL.");
- goto end;
- }
-
- ret = g_new0(struct bt_clock_value, 1);
- if (!ret) {
- BT_LOGE_STR("Failed to allocate one clock value.");
- goto end;
- }
-
- bt_object_init(ret, bt_clock_value_destroy);
- ret->clock_class = bt_get(clock_class);
- ret->value = value;
- set_ns_from_epoch(ret);
- bt_clock_class_freeze(clock_class);
- BT_LOGD("Created clock value object: clock-value-addr=%p, "
- "clock-class-addr=%p, clock-class-name=\"%s\", "
- "ns-from-epoch=%" PRId64 ", ns-from-epoch-overflows=%d",
- ret, clock_class, bt_clock_class_get_name(clock_class),
- ret->ns_from_epoch, ret->ns_from_epoch_overflows);
-
-end:
- return ret;
-}
-
-int bt_clock_value_get_value(
- struct bt_clock_value *clock_value, uint64_t *raw_value)
-{
- int ret = 0;
-
- if (!clock_value || !raw_value) {
- BT_LOGW("Invalid parameter: clock value or raw value is NULL: "
- "clock-value-addr=%p, raw-value-addr=%p",
- clock_value, raw_value);
- ret = -1;
- goto end;
- }
-
- *raw_value = clock_value->value;
-end:
- return ret;
-}
-
-int bt_clock_value_get_value_ns_from_epoch(struct bt_clock_value *value,
- int64_t *ret_value_ns)
-{
- int ret = 0;
-
- if (!value || !ret_value_ns) {
- BT_LOGW("Invalid parameter: clock value or return value pointer is NULL: "
- "clock-value-addr=%p, ret-value-addr=%p",
- value, ret_value_ns);
- ret = -1;
- goto end;
- }
-
- if (value->ns_from_epoch_overflows) {
- BT_LOGW("Clock value converted to nanoseconds from Epoch overflows the signed 64-bit integer range: "
- "clock-value-addr=%p, "
- "clock-class-offset-s=%" PRId64 ", "
- "clock-class-offset-cycles=%" PRId64 ", "
- "value=%" PRIu64,
- value, value->clock_class->offset_s,
- value->clock_class->offset,
- value->value);
- ret = -1;
- goto end;
- }
-
- *ret_value_ns = value->ns_from_epoch;
-
-end:
- return ret;
-}
-
-struct bt_clock_class *bt_clock_value_get_class(
- struct bt_clock_value *clock_value)
-{
- struct bt_clock_class *clock_class = NULL;
-
- if (!clock_value) {
- BT_LOGW_STR("Invalid parameter: clock value is NULL.");
- goto end;
- }
-
- clock_class = bt_get(clock_value->clock_class);
-
-end:
- return clock_class;
-}
-
-BT_HIDDEN
-int bt_clock_class_compare(struct bt_clock_class *clock_class_a,
- struct bt_clock_class *clock_class_b)
-{
- int ret = 1;
- assert(clock_class_a);
- assert(clock_class_b);
-
- /* Name */
- if (strcmp(clock_class_a->name->str, clock_class_b->name->str) != 0) {
- BT_LOGV("Clock classes differ: different names: "
- "cc-a-name=\"%s\", cc-b-name=\"%s\"",
- clock_class_a->name->str,
- clock_class_b->name->str);
- goto end;
- }
-
- /* Description */
- if (clock_class_a->description) {
- if (!clock_class_b->description) {
- BT_LOGV_STR("Clock classes differ: clock class A has a "
- "description, but clock class B does not.");
- goto end;
- }
-
- if (strcmp(clock_class_a->name->str, clock_class_b->name->str)
- != 0) {
- BT_LOGV("Clock classes differ: different descriptions: "
- "cc-a-descr=\"%s\", cc-b-descr=\"%s\"",
- clock_class_a->description->str,
- clock_class_b->description->str);
- goto end;
- }
- } else {
- if (clock_class_b->description) {
- BT_LOGV_STR("Clock classes differ: clock class A has "
- "no description, but clock class B has one.");
- goto end;
- }
- }
-
- /* Frequency */
- if (clock_class_a->frequency != clock_class_b->frequency) {
- BT_LOGV("Clock classes differ: different frequencies: "
- "cc-a-freq=%" PRIu64 ", cc-b-freq=%" PRIu64,
- clock_class_a->frequency,
- clock_class_b->frequency);
- goto end;
- }
-
- /* Precision */
- if (clock_class_a->precision != clock_class_b->precision) {
- BT_LOGV("Clock classes differ: different precisions: "
- "cc-a-freq=%" PRIu64 ", cc-b-freq=%" PRIu64,
- clock_class_a->precision,
- clock_class_b->precision);
- goto end;
- }
-
- /* Offset (seconds) */
- if (clock_class_a->offset_s != clock_class_b->offset_s) {
- BT_LOGV("Clock classes differ: different offsets (seconds): "
- "cc-a-offset-s=%" PRId64 ", cc-b-offset-s=%" PRId64,
- clock_class_a->offset_s,
- clock_class_b->offset_s);
- goto end;
- }
-
- /* Offset (cycles) */
- if (clock_class_a->offset != clock_class_b->offset) {
- BT_LOGV("Clock classes differ: different offsets (cycles): "
- "cc-a-offset-s=%" PRId64 ", cc-b-offset-s=%" PRId64,
- clock_class_a->offset,
- clock_class_b->offset);
- goto end;
- }
-
- /* UUIDs */
- if (clock_class_a->uuid_set) {
- if (!clock_class_b->uuid_set) {
- BT_LOGV_STR("Clock classes differ: clock class A has a "
- "UUID, but clock class B does not.");
- goto end;
- }
-
- if (memcmp(clock_class_a->uuid, clock_class_b->uuid,
- BABELTRACE_UUID_LEN) != 0) {
- BT_LOGV("Clock classes differ: different UUIDs: "
- "cc-a-uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\", "
- "cc-b-uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"",
- (unsigned int) clock_class_a->uuid[0],
- (unsigned int) clock_class_a->uuid[1],
- (unsigned int) clock_class_a->uuid[2],
- (unsigned int) clock_class_a->uuid[3],
- (unsigned int) clock_class_a->uuid[4],
- (unsigned int) clock_class_a->uuid[5],
- (unsigned int) clock_class_a->uuid[6],
- (unsigned int) clock_class_a->uuid[7],
- (unsigned int) clock_class_a->uuid[8],
- (unsigned int) clock_class_a->uuid[9],
- (unsigned int) clock_class_a->uuid[10],
- (unsigned int) clock_class_a->uuid[11],
- (unsigned int) clock_class_a->uuid[12],
- (unsigned int) clock_class_a->uuid[13],
- (unsigned int) clock_class_a->uuid[14],
- (unsigned int) clock_class_a->uuid[15],
- (unsigned int) clock_class_b->uuid[0],
- (unsigned int) clock_class_b->uuid[1],
- (unsigned int) clock_class_b->uuid[2],
- (unsigned int) clock_class_b->uuid[3],
- (unsigned int) clock_class_b->uuid[4],
- (unsigned int) clock_class_b->uuid[5],
- (unsigned int) clock_class_b->uuid[6],
- (unsigned int) clock_class_b->uuid[7],
- (unsigned int) clock_class_b->uuid[8],
- (unsigned int) clock_class_b->uuid[9],
- (unsigned int) clock_class_b->uuid[10],
- (unsigned int) clock_class_b->uuid[11],
- (unsigned int) clock_class_b->uuid[12],
- (unsigned int) clock_class_b->uuid[13],
- (unsigned int) clock_class_b->uuid[14],
- (unsigned int) clock_class_b->uuid[15]);
- goto end;
- }
- } else {
- if (clock_class_b->uuid_set) {
- BT_LOGV_STR("Clock classes differ: clock class A has "
- "no UUID, but clock class B has one.");
- goto end;
- }
- }