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 "compat/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"
39 #include "common/assert.h"
41 #include "assert-pre.h"
42 #include "clock-class.h"
46 void bt_ctf_clock_class_destroy(struct bt_ctf_object
*obj
);
49 bt_bool
bt_ctf_clock_class_is_valid(struct bt_ctf_clock_class
*clock_class
)
51 return clock_class
&& clock_class
->name
;
55 int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class
*clock_class
,
61 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
66 if (clock_class
->frozen
) {
67 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
68 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
73 if (!bt_ctf_identifier_is_valid(name
)) {
74 BT_LOGW("Clock class's name is not a valid CTF identifier: "
75 "addr=%p, name=\"%s\"",
81 if (clock_class
->name
) {
82 g_string_assign(clock_class
->name
, name
);
84 clock_class
->name
= g_string_new(name
);
85 if (!clock_class
->name
) {
86 BT_LOGE_STR("Failed to allocate a GString.");
92 BT_LOGT("Set clock class's name: addr=%p, name=\"%s\"",
100 bool validate_freq(struct bt_ctf_clock_class
*clock_class
,
101 const char *name
, uint64_t freq
)
103 bool is_valid
= true;
105 if (freq
== -1ULL || freq
== 0) {
106 BT_LOGW("Invalid parameter: frequency is invalid: "
107 "addr=%p, name=\"%s\", freq=%" PRIu64
,
108 clock_class
, name
, freq
);
118 struct bt_ctf_clock_class
*bt_ctf_clock_class_create(const char *name
,
122 struct bt_ctf_clock_class
*clock_class
= NULL
;
124 BT_LOGD("Creating default clock class object: name=\"%s\"",
127 if (!validate_freq(NULL
, name
, freq
)) {
128 /* validate_freq() logs errors */
132 clock_class
= g_new0(struct bt_ctf_clock_class
, 1);
134 BT_LOGE_STR("Failed to allocate one clock class.");
138 clock_class
->precision
= 1;
139 clock_class
->frequency
= freq
;
140 bt_ctf_object_init_shared(&clock_class
->base
, bt_ctf_clock_class_destroy
);
143 ret
= bt_ctf_clock_class_set_name(clock_class
, name
);
145 /* bt_ctf_clock_class_set_name() logs errors */
150 BT_LOGD("Created clock class object: addr=%p, name=\"%s\"",
154 BT_CTF_OBJECT_PUT_REF_AND_RESET(clock_class
);
159 const char *bt_ctf_clock_class_get_name(struct bt_ctf_clock_class
*clock_class
)
161 const char *ret
= NULL
;
164 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
168 if (clock_class
->name
) {
169 ret
= clock_class
->name
->str
;
177 const char *bt_ctf_clock_class_get_description(
178 struct bt_ctf_clock_class
*clock_class
)
180 const char *ret
= NULL
;
183 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
187 if (clock_class
->description
) {
188 ret
= clock_class
->description
->str
;
195 int bt_ctf_clock_class_set_description(struct bt_ctf_clock_class
*clock_class
,
200 if (!clock_class
|| !desc
) {
201 BT_LOGW("Invalid parameter: clock class or description is NULL: "
202 "clock-class-addr=%p, name=\"%s\", desc-addr=%p",
203 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
209 if (clock_class
->frozen
) {
210 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
211 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
216 clock_class
->description
= g_string_new(desc
);
217 ret
= clock_class
->description
? 0 : -1;
218 BT_LOGT("Set clock class's description: addr=%p, "
219 "name=\"%s\", desc=\"%s\"",
220 clock_class
, bt_ctf_clock_class_get_name(clock_class
), desc
);
226 uint64_t bt_ctf_clock_class_get_frequency(
227 struct bt_ctf_clock_class
*clock_class
)
229 uint64_t ret
= -1ULL;
232 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
236 ret
= clock_class
->frequency
;
242 int bt_ctf_clock_class_set_frequency(struct bt_ctf_clock_class
*clock_class
,
248 BT_LOGW("Invalid parameter: clock class is NULL or frequency is invalid: "
249 "addr=%p, name=\"%s\"",
250 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
255 if (!validate_freq(clock_class
, bt_ctf_clock_class_get_name(clock_class
),
257 /* validate_freq() logs errors */
261 if (clock_class
->frozen
) {
262 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
263 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
268 clock_class
->frequency
= freq
;
269 BT_LOGT("Set clock class's frequency: addr=%p, name=\"%s\", freq=%" PRIu64
,
270 clock_class
, bt_ctf_clock_class_get_name(clock_class
), freq
);
276 uint64_t bt_ctf_clock_class_get_precision(struct bt_ctf_clock_class
*clock_class
)
278 uint64_t ret
= -1ULL;
281 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
285 ret
= clock_class
->precision
;
291 int bt_ctf_clock_class_set_precision(struct bt_ctf_clock_class
*clock_class
,
296 if (!clock_class
|| precision
== -1ULL) {
297 BT_LOGW("Invalid parameter: clock class is NULL or precision is invalid: "
298 "addr=%p, name=\"%s\", precision=%" PRIu64
,
299 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
305 if (clock_class
->frozen
) {
306 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
307 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
312 clock_class
->precision
= precision
;
313 BT_LOGT("Set clock class's precision: addr=%p, name=\"%s\", precision=%" PRIu64
,
314 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
321 int bt_ctf_clock_class_get_offset_s(struct bt_ctf_clock_class
*clock_class
,
326 if (!clock_class
|| !offset_s
) {
327 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
328 "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
329 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
335 *offset_s
= clock_class
->offset_s
;
341 int bt_ctf_clock_class_set_offset_s(struct bt_ctf_clock_class
*clock_class
,
347 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
352 if (clock_class
->frozen
) {
353 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
354 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
359 clock_class
->offset_s
= offset_s
;
360 BT_LOGT("Set clock class's offset (seconds): "
361 "addr=%p, name=\"%s\", offset-s=%" PRId64
,
362 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
369 int bt_ctf_clock_class_get_offset_cycles(struct bt_ctf_clock_class
*clock_class
,
374 if (!clock_class
|| !offset
) {
375 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
376 "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
377 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
383 *offset
= clock_class
->offset
;
389 int bt_ctf_clock_class_set_offset_cycles(struct bt_ctf_clock_class
*clock_class
,
395 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
400 if (clock_class
->frozen
) {
401 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
402 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
407 clock_class
->offset
= offset
;
408 BT_LOGT("Set clock class's offset (cycles): addr=%p, name=\"%s\", offset-cycles=%" PRId64
,
409 clock_class
, bt_ctf_clock_class_get_name(clock_class
), offset
);
415 bt_bool
bt_ctf_clock_class_is_absolute(struct bt_ctf_clock_class
*clock_class
)
420 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
424 ret
= clock_class
->absolute
;
430 int bt_ctf_clock_class_set_is_absolute(struct bt_ctf_clock_class
*clock_class
,
436 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
441 if (clock_class
->frozen
) {
442 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
443 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
448 clock_class
->absolute
= !!is_absolute
;
449 BT_LOGT("Set clock class's absolute flag: addr=%p, name=\"%s\", is-absolute=%d",
450 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
457 const unsigned char *bt_ctf_clock_class_get_uuid(
458 struct bt_ctf_clock_class
*clock_class
)
460 const unsigned char *ret
;
463 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
468 if (!clock_class
->uuid_set
) {
469 BT_LOGT("Clock class's UUID is not set: addr=%p, name=\"%s\"",
470 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
475 ret
= clock_class
->uuid
;
481 int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class
*clock_class
,
482 const unsigned char *uuid
)
486 if (!clock_class
|| !uuid
) {
487 BT_LOGW("Invalid parameter: clock class or UUID is NULL: "
488 "clock-class-addr=%p, name=\"%s\", uuid-addr=%p",
489 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
495 if (clock_class
->frozen
) {
496 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
497 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
502 memcpy(clock_class
->uuid
, uuid
, BABELTRACE_UUID_LEN
);
503 clock_class
->uuid_set
= 1;
504 BT_LOGT("Set clock class's UUID: addr=%p, name=\"%s\", "
505 "uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"",
506 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
507 (unsigned int) uuid
[0],
508 (unsigned int) uuid
[1],
509 (unsigned int) uuid
[2],
510 (unsigned int) uuid
[3],
511 (unsigned int) uuid
[4],
512 (unsigned int) uuid
[5],
513 (unsigned int) uuid
[6],
514 (unsigned int) uuid
[7],
515 (unsigned int) uuid
[8],
516 (unsigned int) uuid
[9],
517 (unsigned int) uuid
[10],
518 (unsigned int) uuid
[11],
519 (unsigned int) uuid
[12],
520 (unsigned int) uuid
[13],
521 (unsigned int) uuid
[14],
522 (unsigned int) uuid
[15]);
528 void bt_ctf_clock_class_freeze(struct bt_ctf_clock_class
*clock_class
)
530 if (!clock_class
|| clock_class
->frozen
) {
534 BT_LOGD("Freezing clock class: addr=%p, name=\"%s\"",
535 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
536 clock_class
->frozen
= 1;
540 void bt_ctf_clock_class_destroy(struct bt_ctf_object
*obj
)
542 struct bt_ctf_clock_class
*clock_class
;
544 clock_class
= container_of(obj
, struct bt_ctf_clock_class
, base
);
545 BT_LOGD("Destroying clock class: addr=%p, name=\"%s\"",
546 obj
, bt_ctf_clock_class_get_name(clock_class
));
548 if (clock_class
->name
) {
549 g_string_free(clock_class
->name
, TRUE
);
552 if (clock_class
->description
) {
553 g_string_free(clock_class
->description
, TRUE
);
560 int bt_ctf_clock_class_compare(struct bt_ctf_clock_class
*clock_class_a
,
561 struct bt_ctf_clock_class
*clock_class_b
)
564 BT_ASSERT(clock_class_a
);
565 BT_ASSERT(clock_class_b
);
568 if (strcmp(clock_class_a
->name
->str
, clock_class_b
->name
->str
) != 0) {
569 BT_LOGT("Clock classes differ: different names: "
570 "cc-a-name=\"%s\", cc-b-name=\"%s\"",
571 clock_class_a
->name
->str
,
572 clock_class_b
->name
->str
);
577 if (clock_class_a
->description
) {
578 if (!clock_class_b
->description
) {
579 BT_LOGT_STR("Clock classes differ: clock class A has a "
580 "description, but clock class B does not.");
584 if (strcmp(clock_class_a
->name
->str
, clock_class_b
->name
->str
)
586 BT_LOGT("Clock classes differ: different descriptions: "
587 "cc-a-descr=\"%s\", cc-b-descr=\"%s\"",
588 clock_class_a
->description
->str
,
589 clock_class_b
->description
->str
);
593 if (clock_class_b
->description
) {
594 BT_LOGT_STR("Clock classes differ: clock class A has "
595 "no description, but clock class B has one.");
601 if (clock_class_a
->frequency
!= clock_class_b
->frequency
) {
602 BT_LOGT("Clock classes differ: different frequencies: "
603 "cc-a-freq=%" PRIu64
", cc-b-freq=%" PRIu64
,
604 clock_class_a
->frequency
,
605 clock_class_b
->frequency
);
610 if (clock_class_a
->precision
!= clock_class_b
->precision
) {
611 BT_LOGT("Clock classes differ: different precisions: "
612 "cc-a-freq=%" PRIu64
", cc-b-freq=%" PRIu64
,
613 clock_class_a
->precision
,
614 clock_class_b
->precision
);
618 /* Offset (seconds) */
619 if (clock_class_a
->offset_s
!= clock_class_b
->offset_s
) {
620 BT_LOGT("Clock classes differ: different offsets (seconds): "
621 "cc-a-offset-s=%" PRId64
", cc-b-offset-s=%" PRId64
,
622 clock_class_a
->offset_s
,
623 clock_class_b
->offset_s
);
627 /* Offset (cycles) */
628 if (clock_class_a
->offset
!= clock_class_b
->offset
) {
629 BT_LOGT("Clock classes differ: different offsets (cycles): "
630 "cc-a-offset-s=%" PRId64
", cc-b-offset-s=%" PRId64
,
631 clock_class_a
->offset
,
632 clock_class_b
->offset
);
637 if (clock_class_a
->uuid_set
) {
638 if (!clock_class_b
->uuid_set
) {
639 BT_LOGT_STR("Clock classes differ: clock class A has a "
640 "UUID, but clock class B does not.");
644 if (memcmp(clock_class_a
->uuid
, clock_class_b
->uuid
,
645 BABELTRACE_UUID_LEN
) != 0) {
646 BT_LOGT("Clock classes differ: different UUIDs: "
647 "cc-a-uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\", "
648 "cc-b-uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"",
649 (unsigned int) clock_class_a
->uuid
[0],
650 (unsigned int) clock_class_a
->uuid
[1],
651 (unsigned int) clock_class_a
->uuid
[2],
652 (unsigned int) clock_class_a
->uuid
[3],
653 (unsigned int) clock_class_a
->uuid
[4],
654 (unsigned int) clock_class_a
->uuid
[5],
655 (unsigned int) clock_class_a
->uuid
[6],
656 (unsigned int) clock_class_a
->uuid
[7],
657 (unsigned int) clock_class_a
->uuid
[8],
658 (unsigned int) clock_class_a
->uuid
[9],
659 (unsigned int) clock_class_a
->uuid
[10],
660 (unsigned int) clock_class_a
->uuid
[11],
661 (unsigned int) clock_class_a
->uuid
[12],
662 (unsigned int) clock_class_a
->uuid
[13],
663 (unsigned int) clock_class_a
->uuid
[14],
664 (unsigned int) clock_class_a
->uuid
[15],
665 (unsigned int) clock_class_b
->uuid
[0],
666 (unsigned int) clock_class_b
->uuid
[1],
667 (unsigned int) clock_class_b
->uuid
[2],
668 (unsigned int) clock_class_b
->uuid
[3],
669 (unsigned int) clock_class_b
->uuid
[4],
670 (unsigned int) clock_class_b
->uuid
[5],
671 (unsigned int) clock_class_b
->uuid
[6],
672 (unsigned int) clock_class_b
->uuid
[7],
673 (unsigned int) clock_class_b
->uuid
[8],
674 (unsigned int) clock_class_b
->uuid
[9],
675 (unsigned int) clock_class_b
->uuid
[10],
676 (unsigned int) clock_class_b
->uuid
[11],
677 (unsigned int) clock_class_b
->uuid
[12],
678 (unsigned int) clock_class_b
->uuid
[13],
679 (unsigned int) clock_class_b
->uuid
[14],
680 (unsigned int) clock_class_b
->uuid
[15]);
684 if (clock_class_b
->uuid_set
) {
685 BT_LOGT_STR("Clock classes differ: clock class A has "
686 "no UUID, but clock class B has one.");
692 if (!!clock_class_a
->absolute
!= !!clock_class_b
->absolute
) {
693 BT_LOGT("Clock classes differ: one is absolute, the other "
694 "is not: cc-a-is-absolute=%d, cc-b-is-absolute=%d",
695 !!clock_class_a
->absolute
,
696 !!clock_class_b
->absolute
);