4 * Babeltrace CTF writer - 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 "CTF-WRITER/CLOCK-CLASS"
32 #include "common/uuid.h"
33 #include <babeltrace2-ctf-writer/utils.h>
34 #include <babeltrace2-ctf-writer/object.h>
35 #include "compat/compiler.h"
36 #include <babeltrace2/types.h>
37 #include "compat/string.h"
40 #include "common/assert.h"
42 #include "assert-pre.h"
43 #include "clock-class.h"
47 void bt_ctf_clock_class_destroy(struct bt_ctf_object
*obj
);
50 bt_ctf_bool
bt_ctf_clock_class_is_valid(struct bt_ctf_clock_class
*clock_class
)
52 return clock_class
&& clock_class
->name
;
56 int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class
*clock_class
,
62 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
67 if (clock_class
->frozen
) {
68 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
69 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
74 if (!bt_ctf_identifier_is_valid(name
)) {
75 BT_LOGW("Clock class's name is not a valid CTF identifier: "
76 "addr=%p, name=\"%s\"",
82 if (clock_class
->name
) {
83 g_string_assign(clock_class
->name
, name
);
85 clock_class
->name
= g_string_new(name
);
86 if (!clock_class
->name
) {
87 BT_LOGE_STR("Failed to allocate a GString.");
93 BT_LOGT("Set clock class's name: addr=%p, name=\"%s\"",
101 bool validate_freq(struct bt_ctf_clock_class
*clock_class
,
102 const char *name
, uint64_t freq
)
104 bool is_valid
= true;
106 if (freq
== -1ULL || freq
== 0) {
107 BT_LOGW("Invalid parameter: frequency is invalid: "
108 "addr=%p, name=\"%s\", freq=%" PRIu64
,
109 clock_class
, name
, freq
);
119 struct bt_ctf_clock_class
*bt_ctf_clock_class_create(const char *name
,
123 struct bt_ctf_clock_class
*clock_class
= NULL
;
125 BT_LOGD("Creating default clock class object: name=\"%s\"",
128 if (!validate_freq(NULL
, name
, freq
)) {
129 /* validate_freq() logs errors */
133 clock_class
= g_new0(struct bt_ctf_clock_class
, 1);
135 BT_LOGE_STR("Failed to allocate one clock class.");
139 clock_class
->precision
= 1;
140 clock_class
->frequency
= freq
;
141 bt_ctf_object_init_shared(&clock_class
->base
, bt_ctf_clock_class_destroy
);
144 ret
= bt_ctf_clock_class_set_name(clock_class
, name
);
146 /* bt_ctf_clock_class_set_name() logs errors */
151 BT_LOGD("Created clock class object: addr=%p, name=\"%s\"",
155 BT_CTF_OBJECT_PUT_REF_AND_RESET(clock_class
);
160 const char *bt_ctf_clock_class_get_name(struct bt_ctf_clock_class
*clock_class
)
162 const char *ret
= NULL
;
165 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
169 if (clock_class
->name
) {
170 ret
= clock_class
->name
->str
;
178 const char *bt_ctf_clock_class_get_description(
179 struct bt_ctf_clock_class
*clock_class
)
181 const char *ret
= NULL
;
184 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
188 if (clock_class
->description
) {
189 ret
= clock_class
->description
->str
;
196 int bt_ctf_clock_class_set_description(struct bt_ctf_clock_class
*clock_class
,
201 if (!clock_class
|| !desc
) {
202 BT_LOGW("Invalid parameter: clock class or description is NULL: "
203 "clock-class-addr=%p, name=\"%s\", desc-addr=%p",
204 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
210 if (clock_class
->frozen
) {
211 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
212 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
217 clock_class
->description
= g_string_new(desc
);
218 ret
= clock_class
->description
? 0 : -1;
219 BT_LOGT("Set clock class's description: addr=%p, "
220 "name=\"%s\", desc=\"%s\"",
221 clock_class
, bt_ctf_clock_class_get_name(clock_class
), desc
);
227 uint64_t bt_ctf_clock_class_get_frequency(
228 struct bt_ctf_clock_class
*clock_class
)
230 uint64_t ret
= -1ULL;
233 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
237 ret
= clock_class
->frequency
;
243 int bt_ctf_clock_class_set_frequency(struct bt_ctf_clock_class
*clock_class
,
249 BT_LOGW("Invalid parameter: clock class is NULL or frequency is invalid: "
250 "addr=%p, name=\"%s\"",
251 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
256 if (!validate_freq(clock_class
, bt_ctf_clock_class_get_name(clock_class
),
258 /* validate_freq() logs errors */
262 if (clock_class
->frozen
) {
263 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
264 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
269 clock_class
->frequency
= freq
;
270 BT_LOGT("Set clock class's frequency: addr=%p, name=\"%s\", freq=%" PRIu64
,
271 clock_class
, bt_ctf_clock_class_get_name(clock_class
), freq
);
277 uint64_t bt_ctf_clock_class_get_precision(struct bt_ctf_clock_class
*clock_class
)
279 uint64_t ret
= -1ULL;
282 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
286 ret
= clock_class
->precision
;
292 int bt_ctf_clock_class_set_precision(struct bt_ctf_clock_class
*clock_class
,
297 if (!clock_class
|| precision
== -1ULL) {
298 BT_LOGW("Invalid parameter: clock class is NULL or precision is invalid: "
299 "addr=%p, name=\"%s\", precision=%" PRIu64
,
300 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
306 if (clock_class
->frozen
) {
307 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
308 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
313 clock_class
->precision
= precision
;
314 BT_LOGT("Set clock class's precision: addr=%p, name=\"%s\", precision=%" PRIu64
,
315 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
322 int bt_ctf_clock_class_get_offset_s(struct bt_ctf_clock_class
*clock_class
,
327 if (!clock_class
|| !offset_s
) {
328 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
329 "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
330 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
336 *offset_s
= clock_class
->offset_s
;
342 int bt_ctf_clock_class_set_offset_s(struct bt_ctf_clock_class
*clock_class
,
348 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
353 if (clock_class
->frozen
) {
354 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
355 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
360 clock_class
->offset_s
= offset_s
;
361 BT_LOGT("Set clock class's offset (seconds): "
362 "addr=%p, name=\"%s\", offset-s=%" PRId64
,
363 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
370 int bt_ctf_clock_class_get_offset_cycles(struct bt_ctf_clock_class
*clock_class
,
375 if (!clock_class
|| !offset
) {
376 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
377 "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
378 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
384 *offset
= clock_class
->offset
;
390 int bt_ctf_clock_class_set_offset_cycles(struct bt_ctf_clock_class
*clock_class
,
396 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
401 if (clock_class
->frozen
) {
402 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
403 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
408 clock_class
->offset
= offset
;
409 BT_LOGT("Set clock class's offset (cycles): addr=%p, name=\"%s\", offset-cycles=%" PRId64
,
410 clock_class
, bt_ctf_clock_class_get_name(clock_class
), offset
);
416 bt_ctf_bool
bt_ctf_clock_class_is_absolute(struct bt_ctf_clock_class
*clock_class
)
421 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
425 ret
= clock_class
->absolute
;
431 int bt_ctf_clock_class_set_is_absolute(struct bt_ctf_clock_class
*clock_class
,
432 bt_ctf_bool is_absolute
)
437 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
442 if (clock_class
->frozen
) {
443 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
444 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
449 clock_class
->absolute
= !!is_absolute
;
450 BT_LOGT("Set clock class's absolute flag: addr=%p, name=\"%s\", is-absolute=%d",
451 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
458 const uint8_t *bt_ctf_clock_class_get_uuid(
459 struct bt_ctf_clock_class
*clock_class
)
464 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
469 if (!clock_class
->uuid_set
) {
470 BT_LOGT("Clock class's UUID is not set: addr=%p, name=\"%s\"",
471 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
476 ret
= clock_class
->uuid
;
482 int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class
*clock_class
,
487 if (!clock_class
|| !uuid
) {
488 BT_LOGW("Invalid parameter: clock class or UUID is NULL: "
489 "clock-class-addr=%p, name=\"%s\", uuid-addr=%p",
490 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
496 if (clock_class
->frozen
) {
497 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
498 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
503 bt_uuid_copy(clock_class
->uuid
, uuid
);
504 clock_class
->uuid_set
= 1;
505 BT_LOGT("Set clock class's UUID: addr=%p, name=\"%s\", uuid=\"" BT_UUID_FMT
"\"",
506 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
507 BT_UUID_FMT_VALUES(uuid
));
513 void bt_ctf_clock_class_freeze(struct bt_ctf_clock_class
*clock_class
)
515 if (!clock_class
|| clock_class
->frozen
) {
519 BT_LOGD("Freezing clock class: addr=%p, name=\"%s\"",
520 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
521 clock_class
->frozen
= 1;
525 void bt_ctf_clock_class_destroy(struct bt_ctf_object
*obj
)
527 struct bt_ctf_clock_class
*clock_class
;
529 clock_class
= container_of(obj
, struct bt_ctf_clock_class
, base
);
530 BT_LOGD("Destroying clock class: addr=%p, name=\"%s\"",
531 obj
, bt_ctf_clock_class_get_name(clock_class
));
533 if (clock_class
->name
) {
534 g_string_free(clock_class
->name
, TRUE
);
537 if (clock_class
->description
) {
538 g_string_free(clock_class
->description
, TRUE
);
545 int bt_ctf_clock_class_compare(struct bt_ctf_clock_class
*clock_class_a
,
546 struct bt_ctf_clock_class
*clock_class_b
)
549 BT_ASSERT_DBG(clock_class_a
);
550 BT_ASSERT_DBG(clock_class_b
);
553 if (strcmp(clock_class_a
->name
->str
, clock_class_b
->name
->str
) != 0) {
554 BT_LOGT("Clock classes differ: different names: "
555 "cc-a-name=\"%s\", cc-b-name=\"%s\"",
556 clock_class_a
->name
->str
,
557 clock_class_b
->name
->str
);
562 if (clock_class_a
->description
) {
563 if (!clock_class_b
->description
) {
564 BT_LOGT_STR("Clock classes differ: clock class A has a "
565 "description, but clock class B does not.");
569 if (strcmp(clock_class_a
->name
->str
, clock_class_b
->name
->str
)
571 BT_LOGT("Clock classes differ: different descriptions: "
572 "cc-a-descr=\"%s\", cc-b-descr=\"%s\"",
573 clock_class_a
->description
->str
,
574 clock_class_b
->description
->str
);
578 if (clock_class_b
->description
) {
579 BT_LOGT_STR("Clock classes differ: clock class A has "
580 "no description, but clock class B has one.");
586 if (clock_class_a
->frequency
!= clock_class_b
->frequency
) {
587 BT_LOGT("Clock classes differ: different frequencies: "
588 "cc-a-freq=%" PRIu64
", cc-b-freq=%" PRIu64
,
589 clock_class_a
->frequency
,
590 clock_class_b
->frequency
);
595 if (clock_class_a
->precision
!= clock_class_b
->precision
) {
596 BT_LOGT("Clock classes differ: different precisions: "
597 "cc-a-freq=%" PRIu64
", cc-b-freq=%" PRIu64
,
598 clock_class_a
->precision
,
599 clock_class_b
->precision
);
603 /* Offset (seconds) */
604 if (clock_class_a
->offset_s
!= clock_class_b
->offset_s
) {
605 BT_LOGT("Clock classes differ: different offsets (seconds): "
606 "cc-a-offset-s=%" PRId64
", cc-b-offset-s=%" PRId64
,
607 clock_class_a
->offset_s
,
608 clock_class_b
->offset_s
);
612 /* Offset (cycles) */
613 if (clock_class_a
->offset
!= clock_class_b
->offset
) {
614 BT_LOGT("Clock classes differ: different offsets (cycles): "
615 "cc-a-offset-s=%" PRId64
", cc-b-offset-s=%" PRId64
,
616 clock_class_a
->offset
,
617 clock_class_b
->offset
);
622 if (clock_class_a
->uuid_set
) {
623 if (!clock_class_b
->uuid_set
) {
624 BT_LOGT_STR("Clock classes differ: clock class A has a "
625 "UUID, but clock class B does not.");
629 if (bt_uuid_compare(clock_class_a
->uuid
, clock_class_b
->uuid
) != 0) {
630 BT_LOGT("Clock classes differ: different UUIDs: "
631 "cc-a-uuid=\"" BT_UUID_FMT
"\", "
632 "cc-b-uuid=\"" BT_UUID_FMT
"\"",
633 BT_UUID_FMT_VALUES(clock_class_a
->uuid
),
634 BT_UUID_FMT_VALUES(clock_class_b
->uuid
));
638 if (clock_class_b
->uuid_set
) {
639 BT_LOGT_STR("Clock classes differ: clock class A has "
640 "no UUID, but clock class B has one.");
646 if (!!clock_class_a
->absolute
!= !!clock_class_b
->absolute
) {
647 BT_LOGT("Clock classes differ: one is absolute, the other "
648 "is not: cc-a-is-absolute=%d, cc-b-is-absolute=%d",
649 !!clock_class_a
->absolute
,
650 !!clock_class_b
->absolute
);