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_shared(&clock_class
->base
, 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_unique(&ret
->base
);
766 ret
->clock_class
= bt_get(clock_class
);
767 bt_clock_class_freeze(clock_class
);
768 BT_LOGD("Created clock value object: clock-value-addr=%p, "
769 "clock-class-addr=%p, clock-class-name=\"%s\", "
770 "ns-from-epoch=%" PRId64
", ns-from-epoch-overflows=%d",
771 ret
, clock_class
, bt_clock_class_get_name(clock_class
),
772 ret
->ns_from_epoch
, ret
->ns_from_epoch_overflows
);
779 struct bt_clock_value
*bt_clock_value_create(struct bt_clock_class
*clock_class
)
781 struct bt_clock_value
*clock_value
= NULL
;
783 BT_ASSERT(clock_class
);
784 clock_value
= bt_object_pool_create_object(&clock_class
->cv_pool
);
786 BT_LIB_LOGE("Cannot allocate one clock value from clock class's clock value pool: "
787 "%![cc-]+K", clock_class
);
791 if (!clock_value
->clock_class
) {
792 clock_value
->clock_class
= bt_get(clock_class
);
799 bt_clock_value_recycle(clock_value
);
808 void bt_clock_value_recycle(struct bt_clock_value
*clock_value
)
810 struct bt_clock_class
*clock_class
;
812 BT_ASSERT(clock_value
);
813 BT_LIB_LOGD("Recycling clock value: %!+k", clock_value
);
816 * Those are the important ordered steps:
818 * 1. Reset the clock value object, but do NOT put its clock
819 * class's reference. This clock class contains the pool to
820 * which we're about to recycle this clock value object, so
821 * we must guarantee its existence thanks to this existing
824 * 2. Move the clock class reference to our `clock_class`
825 * variable so that we can set the clock value's clock class
826 * member to NULL before recycling it. We CANNOT do this
827 * after we put the clock class reference because this
828 * bt_put() could destroy the clock class, also destroying
829 * its clock value pool, thus also destroying our clock value
830 * object (this would result in an invalid write access).
832 * 3. Recycle the clock value object.
834 * 4. Put our clock class reference.
836 bt_clock_value_reset(clock_value
);
837 bt_clock_value_set_is_frozen(clock_value
, false);
838 clock_class
= clock_value
->clock_class
;
839 BT_ASSERT(clock_class
);
840 clock_value
->clock_class
= NULL
;
841 bt_object_pool_recycle_object(&clock_class
->cv_pool
, clock_value
);
846 void bt_clock_value_set_raw_value(struct bt_clock_value
*clock_value
,
849 BT_ASSERT(clock_value
);
851 clock_value
->value
= cycles
;
852 set_ns_from_epoch(clock_value
);
853 bt_clock_value_set(clock_value
);
856 int bt_clock_value_set_value(struct bt_clock_value
*clock_value
,
859 BT_ASSERT_PRE_NON_NULL(clock_value
, "Clock value");
860 BT_ASSERT_PRE_HOT(clock_value
, "Clock value", ": %!+k", clock_value
);
861 bt_clock_value_set_raw_value(clock_value
, raw_value
);
865 int bt_clock_value_get_value(struct bt_clock_value
*clock_value
,
870 if (!clock_value
|| !raw_value
) {
871 BT_LOGW("Invalid parameter: clock value or raw value is NULL: "
872 "clock-value-addr=%p, raw-value-addr=%p",
873 clock_value
, raw_value
);
878 *raw_value
= clock_value
->value
;
883 int bt_clock_value_get_value_ns_from_epoch(struct bt_clock_value
*value
,
884 int64_t *ret_value_ns
)
888 if (!value
|| !ret_value_ns
) {
889 BT_LOGW("Invalid parameter: clock value or return value pointer is NULL: "
890 "clock-value-addr=%p, ret-value-addr=%p",
891 value
, ret_value_ns
);
896 if (value
->ns_from_epoch_overflows
) {
897 BT_LOGW("Clock value converted to nanoseconds from Epoch overflows the signed 64-bit integer range: "
898 "clock-value-addr=%p, "
899 "clock-class-offset-s=%" PRId64
", "
900 "clock-class-offset-cycles=%" PRId64
", "
902 value
, value
->clock_class
->offset_s
,
903 value
->clock_class
->offset
,
909 *ret_value_ns
= value
->ns_from_epoch
;
915 struct bt_clock_class
*bt_clock_value_borrow_class(
916 struct bt_clock_value
*clock_value
)
918 struct bt_clock_class
*clock_class
= NULL
;
921 BT_LOGW_STR("Invalid parameter: clock value is NULL.");
925 clock_class
= clock_value
->clock_class
;
932 int bt_clock_class_compare(struct bt_clock_class
*clock_class_a
,
933 struct bt_clock_class
*clock_class_b
)
936 BT_ASSERT(clock_class_a
);
937 BT_ASSERT(clock_class_b
);
940 if (strcmp(clock_class_a
->name
->str
, clock_class_b
->name
->str
) != 0) {
941 BT_LOGV("Clock classes differ: different names: "
942 "cc-a-name=\"%s\", cc-b-name=\"%s\"",
943 clock_class_a
->name
->str
,
944 clock_class_b
->name
->str
);
949 if (clock_class_a
->description
) {
950 if (!clock_class_b
->description
) {
951 BT_LOGV_STR("Clock classes differ: clock class A has a "
952 "description, but clock class B does not.");
956 if (strcmp(clock_class_a
->name
->str
, clock_class_b
->name
->str
)
958 BT_LOGV("Clock classes differ: different descriptions: "
959 "cc-a-descr=\"%s\", cc-b-descr=\"%s\"",
960 clock_class_a
->description
->str
,
961 clock_class_b
->description
->str
);
965 if (clock_class_b
->description
) {
966 BT_LOGV_STR("Clock classes differ: clock class A has "
967 "no description, but clock class B has one.");
973 if (clock_class_a
->frequency
!= clock_class_b
->frequency
) {
974 BT_LOGV("Clock classes differ: different frequencies: "
975 "cc-a-freq=%" PRIu64
", cc-b-freq=%" PRIu64
,
976 clock_class_a
->frequency
,
977 clock_class_b
->frequency
);
982 if (clock_class_a
->precision
!= clock_class_b
->precision
) {
983 BT_LOGV("Clock classes differ: different precisions: "
984 "cc-a-freq=%" PRIu64
", cc-b-freq=%" PRIu64
,
985 clock_class_a
->precision
,
986 clock_class_b
->precision
);
990 /* Offset (seconds) */
991 if (clock_class_a
->offset_s
!= clock_class_b
->offset_s
) {
992 BT_LOGV("Clock classes differ: different offsets (seconds): "
993 "cc-a-offset-s=%" PRId64
", cc-b-offset-s=%" PRId64
,
994 clock_class_a
->offset_s
,
995 clock_class_b
->offset_s
);
999 /* Offset (cycles) */
1000 if (clock_class_a
->offset
!= clock_class_b
->offset
) {
1001 BT_LOGV("Clock classes differ: different offsets (cycles): "
1002 "cc-a-offset-s=%" PRId64
", cc-b-offset-s=%" PRId64
,
1003 clock_class_a
->offset
,
1004 clock_class_b
->offset
);
1009 if (clock_class_a
->uuid_set
) {
1010 if (!clock_class_b
->uuid_set
) {
1011 BT_LOGV_STR("Clock classes differ: clock class A has a "
1012 "UUID, but clock class B does not.");
1016 if (memcmp(clock_class_a
->uuid
, clock_class_b
->uuid
,
1017 BABELTRACE_UUID_LEN
) != 0) {
1018 BT_LOGV("Clock classes differ: different UUIDs: "
1019 "cc-a-uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\", "
1020 "cc-b-uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"",
1021 (unsigned int) clock_class_a
->uuid
[0],
1022 (unsigned int) clock_class_a
->uuid
[1],
1023 (unsigned int) clock_class_a
->uuid
[2],
1024 (unsigned int) clock_class_a
->uuid
[3],
1025 (unsigned int) clock_class_a
->uuid
[4],
1026 (unsigned int) clock_class_a
->uuid
[5],
1027 (unsigned int) clock_class_a
->uuid
[6],
1028 (unsigned int) clock_class_a
->uuid
[7],
1029 (unsigned int) clock_class_a
->uuid
[8],
1030 (unsigned int) clock_class_a
->uuid
[9],
1031 (unsigned int) clock_class_a
->uuid
[10],
1032 (unsigned int) clock_class_a
->uuid
[11],
1033 (unsigned int) clock_class_a
->uuid
[12],
1034 (unsigned int) clock_class_a
->uuid
[13],
1035 (unsigned int) clock_class_a
->uuid
[14],
1036 (unsigned int) clock_class_a
->uuid
[15],
1037 (unsigned int) clock_class_b
->uuid
[0],
1038 (unsigned int) clock_class_b
->uuid
[1],
1039 (unsigned int) clock_class_b
->uuid
[2],
1040 (unsigned int) clock_class_b
->uuid
[3],
1041 (unsigned int) clock_class_b
->uuid
[4],
1042 (unsigned int) clock_class_b
->uuid
[5],
1043 (unsigned int) clock_class_b
->uuid
[6],
1044 (unsigned int) clock_class_b
->uuid
[7],
1045 (unsigned int) clock_class_b
->uuid
[8],
1046 (unsigned int) clock_class_b
->uuid
[9],
1047 (unsigned int) clock_class_b
->uuid
[10],
1048 (unsigned int) clock_class_b
->uuid
[11],
1049 (unsigned int) clock_class_b
->uuid
[12],
1050 (unsigned int) clock_class_b
->uuid
[13],
1051 (unsigned int) clock_class_b
->uuid
[14],
1052 (unsigned int) clock_class_b
->uuid
[15]);
1056 if (clock_class_b
->uuid_set
) {
1057 BT_LOGV_STR("Clock classes differ: clock class A has "
1058 "no UUID, but clock class B has one.");
1064 if (!!clock_class_a
->absolute
!= !!clock_class_b
->absolute
) {
1065 BT_LOGV("Clock classes differ: one is absolute, the other "
1066 "is not: cc-a-is-absolute=%d, cc-b-is-absolute=%d",
1067 !!clock_class_a
->absolute
,
1068 !!clock_class_b
->absolute
);
1079 int bt_clock_class_cycles_to_ns(struct bt_clock_class
*clock_class
,
1080 uint64_t cycles
, int64_t *ns
)
1085 BT_ASSERT_PRE_NON_NULL(clock_class
, "Clock class");
1086 BT_ASSERT_PRE_NON_NULL(ns
, "Nanoseconds");
1088 ret
= ns_from_epoch(clock_class
, cycles
, ns
, &overflows
);
1091 BT_LIB_LOGW("Cannot convert cycles to nanoseconds "
1092 "from Epoch for given clock class: "
1093 "value overflow: %![cc-]+K, cycles=%" PRIu64
,
1094 clock_class
, cycles
);
1096 BT_LIB_LOGW("Cannot convert cycles to nanoseconds "
1097 "from Epoch for given clock class: "
1098 "%![cc-]+K, cycles=%" PRIu64
,
1099 clock_class
, cycles
);