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 #include <babeltrace/ctf-ir/clock-class-internal.h>
30 #include <babeltrace/ctf-ir/utils.h>
31 #include <babeltrace/ref.h>
32 #include <babeltrace/object-internal.h>
33 #include <babeltrace/compiler-internal.h>
36 #define BT_LOG_TAG "CLOCK-CLASS"
37 #include <babeltrace/lib-logging-internal.h>
40 void bt_ctf_clock_class_destroy(struct bt_object
*obj
);
43 bool bt_ctf_clock_class_is_valid(struct bt_ctf_clock_class
*clock_class
)
45 return clock_class
&& clock_class
->name
;
48 int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class
*clock_class
,
54 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
59 if (clock_class
->frozen
) {
60 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p",
66 if (bt_ctf_validate_identifier(name
)) {
67 BT_LOGE("Clock class's name is not a valid CTF identifier: "
68 "clock-class-addr=%p, name=\"%s\"",
74 if (clock_class
->name
) {
75 g_string_assign(clock_class
->name
, name
);
77 clock_class
->name
= g_string_new(name
);
78 if (!clock_class
->name
) {
79 BT_LOGE_STR("Failed to allocate a GString.");
85 BT_LOGV("Set clock class's name: clock-class-addr=%p, name=\"%s\"",
92 struct bt_ctf_clock_class
*bt_ctf_clock_class_create(const char *name
)
95 struct bt_ctf_clock_class
*clock_class
;
97 BT_LOGD("Creating default clock class object: name=\"%s\"",
99 clock_class
= g_new0(struct bt_ctf_clock_class
, 1);
101 BT_LOGE_STR("Failed to allocate one clock class.");
105 clock_class
->precision
= 1;
106 clock_class
->frequency
= 1000000000;
107 bt_object_init(clock_class
, bt_ctf_clock_class_destroy
);
110 ret
= bt_ctf_clock_class_set_name(clock_class
, name
);
112 BT_LOGE("Cannot set clock class's name: "
113 "clock-class-addr=%p, name=\"%s\"",
119 ret
= bt_uuid_generate(clock_class
->uuid
);
121 BT_LOGE_STR("Failed to generate a UUID.");
125 clock_class
->uuid_set
= 1;
126 BT_LOGD("Created clock class object: addr=%p", clock_class
);
133 const char *bt_ctf_clock_class_get_name(struct bt_ctf_clock_class
*clock_class
)
135 const char *ret
= NULL
;
138 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
142 if (clock_class
->name
) {
143 ret
= clock_class
->name
->str
;
150 const char *bt_ctf_clock_class_get_description(
151 struct bt_ctf_clock_class
*clock_class
)
153 const char *ret
= NULL
;
156 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
160 if (clock_class
->description
) {
161 ret
= clock_class
->description
->str
;
167 int bt_ctf_clock_class_set_description(struct bt_ctf_clock_class
*clock_class
,
172 if (!clock_class
|| !desc
) {
173 BT_LOGW("Invalid parameter: clock class or description is NULL: "
174 "clock-class-addr=%p, desc-addr=%p",
180 if (clock_class
->frozen
) {
181 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p",
187 clock_class
->description
= g_string_new(desc
);
188 ret
= clock_class
->description
? 0 : -1;
189 BT_LOGV("Set clock class's description: clock-class-addr=%p, desc=\"%s\"",
195 uint64_t bt_ctf_clock_class_get_frequency(
196 struct bt_ctf_clock_class
*clock_class
)
198 uint64_t ret
= -1ULL;
201 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
205 ret
= clock_class
->frequency
;
210 int bt_ctf_clock_class_set_frequency(struct bt_ctf_clock_class
*clock_class
,
215 if (!clock_class
|| freq
== -1ULL) {
216 BT_LOGW("Invalid parameter: clock class is NULL or frequency is invalid: "
217 "clock-class-addr=%p, freq=%" PRIu64
,
223 if (clock_class
->frozen
) {
224 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p",
230 clock_class
->frequency
= freq
;
231 BT_LOGV("Set clock class's frequency: clock-class-addr=%p, freq=%" PRIu64
,
237 uint64_t bt_ctf_clock_class_get_precision(struct bt_ctf_clock_class
*clock_class
)
239 uint64_t ret
= -1ULL;
242 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
246 ret
= clock_class
->precision
;
251 int bt_ctf_clock_class_set_precision(struct bt_ctf_clock_class
*clock_class
,
256 if (!clock_class
|| precision
== -1ULL) {
257 BT_LOGW("Invalid parameter: clock class is NULL or precision is invalid: "
258 "clock-class-addr=%p, precision=%" PRIu64
,
259 clock_class
, precision
);
264 if (clock_class
->frozen
) {
265 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p",
271 clock_class
->precision
= precision
;
272 BT_LOGV("Set clock class's precision: clock-class-addr=%p, precision=%" PRIu64
,
273 clock_class
, precision
);
278 int bt_ctf_clock_class_get_offset_s(struct bt_ctf_clock_class
*clock_class
,
283 if (!clock_class
|| !offset_s
) {
284 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
285 "clock-class-addr=%p, offset-addr=%p",
286 clock_class
, offset_s
);
291 *offset_s
= clock_class
->offset_s
;
296 int bt_ctf_clock_class_set_offset_s(struct bt_ctf_clock_class
*clock_class
,
302 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
307 if (clock_class
->frozen
) {
308 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p",
314 clock_class
->offset_s
= offset_s
;
315 BT_LOGV("Set clock class's offset (seconds): clock-class-addr=%p, offset-s=%" PRId64
,
316 clock_class
, offset_s
);
321 int bt_ctf_clock_class_get_offset_cycles(struct bt_ctf_clock_class
*clock_class
,
326 if (!clock_class
|| !offset
) {
327 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
328 "clock-class-addr=%p, offset-addr=%p",
329 clock_class
, offset
);
334 *offset
= clock_class
->offset
;
339 int bt_ctf_clock_class_set_offset_cycles(struct bt_ctf_clock_class
*clock_class
,
345 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
350 if (clock_class
->frozen
) {
351 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p",
357 clock_class
->offset
= offset
;
358 BT_LOGV("Set clock class's offset (cycles): clock-class-addr=%p, offset-cycles=%" PRId64
,
359 clock_class
, offset
);
364 int bt_ctf_clock_class_is_absolute(struct bt_ctf_clock_class
*clock_class
)
369 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
373 ret
= clock_class
->absolute
;
378 int bt_ctf_clock_class_set_is_absolute(struct bt_ctf_clock_class
*clock_class
,
384 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
389 if (clock_class
->frozen
) {
390 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p",
396 clock_class
->absolute
= !!is_absolute
;
397 BT_LOGV("Set clock class's absolute flag: clock-class-addr=%p, is-absolute=%d",
398 clock_class
, !!is_absolute
);
403 const unsigned char *bt_ctf_clock_class_get_uuid(
404 struct bt_ctf_clock_class
*clock_class
)
406 const unsigned char *ret
;
409 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
414 if (!clock_class
->uuid_set
) {
415 BT_LOGV("Clock class's UUID is not set: clock-class-addr=%p",
421 ret
= clock_class
->uuid
;
426 int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class
*clock_class
,
427 const unsigned char *uuid
)
431 if (!clock_class
|| !uuid
) {
432 BT_LOGW("Invalid parameter: clock class or UUID is NULL: "
433 "clock-class-addr=%p, uuid-addr=%p",
439 if (clock_class
->frozen
) {
440 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p",
446 memcpy(clock_class
->uuid
, uuid
, sizeof(uuid_t
));
447 clock_class
->uuid_set
= 1;
448 BT_LOGV("Set clock class's UUID: clock-class-addr=%p, "
449 "uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"",
451 (unsigned int) uuid
[0],
452 (unsigned int) uuid
[1],
453 (unsigned int) uuid
[2],
454 (unsigned int) uuid
[3],
455 (unsigned int) uuid
[4],
456 (unsigned int) uuid
[5],
457 (unsigned int) uuid
[6],
458 (unsigned int) uuid
[7],
459 (unsigned int) uuid
[8],
460 (unsigned int) uuid
[9],
461 (unsigned int) uuid
[10],
462 (unsigned int) uuid
[11],
463 (unsigned int) uuid
[12],
464 (unsigned int) uuid
[13],
465 (unsigned int) uuid
[14],
466 (unsigned int) uuid
[15]);
471 static uint64_t ns_from_value(uint64_t frequency
, uint64_t value
)
475 if (frequency
== 1000000000) {
478 ns
= (uint64_t) ((1e9
* (double) value
) / (double) frequency
);
485 void bt_ctf_clock_class_freeze(struct bt_ctf_clock_class
*clock_class
)
488 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
492 if (!clock_class
->frozen
) {
493 BT_LOGD("Freezing clock class: addr=%p", clock_class
);
494 clock_class
->frozen
= 1;
499 void bt_ctf_clock_class_serialize(struct bt_ctf_clock_class
*clock_class
,
500 struct metadata_context
*context
)
504 BT_LOGD("Serializing clock class's metadata: clock-class-addr=%p, "
505 "metadata-context-addr=%p", clock_class
, context
);
507 if (!clock_class
|| !context
) {
508 BT_LOGW("Invalid parameter: clock class or metadata context is NULL: "
509 "clock-class-addr=%p, metadata-context-addr=%p",
510 clock_class
, context
);
514 uuid
= clock_class
->uuid
;
515 g_string_append(context
->string
, "clock {\n");
516 g_string_append_printf(context
->string
, "\tname = %s;\n",
517 clock_class
->name
->str
);
518 g_string_append_printf(context
->string
,
519 "\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n",
520 uuid
[0], uuid
[1], uuid
[2], uuid
[3],
521 uuid
[4], uuid
[5], uuid
[6], uuid
[7],
522 uuid
[8], uuid
[9], uuid
[10], uuid
[11],
523 uuid
[12], uuid
[13], uuid
[14], uuid
[15]);
524 if (clock_class
->description
) {
525 g_string_append_printf(context
->string
, "\tdescription = \"%s\";\n",
526 clock_class
->description
->str
);
529 g_string_append_printf(context
->string
, "\tfreq = %" PRIu64
";\n",
530 clock_class
->frequency
);
531 g_string_append_printf(context
->string
, "\tprecision = %" PRIu64
";\n",
532 clock_class
->precision
);
533 g_string_append_printf(context
->string
, "\toffset_s = %" PRIu64
";\n",
534 clock_class
->offset_s
);
535 g_string_append_printf(context
->string
, "\toffset = %" PRIu64
";\n",
536 clock_class
->offset
);
537 g_string_append_printf(context
->string
, "\tabsolute = %s;\n",
538 clock_class
->absolute
? "TRUE" : "FALSE");
539 g_string_append(context
->string
, "};\n\n");
543 void bt_ctf_clock_class_destroy(struct bt_object
*obj
)
545 struct bt_ctf_clock_class
*clock_class
;
547 BT_LOGD("Destroying clock class: addr=%p", obj
);
548 clock_class
= container_of(obj
, struct bt_ctf_clock_class
, base
);
549 if (clock_class
->name
) {
550 g_string_free(clock_class
->name
, TRUE
);
552 if (clock_class
->description
) {
553 g_string_free(clock_class
->description
, TRUE
);
560 void bt_ctf_clock_value_destroy(struct bt_object
*obj
)
562 struct bt_ctf_clock_value
*value
;
564 BT_LOGD("Destroying clock value: addr=%p", obj
);
570 value
= container_of(obj
, struct bt_ctf_clock_value
, base
);
571 bt_put(value
->clock_class
);
575 struct bt_ctf_clock_value
*bt_ctf_clock_value_create(
576 struct bt_ctf_clock_class
*clock_class
, uint64_t value
)
578 struct bt_ctf_clock_value
*ret
= NULL
;
580 BT_LOGD("Creating clock value object: clock-class-addr=%p, "
581 "value=%" PRIu64
, clock_class
, value
);
584 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
588 ret
= g_new0(struct bt_ctf_clock_value
, 1);
590 BT_LOGE_STR("Failed to allocate one clock value.");
594 bt_object_init(ret
, bt_ctf_clock_value_destroy
);
595 ret
->clock_class
= bt_get(clock_class
);
597 BT_LOGD("Created clock value object: addr=%p", ret
);
602 int bt_ctf_clock_value_get_value(
603 struct bt_ctf_clock_value
*clock_value
, uint64_t *raw_value
)
607 if (!clock_value
|| !raw_value
) {
608 BT_LOGW("Invalid parameter: clock value or raw value is NULL: "
609 "clock-value-addr=%p, raw-value-addr=%p",
610 clock_value
, raw_value
);
615 *raw_value
= clock_value
->value
;
620 int bt_ctf_clock_value_get_value_ns_from_epoch(struct bt_ctf_clock_value
*value
,
621 int64_t *ret_value_ns
)
626 if (!value
|| !ret_value_ns
) {
627 BT_LOGW("Invalid parameter: clock value or return value pointer is NULL: "
628 "clock-value-addr=%p, ret-value-addr=%p",
629 value
, ret_value_ns
);
634 /* Initialize nanosecond timestamp to clock's offset in seconds. */
635 ns
= value
->clock_class
->offset_s
* (int64_t) 1000000000;
637 /* Add offset in cycles, converted to nanoseconds. */
638 ns
+= ns_from_value(value
->clock_class
->frequency
,
639 value
->clock_class
->offset
);
641 /* Add given value, converter to nanoseconds. */
642 ns
+= ns_from_value(value
->clock_class
->frequency
, value
->value
);
649 struct bt_ctf_clock_class
*bt_ctf_clock_value_get_class(
650 struct bt_ctf_clock_value
*clock_value
)
652 struct bt_ctf_clock_class
*clock_class
= NULL
;
655 BT_LOGW_STR("Invalid parameter: clock value is NULL.");
659 clock_class
= bt_get(clock_value
->clock_class
);