4 * Babeltrace CTF IR - Clock class
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 #define BT_LOG_TAG "CLOCK-CLASS"
30 #include <babeltrace/lib-logging-internal.h>
32 #include <babeltrace/assert-pre-internal.h>
33 #include <babeltrace/compat/uuid-internal.h>
34 #include <babeltrace/ctf-ir/clock-class-internal.h>
35 #include <babeltrace/ctf-ir/clock-value-internal.h>
36 #include <babeltrace/ctf-ir/utils.h>
37 #include <babeltrace/ref.h>
38 #include <babeltrace/compiler-internal.h>
39 #include <babeltrace/types.h>
40 #include <babeltrace/compat/string-internal.h>
42 #include <babeltrace/object-internal.h>
43 #include <babeltrace/assert-internal.h>
46 void bt_clock_class_destroy(struct bt_object
*obj
);
49 struct bt_clock_value
*bt_clock_value_new(struct bt_clock_class
*clock_class
);
52 void bt_clock_value_destroy(struct bt_clock_value
*clock_value
);
55 bt_bool
bt_clock_class_is_valid(struct bt_clock_class
*clock_class
)
57 return clock_class
&& clock_class
->name
;
60 int bt_clock_class_set_name(struct bt_clock_class
*clock_class
,
66 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
71 if (clock_class
->frozen
) {
72 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
73 clock_class
, bt_clock_class_get_name(clock_class
));
78 if (!bt_identifier_is_valid(name
)) {
79 BT_LOGW("Clock class's name is not a valid CTF identifier: "
80 "addr=%p, name=\"%s\"",
86 if (clock_class
->name
) {
87 g_string_assign(clock_class
->name
, name
);
89 clock_class
->name
= g_string_new(name
);
90 if (!clock_class
->name
) {
91 BT_LOGE_STR("Failed to allocate a GString.");
97 BT_LOGV("Set clock class's name: addr=%p, name=\"%s\"",
105 bool validate_freq(struct bt_clock_class
*clock_class
,
106 const char *name
, uint64_t freq
)
108 bool is_valid
= true;
110 if (freq
== -1ULL || freq
== 0) {
111 BT_LOGW("Invalid parameter: frequency is invalid: "
112 "addr=%p, name=\"%s\", freq=%" PRIu64
,
113 clock_class
, name
, freq
);
123 void bt_clock_class_free_clock_value(struct bt_clock_value
*clock_value
,
124 struct bt_clock_class
*clock_class
)
126 bt_clock_value_destroy(clock_value
);
129 struct bt_clock_class
*bt_clock_class_create(const char *name
,
133 struct bt_clock_class
*clock_class
= NULL
;
135 BT_LOGD("Creating default clock class object: name=\"%s\"",
138 if (!validate_freq(NULL
, name
, freq
)) {
139 /* validate_freq() logs errors */
143 clock_class
= g_new0(struct bt_clock_class
, 1);
145 BT_LOGE_STR("Failed to allocate one clock class.");
149 clock_class
->precision
= 1;
150 clock_class
->frequency
= freq
;
151 bt_object_init(clock_class
, bt_clock_class_destroy
);
154 ret
= bt_clock_class_set_name(clock_class
, name
);
156 /* bt_clock_class_set_name() logs errors */
161 ret
= bt_object_pool_initialize(&clock_class
->cv_pool
,
162 (bt_object_pool_new_object_func
) bt_clock_value_new
,
163 (bt_object_pool_destroy_object_func
)
164 bt_clock_class_free_clock_value
,
167 BT_LOGE("Failed to initialize clock value pool: ret=%d",
172 BT_LOGD("Created clock class object: addr=%p, name=\"%s\"",
180 const char *bt_clock_class_get_name(struct bt_clock_class
*clock_class
)
182 const char *ret
= NULL
;
185 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
189 if (clock_class
->name
) {
190 ret
= clock_class
->name
->str
;
197 const char *bt_clock_class_get_description(
198 struct bt_clock_class
*clock_class
)
200 const char *ret
= NULL
;
203 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
207 if (clock_class
->description
) {
208 ret
= clock_class
->description
->str
;
214 int bt_clock_class_set_description(struct bt_clock_class
*clock_class
,
219 if (!clock_class
|| !desc
) {
220 BT_LOGW("Invalid parameter: clock class or description is NULL: "
221 "clock-class-addr=%p, name=\"%s\", desc-addr=%p",
222 clock_class
, bt_clock_class_get_name(clock_class
),
228 if (clock_class
->frozen
) {
229 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
230 clock_class
, bt_clock_class_get_name(clock_class
));
235 clock_class
->description
= g_string_new(desc
);
236 ret
= clock_class
->description
? 0 : -1;
237 BT_LOGV("Set clock class's description: addr=%p, "
238 "name=\"%s\", desc=\"%s\"",
239 clock_class
, bt_clock_class_get_name(clock_class
), desc
);
244 uint64_t bt_clock_class_get_frequency(
245 struct bt_clock_class
*clock_class
)
247 uint64_t ret
= -1ULL;
250 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
254 ret
= clock_class
->frequency
;
259 int bt_clock_class_set_frequency(struct bt_clock_class
*clock_class
,
265 BT_LOGW("Invalid parameter: clock class is NULL or frequency is invalid: "
266 "addr=%p, name=\"%s\"",
267 clock_class
, bt_clock_class_get_name(clock_class
));
272 if (!validate_freq(clock_class
, bt_clock_class_get_name(clock_class
),
274 /* validate_freq() logs errors */
278 if (clock_class
->frozen
) {
279 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
280 clock_class
, bt_clock_class_get_name(clock_class
));
285 clock_class
->frequency
= freq
;
286 BT_LOGV("Set clock class's frequency: addr=%p, name=\"%s\", freq=%" PRIu64
,
287 clock_class
, bt_clock_class_get_name(clock_class
), freq
);
292 uint64_t bt_clock_class_get_precision(struct bt_clock_class
*clock_class
)
294 uint64_t ret
= -1ULL;
297 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
301 ret
= clock_class
->precision
;
306 int bt_clock_class_set_precision(struct bt_clock_class
*clock_class
,
311 if (!clock_class
|| precision
== -1ULL) {
312 BT_LOGW("Invalid parameter: clock class is NULL or precision is invalid: "
313 "addr=%p, name=\"%s\", precision=%" PRIu64
,
314 clock_class
, bt_clock_class_get_name(clock_class
),
320 if (clock_class
->frozen
) {
321 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
322 clock_class
, bt_clock_class_get_name(clock_class
));
327 clock_class
->precision
= precision
;
328 BT_LOGV("Set clock class's precision: addr=%p, name=\"%s\", precision=%" PRIu64
,
329 clock_class
, bt_clock_class_get_name(clock_class
),
335 int bt_clock_class_get_offset_s(struct bt_clock_class
*clock_class
,
340 if (!clock_class
|| !offset_s
) {
341 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
342 "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
343 clock_class
, bt_clock_class_get_name(clock_class
),
349 *offset_s
= clock_class
->offset_s
;
354 int bt_clock_class_set_offset_s(struct bt_clock_class
*clock_class
,
360 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
365 if (clock_class
->frozen
) {
366 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
367 clock_class
, bt_clock_class_get_name(clock_class
));
372 clock_class
->offset_s
= offset_s
;
373 BT_LOGV("Set clock class's offset (seconds): "
374 "addr=%p, name=\"%s\", offset-s=%" PRId64
,
375 clock_class
, bt_clock_class_get_name(clock_class
),
381 int bt_clock_class_get_offset_cycles(struct bt_clock_class
*clock_class
,
386 if (!clock_class
|| !offset
) {
387 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
388 "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
389 clock_class
, bt_clock_class_get_name(clock_class
),
395 *offset
= clock_class
->offset
;
400 int bt_clock_class_set_offset_cycles(struct bt_clock_class
*clock_class
,
406 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
411 if (clock_class
->frozen
) {
412 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
413 clock_class
, bt_clock_class_get_name(clock_class
));
418 clock_class
->offset
= offset
;
419 BT_LOGV("Set clock class's offset (cycles): addr=%p, name=\"%s\", offset-cycles=%" PRId64
,
420 clock_class
, bt_clock_class_get_name(clock_class
), offset
);
425 bt_bool
bt_clock_class_is_absolute(struct bt_clock_class
*clock_class
)
430 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
434 ret
= clock_class
->absolute
;
439 int bt_clock_class_set_is_absolute(struct bt_clock_class
*clock_class
,
445 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
450 if (clock_class
->frozen
) {
451 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
452 clock_class
, bt_clock_class_get_name(clock_class
));
457 clock_class
->absolute
= !!is_absolute
;
458 BT_LOGV("Set clock class's absolute flag: addr=%p, name=\"%s\", is-absolute=%d",
459 clock_class
, bt_clock_class_get_name(clock_class
),
465 const unsigned char *bt_clock_class_get_uuid(
466 struct bt_clock_class
*clock_class
)
468 const unsigned char *ret
;
471 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
476 if (!clock_class
->uuid_set
) {
477 BT_LOGV("Clock class's UUID is not set: addr=%p, name=\"%s\"",
478 clock_class
, bt_clock_class_get_name(clock_class
));
483 ret
= clock_class
->uuid
;
488 int bt_clock_class_set_uuid(struct bt_clock_class
*clock_class
,
489 const unsigned char *uuid
)
493 if (!clock_class
|| !uuid
) {
494 BT_LOGW("Invalid parameter: clock class or UUID is NULL: "
495 "clock-class-addr=%p, name=\"%s\", uuid-addr=%p",
496 clock_class
, bt_clock_class_get_name(clock_class
),
502 if (clock_class
->frozen
) {
503 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
504 clock_class
, bt_clock_class_get_name(clock_class
));
509 memcpy(clock_class
->uuid
, uuid
, BABELTRACE_UUID_LEN
);
510 clock_class
->uuid_set
= 1;
511 BT_LOGV("Set clock class's UUID: addr=%p, name=\"%s\", "
512 "uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"",
513 clock_class
, bt_clock_class_get_name(clock_class
),
514 (unsigned int) uuid
[0],
515 (unsigned int) uuid
[1],
516 (unsigned int) uuid
[2],
517 (unsigned int) uuid
[3],
518 (unsigned int) uuid
[4],
519 (unsigned int) uuid
[5],
520 (unsigned int) uuid
[6],
521 (unsigned int) uuid
[7],
522 (unsigned int) uuid
[8],
523 (unsigned int) uuid
[9],
524 (unsigned int) uuid
[10],
525 (unsigned int) uuid
[11],
526 (unsigned int) uuid
[12],
527 (unsigned int) uuid
[13],
528 (unsigned int) uuid
[14],
529 (unsigned int) uuid
[15]);
535 uint64_t ns_from_value(uint64_t frequency
, uint64_t value
)
539 if (frequency
== UINT64_C(1000000000)) {
542 double dblres
= ((1e9
* (double) value
) / (double) frequency
);
544 if (dblres
>= (double) UINT64_MAX
) {
545 /* Overflows uint64_t */
548 ns
= (uint64_t) dblres
;
556 void bt_clock_class_freeze(struct bt_clock_class
*clock_class
)
558 if (!clock_class
|| clock_class
->frozen
) {
562 BT_LOGD("Freezing clock class: addr=%p, name=\"%s\"",
563 clock_class
, bt_clock_class_get_name(clock_class
));
564 clock_class
->frozen
= 1;
568 void bt_clock_class_destroy(struct bt_object
*obj
)
570 struct bt_clock_class
*clock_class
;
572 clock_class
= container_of(obj
, struct bt_clock_class
, base
);
573 BT_LOGD("Destroying clock class: addr=%p, name=\"%s\"",
574 obj
, bt_clock_class_get_name(clock_class
));
576 if (clock_class
->name
) {
577 g_string_free(clock_class
->name
, TRUE
);
580 if (clock_class
->description
) {
581 g_string_free(clock_class
->description
, TRUE
);
584 bt_object_pool_finalize(&clock_class
->cv_pool
);
589 void bt_clock_value_destroy(struct bt_clock_value
*clock_value
)
591 BT_LOGD("Destroying clock value: addr=%p, clock-class-addr=%p, "
592 "clock-class-name=\"%s\"", clock_value
,
593 clock_value
->clock_class
,
594 bt_clock_class_get_name(clock_value
->clock_class
));
595 bt_put(clock_value
->clock_class
);
600 int ns_from_epoch(struct bt_clock_class
*clock_class
, uint64_t value
,
601 int64_t *ns_from_epoch
, bool *overflows
)
611 /* Initialize nanosecond timestamp to clock's offset in seconds */
612 if (clock_class
->offset_s
<= (INT64_MIN
/ INT64_C(1000000000)) ||
613 clock_class
->offset_s
>= (INT64_MAX
/ INT64_C(1000000000))) {
615 * Overflow: offset in seconds converted to nanoseconds
616 * is outside the int64_t range.
622 *ns_from_epoch
= clock_class
->offset_s
* INT64_C(1000000000);
624 /* Add offset in cycles */
625 if (clock_class
->offset
< 0) {
626 cycles
= (uint64_t) -clock_class
->offset
;
628 cycles
= (uint64_t) clock_class
->offset
;
631 u_ns
= ns_from_value(clock_class
->frequency
, cycles
);
633 if (u_ns
== UINT64_C(-1) || u_ns
>= INT64_MAX
) {
635 * Overflow: offset in cycles converted to nanoseconds
636 * is outside the int64_t range.
642 s_ns
= (int64_t) u_ns
;
643 BT_ASSERT(s_ns
>= 0);
645 if (clock_class
->offset
< 0) {
646 if (*ns_from_epoch
>= 0) {
648 * Offset in cycles is negative so it must also
649 * be negative once converted to nanoseconds.
655 diff
= *ns_from_epoch
- INT64_MIN
;
659 * Overflow: current timestamp in nanoseconds
660 * plus the offset in cycles converted to
661 * nanoseconds is outside the int64_t range.
668 * Offset in cycles is negative so it must also be
669 * negative once converted to nanoseconds.
673 if (*ns_from_epoch
<= 0) {
677 diff
= INT64_MAX
- *ns_from_epoch
;
681 * Overflow: current timestamp in nanoseconds
682 * plus the offset in cycles converted to
683 * nanoseconds is outside the int64_t range.
691 *ns_from_epoch
+= s_ns
;
693 /* Add clock value (cycles) */
694 u_ns
= ns_from_value(clock_class
->frequency
, value
);
696 if (u_ns
== -1ULL || u_ns
>= INT64_MAX
) {
698 * Overflow: value converted to nanoseconds is outside
705 s_ns
= (int64_t) u_ns
;
706 BT_ASSERT(s_ns
>= 0);
708 /* Clock value (cycles) is always positive */
709 if (*ns_from_epoch
<= 0) {
713 diff
= INT64_MAX
- *ns_from_epoch
;
717 * Overflow: current timestamp in nanoseconds plus the
718 * clock value converted to nanoseconds is outside the
726 *ns_from_epoch
+= s_ns
;
738 void set_ns_from_epoch(struct bt_clock_value
*clock_value
)
740 (void) ns_from_epoch(clock_value
->clock_class
,
741 clock_value
->value
, &clock_value
->ns_from_epoch
,
742 &clock_value
->ns_from_epoch_overflows
);
746 struct bt_clock_value
*bt_clock_value_new(struct bt_clock_class
*clock_class
)
748 struct bt_clock_value
*ret
= NULL
;
750 BT_LOGD("Creating clock value object: clock-class-addr=%p, "
751 "clock-class-name=\"%s\"", clock_class
,
752 bt_clock_class_get_name(clock_class
));
755 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
759 ret
= g_new0(struct bt_clock_value
, 1);
761 BT_LOGE_STR("Failed to allocate one clock value.");
765 bt_object_init(ret
, NULL
);
766 bt_object_set_is_shared((void *) ret
, false);
767 ret
->clock_class
= bt_get(clock_class
);
768 bt_clock_class_freeze(clock_class
);
769 BT_LOGD("Created clock value object: clock-value-addr=%p, "
770 "clock-class-addr=%p, clock-class-name=\"%s\", "
771 "ns-from-epoch=%" PRId64
", ns-from-epoch-overflows=%d",
772 ret
, clock_class
, bt_clock_class_get_name(clock_class
),
773 ret
->ns_from_epoch
, ret
->ns_from_epoch_overflows
);
780 struct bt_clock_value
*bt_clock_value_create(struct bt_clock_class
*clock_class
)
782 struct bt_clock_value
*clock_value
= NULL
;
784 BT_ASSERT(clock_class
);
785 clock_value
= bt_object_pool_create_object(&clock_class
->cv_pool
);
787 BT_LIB_LOGE("Cannot allocate one clock value from clock class's clock value pool: "
788 "%![cc-]+K", clock_class
);
792 if (!clock_value
->clock_class
) {
793 clock_value
->clock_class
= bt_get(clock_class
);
800 bt_clock_value_recycle(clock_value
);
809 void bt_clock_value_recycle(struct bt_clock_value
*clock_value
)
811 struct bt_clock_class
*clock_class
;
813 BT_ASSERT(clock_value
);
814 BT_LIB_LOGD("Recycling clock value: %!+k", clock_value
);
817 * Those are the important ordered steps:
819 * 1. Reset the clock value object, but do NOT put its clock
820 * class's reference. This clock class contains the pool to
821 * which we're about to recycle this clock value object, so
822 * we must guarantee its existence thanks to this existing
825 * 2. Move the clock class reference to our `clock_class`
826 * variable so that we can set the clock value's clock class
827 * member to NULL before recycling it. We CANNOT do this
828 * after we put the clock class reference because this
829 * bt_put() could destroy the clock class, also destroying
830 * its clock value pool, thus also destroying our clock value
831 * object (this would result in an invalid write access).
833 * 3. Recycle the clock value object.
835 * 4. Put our clock class reference.
837 bt_clock_value_reset(clock_value
);
838 bt_clock_value_set_is_frozen(clock_value
, false);
839 clock_class
= clock_value
->clock_class
;
840 BT_ASSERT(clock_class
);
841 clock_value
->clock_class
= NULL
;
842 bt_object_pool_recycle_object(&clock_class
->cv_pool
, clock_value
);
847 void bt_clock_value_set_raw_value(struct bt_clock_value
*clock_value
,
850 BT_ASSERT(clock_value
);
852 clock_value
->value
= cycles
;
853 set_ns_from_epoch(clock_value
);
854 bt_clock_value_set(clock_value
);
857 int bt_clock_value_set_value(struct bt_clock_value
*clock_value
,
860 BT_ASSERT_PRE_NON_NULL(clock_value
, "Clock value");
861 BT_ASSERT_PRE_HOT(clock_value
, "Clock value", ": %!+k", clock_value
);
862 bt_clock_value_set_raw_value(clock_value
, raw_value
);
866 int bt_clock_value_get_value(struct bt_clock_value
*clock_value
,
871 if (!clock_value
|| !raw_value
) {
872 BT_LOGW("Invalid parameter: clock value or raw value is NULL: "
873 "clock-value-addr=%p, raw-value-addr=%p",
874 clock_value
, raw_value
);
879 *raw_value
= clock_value
->value
;
884 int bt_clock_value_get_value_ns_from_epoch(struct bt_clock_value
*value
,
885 int64_t *ret_value_ns
)
889 if (!value
|| !ret_value_ns
) {
890 BT_LOGW("Invalid parameter: clock value or return value pointer is NULL: "
891 "clock-value-addr=%p, ret-value-addr=%p",
892 value
, ret_value_ns
);
897 if (value
->ns_from_epoch_overflows
) {
898 BT_LOGW("Clock value converted to nanoseconds from Epoch overflows the signed 64-bit integer range: "
899 "clock-value-addr=%p, "
900 "clock-class-offset-s=%" PRId64
", "
901 "clock-class-offset-cycles=%" PRId64
", "
903 value
, value
->clock_class
->offset_s
,
904 value
->clock_class
->offset
,
910 *ret_value_ns
= value
->ns_from_epoch
;
916 struct bt_clock_class
*bt_clock_value_borrow_class(
917 struct bt_clock_value
*clock_value
)
919 struct bt_clock_class
*clock_class
= NULL
;
922 BT_LOGW_STR("Invalid parameter: clock value is NULL.");
926 clock_class
= clock_value
->clock_class
;
933 int bt_clock_class_compare(struct bt_clock_class
*clock_class_a
,
934 struct bt_clock_class
*clock_class_b
)
937 BT_ASSERT(clock_class_a
);
938 BT_ASSERT(clock_class_b
);
941 if (strcmp(clock_class_a
->name
->str
, clock_class_b
->name
->str
) != 0) {
942 BT_LOGV("Clock classes differ: different names: "
943 "cc-a-name=\"%s\", cc-b-name=\"%s\"",
944 clock_class_a
->name
->str
,
945 clock_class_b
->name
->str
);
950 if (clock_class_a
->description
) {
951 if (!clock_class_b
->description
) {
952 BT_LOGV_STR("Clock classes differ: clock class A has a "
953 "description, but clock class B does not.");
957 if (strcmp(clock_class_a
->name
->str
, clock_class_b
->name
->str
)
959 BT_LOGV("Clock classes differ: different descriptions: "
960 "cc-a-descr=\"%s\", cc-b-descr=\"%s\"",
961 clock_class_a
->description
->str
,
962 clock_class_b
->description
->str
);
966 if (clock_class_b
->description
) {
967 BT_LOGV_STR("Clock classes differ: clock class A has "
968 "no description, but clock class B has one.");
974 if (clock_class_a
->frequency
!= clock_class_b
->frequency
) {
975 BT_LOGV("Clock classes differ: different frequencies: "
976 "cc-a-freq=%" PRIu64
", cc-b-freq=%" PRIu64
,
977 clock_class_a
->frequency
,
978 clock_class_b
->frequency
);
983 if (clock_class_a
->precision
!= clock_class_b
->precision
) {
984 BT_LOGV("Clock classes differ: different precisions: "
985 "cc-a-freq=%" PRIu64
", cc-b-freq=%" PRIu64
,
986 clock_class_a
->precision
,
987 clock_class_b
->precision
);
991 /* Offset (seconds) */
992 if (clock_class_a
->offset_s
!= clock_class_b
->offset_s
) {
993 BT_LOGV("Clock classes differ: different offsets (seconds): "
994 "cc-a-offset-s=%" PRId64
", cc-b-offset-s=%" PRId64
,
995 clock_class_a
->offset_s
,
996 clock_class_b
->offset_s
);
1000 /* Offset (cycles) */
1001 if (clock_class_a
->offset
!= clock_class_b
->offset
) {
1002 BT_LOGV("Clock classes differ: different offsets (cycles): "
1003 "cc-a-offset-s=%" PRId64
", cc-b-offset-s=%" PRId64
,
1004 clock_class_a
->offset
,
1005 clock_class_b
->offset
);
1010 if (clock_class_a
->uuid_set
) {
1011 if (!clock_class_b
->uuid_set
) {
1012 BT_LOGV_STR("Clock classes differ: clock class A has a "
1013 "UUID, but clock class B does not.");
1017 if (memcmp(clock_class_a
->uuid
, clock_class_b
->uuid
,
1018 BABELTRACE_UUID_LEN
) != 0) {
1019 BT_LOGV("Clock classes differ: different UUIDs: "
1020 "cc-a-uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\", "
1021 "cc-b-uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"",
1022 (unsigned int) clock_class_a
->uuid
[0],
1023 (unsigned int) clock_class_a
->uuid
[1],
1024 (unsigned int) clock_class_a
->uuid
[2],
1025 (unsigned int) clock_class_a
->uuid
[3],
1026 (unsigned int) clock_class_a
->uuid
[4],
1027 (unsigned int) clock_class_a
->uuid
[5],
1028 (unsigned int) clock_class_a
->uuid
[6],
1029 (unsigned int) clock_class_a
->uuid
[7],
1030 (unsigned int) clock_class_a
->uuid
[8],
1031 (unsigned int) clock_class_a
->uuid
[9],
1032 (unsigned int) clock_class_a
->uuid
[10],
1033 (unsigned int) clock_class_a
->uuid
[11],
1034 (unsigned int) clock_class_a
->uuid
[12],
1035 (unsigned int) clock_class_a
->uuid
[13],
1036 (unsigned int) clock_class_a
->uuid
[14],
1037 (unsigned int) clock_class_a
->uuid
[15],
1038 (unsigned int) clock_class_b
->uuid
[0],
1039 (unsigned int) clock_class_b
->uuid
[1],
1040 (unsigned int) clock_class_b
->uuid
[2],
1041 (unsigned int) clock_class_b
->uuid
[3],
1042 (unsigned int) clock_class_b
->uuid
[4],
1043 (unsigned int) clock_class_b
->uuid
[5],
1044 (unsigned int) clock_class_b
->uuid
[6],
1045 (unsigned int) clock_class_b
->uuid
[7],
1046 (unsigned int) clock_class_b
->uuid
[8],
1047 (unsigned int) clock_class_b
->uuid
[9],
1048 (unsigned int) clock_class_b
->uuid
[10],
1049 (unsigned int) clock_class_b
->uuid
[11],
1050 (unsigned int) clock_class_b
->uuid
[12],
1051 (unsigned int) clock_class_b
->uuid
[13],
1052 (unsigned int) clock_class_b
->uuid
[14],
1053 (unsigned int) clock_class_b
->uuid
[15]);
1057 if (clock_class_b
->uuid_set
) {
1058 BT_LOGV_STR("Clock classes differ: clock class A has "
1059 "no UUID, but clock class B has one.");
1065 if (!!clock_class_a
->absolute
!= !!clock_class_b
->absolute
) {
1066 BT_LOGV("Clock classes differ: one is absolute, the other "
1067 "is not: cc-a-is-absolute=%d, cc-b-is-absolute=%d",
1068 !!clock_class_a
->absolute
,
1069 !!clock_class_b
->absolute
);
1080 int bt_clock_class_cycles_to_ns(struct bt_clock_class
*clock_class
,
1081 uint64_t cycles
, int64_t *ns
)
1086 BT_ASSERT_PRE_NON_NULL(clock_class
, "Clock class");
1087 BT_ASSERT_PRE_NON_NULL(ns
, "Nanoseconds");
1089 ret
= ns_from_epoch(clock_class
, cycles
, ns
, &overflows
);
1092 BT_LIB_LOGW("Cannot convert cycles to nanoseconds "
1093 "from Epoch for given clock class: "
1094 "value overflow: %![cc-]+K, cycles=%" PRIu64
,
1095 clock_class
, cycles
);
1097 BT_LIB_LOGW("Cannot convert cycles to nanoseconds "
1098 "from Epoch for given clock class: "
1099 "%![cc-]+K, cycles=%" PRIu64
,
1100 clock_class
, cycles
);