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>
37 #include <babeltrace/compat/string-internal.h>
39 #include <babeltrace/object-internal.h>
42 void bt_ctf_clock_class_destroy(struct bt_object
*obj
);
45 bt_bool
bt_ctf_clock_class_is_valid(struct bt_ctf_clock_class
*clock_class
)
47 return clock_class
&& clock_class
->name
;
50 int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class
*clock_class
,
56 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
61 if (clock_class
->frozen
) {
62 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
63 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
68 if (bt_ctf_validate_identifier(name
)) {
69 BT_LOGE("Clock class's name is not a valid CTF identifier: "
70 "addr=%p, name=\"%s\"",
76 if (clock_class
->name
) {
77 g_string_assign(clock_class
->name
, name
);
79 clock_class
->name
= g_string_new(name
);
80 if (!clock_class
->name
) {
81 BT_LOGE_STR("Failed to allocate a GString.");
87 BT_LOGV("Set clock class's name: addr=%p, name=\"%s\"",
94 struct bt_ctf_clock_class
*bt_ctf_clock_class_create(const char *name
)
97 struct bt_ctf_clock_class
*clock_class
;
99 BT_LOGD("Creating default clock class object: name=\"%s\"",
101 clock_class
= g_new0(struct bt_ctf_clock_class
, 1);
103 BT_LOGE_STR("Failed to allocate one clock class.");
107 clock_class
->precision
= 1;
108 clock_class
->frequency
= 1000000000;
109 bt_object_init(clock_class
, bt_ctf_clock_class_destroy
);
112 ret
= bt_ctf_clock_class_set_name(clock_class
, name
);
114 BT_LOGE("Cannot set clock class's name: "
115 "addr=%p, name=\"%s\"",
121 ret
= bt_uuid_generate(clock_class
->uuid
);
123 BT_LOGE_STR("Failed to generate a UUID.");
127 clock_class
->uuid_set
= 1;
128 BT_LOGD("Created clock class object: addr=%p, name=\"%s\"",
136 const char *bt_ctf_clock_class_get_name(struct bt_ctf_clock_class
*clock_class
)
138 const char *ret
= NULL
;
141 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
145 if (clock_class
->name
) {
146 ret
= clock_class
->name
->str
;
153 const char *bt_ctf_clock_class_get_description(
154 struct bt_ctf_clock_class
*clock_class
)
156 const char *ret
= NULL
;
159 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
163 if (clock_class
->description
) {
164 ret
= clock_class
->description
->str
;
170 int bt_ctf_clock_class_set_description(struct bt_ctf_clock_class
*clock_class
,
175 if (!clock_class
|| !desc
) {
176 BT_LOGW("Invalid parameter: clock class or description is NULL: "
177 "clock-class-addr=%p, name=\"%s\", desc-addr=%p",
178 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
184 if (clock_class
->frozen
) {
185 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
186 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
191 clock_class
->description
= g_string_new(desc
);
192 ret
= clock_class
->description
? 0 : -1;
193 BT_LOGV("Set clock class's description: addr=%p, "
194 "name=\"%s\", desc=\"%s\"",
195 clock_class
, bt_ctf_clock_class_get_name(clock_class
), desc
);
200 uint64_t bt_ctf_clock_class_get_frequency(
201 struct bt_ctf_clock_class
*clock_class
)
203 uint64_t ret
= -1ULL;
206 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
210 ret
= clock_class
->frequency
;
215 int bt_ctf_clock_class_set_frequency(struct bt_ctf_clock_class
*clock_class
,
220 if (!clock_class
|| freq
== -1ULL) {
221 BT_LOGW("Invalid parameter: clock class is NULL or frequency is invalid: "
222 "addr=%p, name=\"%s\", freq=%" PRIu64
,
223 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
229 if (clock_class
->frozen
) {
230 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
231 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
236 clock_class
->frequency
= freq
;
237 BT_LOGV("Set clock class's frequency: addr=%p, name=\"%s\", freq=%" PRIu64
,
238 clock_class
, bt_ctf_clock_class_get_name(clock_class
), freq
);
243 uint64_t bt_ctf_clock_class_get_precision(struct bt_ctf_clock_class
*clock_class
)
245 uint64_t ret
= -1ULL;
248 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
252 ret
= clock_class
->precision
;
257 int bt_ctf_clock_class_set_precision(struct bt_ctf_clock_class
*clock_class
,
262 if (!clock_class
|| precision
== -1ULL) {
263 BT_LOGW("Invalid parameter: clock class is NULL or precision is invalid: "
264 "addr=%p, name=\"%s\", precision=%" PRIu64
,
265 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
271 if (clock_class
->frozen
) {
272 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
273 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
278 clock_class
->precision
= precision
;
279 BT_LOGV("Set clock class's precision: addr=%p, name=\"%s\", precision=%" PRIu64
,
280 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
286 int bt_ctf_clock_class_get_offset_s(struct bt_ctf_clock_class
*clock_class
,
291 if (!clock_class
|| !offset_s
) {
292 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
293 "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
294 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
300 *offset_s
= clock_class
->offset_s
;
305 int bt_ctf_clock_class_set_offset_s(struct bt_ctf_clock_class
*clock_class
,
311 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
316 if (clock_class
->frozen
) {
317 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
318 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
323 clock_class
->offset_s
= offset_s
;
324 BT_LOGV("Set clock class's offset (seconds): "
325 "addr=%p, name=\"%s\", offset-s=%" PRId64
,
326 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
332 int bt_ctf_clock_class_get_offset_cycles(struct bt_ctf_clock_class
*clock_class
,
337 if (!clock_class
|| !offset
) {
338 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
339 "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
340 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
346 *offset
= clock_class
->offset
;
351 int bt_ctf_clock_class_set_offset_cycles(struct bt_ctf_clock_class
*clock_class
,
357 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
362 if (clock_class
->frozen
) {
363 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
364 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
369 clock_class
->offset
= offset
;
370 BT_LOGV("Set clock class's offset (cycles): addr=%p, name=\"%s\", offset-cycles=%" PRId64
,
371 clock_class
, bt_ctf_clock_class_get_name(clock_class
), offset
);
376 bt_bool
bt_ctf_clock_class_is_absolute(struct bt_ctf_clock_class
*clock_class
)
381 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
385 ret
= clock_class
->absolute
;
390 int bt_ctf_clock_class_set_is_absolute(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
->absolute
= !!is_absolute
;
409 BT_LOGV("Set clock class's absolute flag: addr=%p, name=\"%s\", is-absolute=%d",
410 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
416 const unsigned char *bt_ctf_clock_class_get_uuid(
417 struct bt_ctf_clock_class
*clock_class
)
419 const unsigned char *ret
;
422 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
427 if (!clock_class
->uuid_set
) {
428 BT_LOGV("Clock class's UUID is not set: addr=%p, name=\"%s\"",
429 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
434 ret
= clock_class
->uuid
;
439 int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class
*clock_class
,
440 const unsigned char *uuid
)
444 if (!clock_class
|| !uuid
) {
445 BT_LOGW("Invalid parameter: clock class or UUID is NULL: "
446 "clock-class-addr=%p, name=\"%s\", uuid-addr=%p",
447 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
453 if (clock_class
->frozen
) {
454 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
455 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
460 memcpy(clock_class
->uuid
, uuid
, BABELTRACE_UUID_LEN
);
461 clock_class
->uuid_set
= 1;
462 BT_LOGV("Set clock class's UUID: addr=%p, name=\"%s\", "
463 "uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"",
464 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
465 (unsigned int) uuid
[0],
466 (unsigned int) uuid
[1],
467 (unsigned int) uuid
[2],
468 (unsigned int) uuid
[3],
469 (unsigned int) uuid
[4],
470 (unsigned int) uuid
[5],
471 (unsigned int) uuid
[6],
472 (unsigned int) uuid
[7],
473 (unsigned int) uuid
[8],
474 (unsigned int) uuid
[9],
475 (unsigned int) uuid
[10],
476 (unsigned int) uuid
[11],
477 (unsigned int) uuid
[12],
478 (unsigned int) uuid
[13],
479 (unsigned int) uuid
[14],
480 (unsigned int) uuid
[15]);
485 static uint64_t ns_from_value(uint64_t frequency
, uint64_t value
)
489 if (frequency
== 1000000000) {
492 ns
= (uint64_t) ((1e9
* (double) value
) / (double) frequency
);
499 void bt_ctf_clock_class_freeze(struct bt_ctf_clock_class
*clock_class
)
502 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
506 if (!clock_class
->frozen
) {
507 BT_LOGD("Freezing clock class: addr=%p, name=\"%s\"",
508 clock_class
, bt_ctf_clock_class_get_name(clock_class
));
509 clock_class
->frozen
= 1;
514 void bt_ctf_clock_class_serialize(struct bt_ctf_clock_class
*clock_class
,
515 struct metadata_context
*context
)
519 BT_LOGD("Serializing clock class's metadata: clock-class-addr=%p, "
520 "name=\"%s\", metadata-context-addr=%p", clock_class
,
521 bt_ctf_clock_class_get_name(clock_class
), context
);
523 if (!clock_class
|| !context
) {
524 BT_LOGW("Invalid parameter: clock class or metadata context is NULL: "
525 "clock-class-addr=%p, name=\"%s\", metadata-context-addr=%p",
526 clock_class
, bt_ctf_clock_class_get_name(clock_class
),
531 uuid
= clock_class
->uuid
;
532 g_string_append(context
->string
, "clock {\n");
533 g_string_append_printf(context
->string
, "\tname = %s;\n",
534 clock_class
->name
->str
);
535 g_string_append_printf(context
->string
,
536 "\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n",
537 uuid
[0], uuid
[1], uuid
[2], uuid
[3],
538 uuid
[4], uuid
[5], uuid
[6], uuid
[7],
539 uuid
[8], uuid
[9], uuid
[10], uuid
[11],
540 uuid
[12], uuid
[13], uuid
[14], uuid
[15]);
541 if (clock_class
->description
) {
542 g_string_append_printf(context
->string
, "\tdescription = \"%s\";\n",
543 clock_class
->description
->str
);
546 g_string_append_printf(context
->string
, "\tfreq = %" PRIu64
";\n",
547 clock_class
->frequency
);
548 g_string_append_printf(context
->string
, "\tprecision = %" PRIu64
";\n",
549 clock_class
->precision
);
550 g_string_append_printf(context
->string
, "\toffset_s = %" PRIu64
";\n",
551 clock_class
->offset_s
);
552 g_string_append_printf(context
->string
, "\toffset = %" PRIu64
";\n",
553 clock_class
->offset
);
554 g_string_append_printf(context
->string
, "\tabsolute = %s;\n",
555 clock_class
->absolute
? "TRUE" : "FALSE");
556 g_string_append(context
->string
, "};\n\n");
560 void bt_ctf_clock_class_destroy(struct bt_object
*obj
)
562 struct bt_ctf_clock_class
*clock_class
;
564 clock_class
= container_of(obj
, struct bt_ctf_clock_class
, base
);
565 BT_LOGD("Destroying clock class: addr=%p, name=\"%s\"",
566 obj
, bt_ctf_clock_class_get_name(clock_class
));
567 if (clock_class
->name
) {
568 g_string_free(clock_class
->name
, TRUE
);
570 if (clock_class
->description
) {
571 g_string_free(clock_class
->description
, TRUE
);
578 void bt_ctf_clock_value_destroy(struct bt_object
*obj
)
580 struct bt_ctf_clock_value
*value
;
586 value
= container_of(obj
, struct bt_ctf_clock_value
, base
);
587 BT_LOGD("Destroying clock value: addr=%p, clock-class-addr=%p, "
588 "clock-class-name=\"%s\"", obj
, value
->clock_class
,
589 bt_ctf_clock_class_get_name(value
->clock_class
));
590 bt_put(value
->clock_class
);
594 struct bt_ctf_clock_value
*bt_ctf_clock_value_create(
595 struct bt_ctf_clock_class
*clock_class
, uint64_t value
)
597 struct bt_ctf_clock_value
*ret
= NULL
;
599 BT_LOGD("Creating clock value object: clock-class-addr=%p, "
600 "clock-class-name=\"%s\", value=%" PRIu64
, clock_class
,
601 bt_ctf_clock_class_get_name(clock_class
), value
);
604 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
608 ret
= g_new0(struct bt_ctf_clock_value
, 1);
610 BT_LOGE_STR("Failed to allocate one clock value.");
614 bt_object_init(ret
, bt_ctf_clock_value_destroy
);
615 ret
->clock_class
= bt_get(clock_class
);
617 BT_LOGD("Created clock value object: clock-value-addr=%p, "
618 "clock-class-addr=%p, clock-class-name=\"%s\"",
619 ret
, clock_class
, bt_ctf_clock_class_get_name(clock_class
));
624 int bt_ctf_clock_value_get_value(
625 struct bt_ctf_clock_value
*clock_value
, uint64_t *raw_value
)
629 if (!clock_value
|| !raw_value
) {
630 BT_LOGW("Invalid parameter: clock value or raw value is NULL: "
631 "clock-value-addr=%p, raw-value-addr=%p",
632 clock_value
, raw_value
);
637 *raw_value
= clock_value
->value
;
642 int bt_ctf_clock_value_get_value_ns_from_epoch(struct bt_ctf_clock_value
*value
,
643 int64_t *ret_value_ns
)
648 if (!value
|| !ret_value_ns
) {
649 BT_LOGW("Invalid parameter: clock value or return value pointer is NULL: "
650 "clock-value-addr=%p, ret-value-addr=%p",
651 value
, ret_value_ns
);
656 /* Initialize nanosecond timestamp to clock's offset in seconds. */
657 ns
= value
->clock_class
->offset_s
* (int64_t) 1000000000;
659 /* Add offset in cycles, converted to nanoseconds. */
660 ns
+= ns_from_value(value
->clock_class
->frequency
,
661 value
->clock_class
->offset
);
663 /* Add given value, converter to nanoseconds. */
664 ns
+= ns_from_value(value
->clock_class
->frequency
, value
->value
);
671 struct bt_ctf_clock_class
*bt_ctf_clock_value_get_class(
672 struct bt_ctf_clock_value
*clock_value
)
674 struct bt_ctf_clock_class
*clock_class
= NULL
;
677 BT_LOGW_STR("Invalid parameter: clock value is NULL.");
681 clock_class
= bt_get(clock_value
->clock_class
);