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/ctf-ir/clock-class-internal.h>
33 #include <babeltrace/ctf-ir/utils.h>
34 #include <babeltrace/ref.h>
35 #include <babeltrace/compiler-internal.h>
36 #include <babeltrace/types.h>
38 #include <babeltrace/object-internal.h>
41 void bt_ctf_clock_class_destroy(struct bt_object
*obj
);
44 bt_bool
bt_ctf_clock_class_is_valid(struct bt_ctf_clock_class
*clock_class
)
46 return clock_class
&& clock_class
->name
;
49 int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class
*clock_class
,
55 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
60 if (clock_class
->frozen
) {
61 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p",
67 if (bt_ctf_validate_identifier(name
)) {
68 BT_LOGE("Clock class's name is not a valid CTF identifier: "
69 "clock-class-addr=%p, name=\"%s\"",
75 if (clock_class
->name
) {
76 g_string_assign(clock_class
->name
, name
);
78 clock_class
->name
= g_string_new(name
);
79 if (!clock_class
->name
) {
80 BT_LOGE_STR("Failed to allocate a GString.");
86 BT_LOGV("Set clock class's name: clock-class-addr=%p, name=\"%s\"",
93 struct bt_ctf_clock_class
*bt_ctf_clock_class_create(const char *name
)
96 struct bt_ctf_clock_class
*clock_class
;
98 BT_LOGD("Creating default clock class object: name=\"%s\"",
100 clock_class
= g_new0(struct bt_ctf_clock_class
, 1);
102 BT_LOGE_STR("Failed to allocate one clock class.");
106 clock_class
->precision
= 1;
107 clock_class
->frequency
= 1000000000;
108 bt_object_init(clock_class
, bt_ctf_clock_class_destroy
);
111 ret
= bt_ctf_clock_class_set_name(clock_class
, name
);
113 BT_LOGE("Cannot set clock class's name: "
114 "clock-class-addr=%p, name=\"%s\"",
120 ret
= bt_uuid_generate(clock_class
->uuid
);
122 BT_LOGE_STR("Failed to generate a UUID.");
126 clock_class
->uuid_set
= 1;
127 BT_LOGD("Created clock class object: addr=%p", clock_class
);
134 const char *bt_ctf_clock_class_get_name(struct bt_ctf_clock_class
*clock_class
)
136 const char *ret
= NULL
;
139 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
143 if (clock_class
->name
) {
144 ret
= clock_class
->name
->str
;
151 const char *bt_ctf_clock_class_get_description(
152 struct bt_ctf_clock_class
*clock_class
)
154 const char *ret
= NULL
;
157 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
161 if (clock_class
->description
) {
162 ret
= clock_class
->description
->str
;
168 int bt_ctf_clock_class_set_description(struct bt_ctf_clock_class
*clock_class
,
173 if (!clock_class
|| !desc
) {
174 BT_LOGW("Invalid parameter: clock class or description is NULL: "
175 "clock-class-addr=%p, desc-addr=%p",
181 if (clock_class
->frozen
) {
182 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p",
188 clock_class
->description
= g_string_new(desc
);
189 ret
= clock_class
->description
? 0 : -1;
190 BT_LOGV("Set clock class's description: clock-class-addr=%p, desc=\"%s\"",
196 uint64_t bt_ctf_clock_class_get_frequency(
197 struct bt_ctf_clock_class
*clock_class
)
199 uint64_t ret
= -1ULL;
202 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
206 ret
= clock_class
->frequency
;
211 int bt_ctf_clock_class_set_frequency(struct bt_ctf_clock_class
*clock_class
,
216 if (!clock_class
|| freq
== -1ULL) {
217 BT_LOGW("Invalid parameter: clock class is NULL or frequency is invalid: "
218 "clock-class-addr=%p, freq=%" PRIu64
,
224 if (clock_class
->frozen
) {
225 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p",
231 clock_class
->frequency
= freq
;
232 BT_LOGV("Set clock class's frequency: clock-class-addr=%p, freq=%" PRIu64
,
238 uint64_t bt_ctf_clock_class_get_precision(struct bt_ctf_clock_class
*clock_class
)
240 uint64_t ret
= -1ULL;
243 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
247 ret
= clock_class
->precision
;
252 int bt_ctf_clock_class_set_precision(struct bt_ctf_clock_class
*clock_class
,
257 if (!clock_class
|| precision
== -1ULL) {
258 BT_LOGW("Invalid parameter: clock class is NULL or precision is invalid: "
259 "clock-class-addr=%p, precision=%" PRIu64
,
260 clock_class
, precision
);
265 if (clock_class
->frozen
) {
266 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p",
272 clock_class
->precision
= precision
;
273 BT_LOGV("Set clock class's precision: clock-class-addr=%p, precision=%" PRIu64
,
274 clock_class
, precision
);
279 int bt_ctf_clock_class_get_offset_s(struct bt_ctf_clock_class
*clock_class
,
284 if (!clock_class
|| !offset_s
) {
285 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
286 "clock-class-addr=%p, offset-addr=%p",
287 clock_class
, offset_s
);
292 *offset_s
= clock_class
->offset_s
;
297 int bt_ctf_clock_class_set_offset_s(struct bt_ctf_clock_class
*clock_class
,
303 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
308 if (clock_class
->frozen
) {
309 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p",
315 clock_class
->offset_s
= offset_s
;
316 BT_LOGV("Set clock class's offset (seconds): clock-class-addr=%p, offset-s=%" PRId64
,
317 clock_class
, offset_s
);
322 int bt_ctf_clock_class_get_offset_cycles(struct bt_ctf_clock_class
*clock_class
,
327 if (!clock_class
|| !offset
) {
328 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
329 "clock-class-addr=%p, offset-addr=%p",
330 clock_class
, offset
);
335 *offset
= clock_class
->offset
;
340 int bt_ctf_clock_class_set_offset_cycles(struct bt_ctf_clock_class
*clock_class
,
346 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
351 if (clock_class
->frozen
) {
352 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p",
358 clock_class
->offset
= offset
;
359 BT_LOGV("Set clock class's offset (cycles): clock-class-addr=%p, offset-cycles=%" PRId64
,
360 clock_class
, offset
);
365 bt_bool
bt_ctf_clock_class_is_absolute(struct bt_ctf_clock_class
*clock_class
)
370 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
374 ret
= clock_class
->absolute
;
379 int bt_ctf_clock_class_set_is_absolute(struct bt_ctf_clock_class
*clock_class
,
385 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
390 if (clock_class
->frozen
) {
391 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p",
397 clock_class
->absolute
= !!is_absolute
;
398 BT_LOGV("Set clock class's absolute flag: clock-class-addr=%p, is-absolute=%d",
399 clock_class
, !!is_absolute
);
404 const unsigned char *bt_ctf_clock_class_get_uuid(
405 struct bt_ctf_clock_class
*clock_class
)
407 const unsigned char *ret
;
410 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
415 if (!clock_class
->uuid_set
) {
416 BT_LOGV("Clock class's UUID is not set: clock-class-addr=%p",
422 ret
= clock_class
->uuid
;
427 int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class
*clock_class
,
428 const unsigned char *uuid
)
432 if (!clock_class
|| !uuid
) {
433 BT_LOGW("Invalid parameter: clock class or UUID is NULL: "
434 "clock-class-addr=%p, uuid-addr=%p",
440 if (clock_class
->frozen
) {
441 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p",
447 memcpy(clock_class
->uuid
, uuid
, sizeof(uuid_t
));
448 clock_class
->uuid_set
= 1;
449 BT_LOGV("Set clock class's UUID: clock-class-addr=%p, "
450 "uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"",
452 (unsigned int) uuid
[0],
453 (unsigned int) uuid
[1],
454 (unsigned int) uuid
[2],
455 (unsigned int) uuid
[3],
456 (unsigned int) uuid
[4],
457 (unsigned int) uuid
[5],
458 (unsigned int) uuid
[6],
459 (unsigned int) uuid
[7],
460 (unsigned int) uuid
[8],
461 (unsigned int) uuid
[9],
462 (unsigned int) uuid
[10],
463 (unsigned int) uuid
[11],
464 (unsigned int) uuid
[12],
465 (unsigned int) uuid
[13],
466 (unsigned int) uuid
[14],
467 (unsigned int) uuid
[15]);
472 static uint64_t ns_from_value(uint64_t frequency
, uint64_t value
)
476 if (frequency
== 1000000000) {
479 ns
= (uint64_t) ((1e9
* (double) value
) / (double) frequency
);
486 void bt_ctf_clock_class_freeze(struct bt_ctf_clock_class
*clock_class
)
489 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
493 if (!clock_class
->frozen
) {
494 BT_LOGD("Freezing clock class: addr=%p", clock_class
);
495 clock_class
->frozen
= 1;
500 void bt_ctf_clock_class_serialize(struct bt_ctf_clock_class
*clock_class
,
501 struct metadata_context
*context
)
505 BT_LOGD("Serializing clock class's metadata: clock-class-addr=%p, "
506 "metadata-context-addr=%p", clock_class
, context
);
508 if (!clock_class
|| !context
) {
509 BT_LOGW("Invalid parameter: clock class or metadata context is NULL: "
510 "clock-class-addr=%p, metadata-context-addr=%p",
511 clock_class
, context
);
515 uuid
= clock_class
->uuid
;
516 g_string_append(context
->string
, "clock {\n");
517 g_string_append_printf(context
->string
, "\tname = %s;\n",
518 clock_class
->name
->str
);
519 g_string_append_printf(context
->string
,
520 "\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n",
521 uuid
[0], uuid
[1], uuid
[2], uuid
[3],
522 uuid
[4], uuid
[5], uuid
[6], uuid
[7],
523 uuid
[8], uuid
[9], uuid
[10], uuid
[11],
524 uuid
[12], uuid
[13], uuid
[14], uuid
[15]);
525 if (clock_class
->description
) {
526 g_string_append_printf(context
->string
, "\tdescription = \"%s\";\n",
527 clock_class
->description
->str
);
530 g_string_append_printf(context
->string
, "\tfreq = %" PRIu64
";\n",
531 clock_class
->frequency
);
532 g_string_append_printf(context
->string
, "\tprecision = %" PRIu64
";\n",
533 clock_class
->precision
);
534 g_string_append_printf(context
->string
, "\toffset_s = %" PRIu64
";\n",
535 clock_class
->offset_s
);
536 g_string_append_printf(context
->string
, "\toffset = %" PRIu64
";\n",
537 clock_class
->offset
);
538 g_string_append_printf(context
->string
, "\tabsolute = %s;\n",
539 clock_class
->absolute
? "TRUE" : "FALSE");
540 g_string_append(context
->string
, "};\n\n");
544 void bt_ctf_clock_class_destroy(struct bt_object
*obj
)
546 struct bt_ctf_clock_class
*clock_class
;
548 BT_LOGD("Destroying clock class: addr=%p", obj
);
549 clock_class
= container_of(obj
, struct bt_ctf_clock_class
, base
);
550 if (clock_class
->name
) {
551 g_string_free(clock_class
->name
, TRUE
);
553 if (clock_class
->description
) {
554 g_string_free(clock_class
->description
, TRUE
);
561 void bt_ctf_clock_value_destroy(struct bt_object
*obj
)
563 struct bt_ctf_clock_value
*value
;
565 BT_LOGD("Destroying clock value: addr=%p", obj
);
571 value
= container_of(obj
, struct bt_ctf_clock_value
, base
);
572 bt_put(value
->clock_class
);
576 struct bt_ctf_clock_value
*bt_ctf_clock_value_create(
577 struct bt_ctf_clock_class
*clock_class
, uint64_t value
)
579 struct bt_ctf_clock_value
*ret
= NULL
;
581 BT_LOGD("Creating clock value object: clock-class-addr=%p, "
582 "value=%" PRIu64
, clock_class
, value
);
585 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
589 ret
= g_new0(struct bt_ctf_clock_value
, 1);
591 BT_LOGE_STR("Failed to allocate one clock value.");
595 bt_object_init(ret
, bt_ctf_clock_value_destroy
);
596 ret
->clock_class
= bt_get(clock_class
);
598 BT_LOGD("Created clock value object: addr=%p", ret
);
603 int bt_ctf_clock_value_get_value(
604 struct bt_ctf_clock_value
*clock_value
, uint64_t *raw_value
)
608 if (!clock_value
|| !raw_value
) {
609 BT_LOGW("Invalid parameter: clock value or raw value is NULL: "
610 "clock-value-addr=%p, raw-value-addr=%p",
611 clock_value
, raw_value
);
616 *raw_value
= clock_value
->value
;
621 int bt_ctf_clock_value_get_value_ns_from_epoch(struct bt_ctf_clock_value
*value
,
622 int64_t *ret_value_ns
)
627 if (!value
|| !ret_value_ns
) {
628 BT_LOGW("Invalid parameter: clock value or return value pointer is NULL: "
629 "clock-value-addr=%p, ret-value-addr=%p",
630 value
, ret_value_ns
);
635 /* Initialize nanosecond timestamp to clock's offset in seconds. */
636 ns
= value
->clock_class
->offset_s
* (int64_t) 1000000000;
638 /* Add offset in cycles, converted to nanoseconds. */
639 ns
+= ns_from_value(value
->clock_class
->frequency
,
640 value
->clock_class
->offset
);
642 /* Add given value, converter to nanoseconds. */
643 ns
+= ns_from_value(value
->clock_class
->frequency
, value
->value
);
650 struct bt_ctf_clock_class
*bt_ctf_clock_value_get_class(
651 struct bt_ctf_clock_value
*clock_value
)
653 struct bt_ctf_clock_class
*clock_class
= NULL
;
656 BT_LOGW_STR("Invalid parameter: clock value is NULL.");
660 clock_class
= bt_get(clock_value
->clock_class
);