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.h>
37 void bt_ctf_clock_class_destroy(struct bt_object
*obj
);
40 bool bt_ctf_clock_class_is_valid(struct bt_ctf_clock_class
*clock_class
)
42 return clock_class
&& clock_class
->name
;
45 int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class
*clock_class
,
50 if (!clock_class
|| clock_class
->frozen
) {
55 if (bt_ctf_validate_identifier(name
)) {
60 if (clock_class
->name
) {
61 g_string_assign(clock_class
->name
, name
);
63 clock_class
->name
= g_string_new(name
);
64 if (!clock_class
->name
) {
74 struct bt_ctf_clock_class
*bt_ctf_clock_class_create(const char *name
)
77 struct bt_ctf_clock_class
*clock_class
=
78 g_new0(struct bt_ctf_clock_class
, 1);
84 clock_class
->precision
= 1;
85 clock_class
->frequency
= 1000000000;
86 bt_object_init(clock_class
, bt_ctf_clock_class_destroy
);
89 ret
= bt_ctf_clock_class_set_name(clock_class
, name
);
95 ret
= bt_uuid_generate(clock_class
->uuid
);
100 clock_class
->uuid_set
= 1;
107 const char *bt_ctf_clock_class_get_name(struct bt_ctf_clock_class
*clock_class
)
109 const char *ret
= NULL
;
115 if (clock_class
->name
) {
116 ret
= clock_class
->name
->str
;
123 const char *bt_ctf_clock_class_get_description(
124 struct bt_ctf_clock_class
*clock_class
)
126 const char *ret
= NULL
;
132 if (clock_class
->description
) {
133 ret
= clock_class
->description
->str
;
139 int bt_ctf_clock_class_set_description(struct bt_ctf_clock_class
*clock_class
,
144 if (!clock_class
|| !desc
|| clock_class
->frozen
) {
149 clock_class
->description
= g_string_new(desc
);
150 ret
= clock_class
->description
? 0 : -1;
155 uint64_t bt_ctf_clock_class_get_frequency(
156 struct bt_ctf_clock_class
*clock_class
)
158 uint64_t ret
= -1ULL;
164 ret
= clock_class
->frequency
;
169 int bt_ctf_clock_class_set_frequency(struct bt_ctf_clock_class
*clock_class
,
174 if (!clock_class
|| clock_class
->frozen
) {
179 clock_class
->frequency
= freq
;
184 uint64_t bt_ctf_clock_class_get_precision(struct bt_ctf_clock_class
*clock_class
)
186 uint64_t ret
= -1ULL;
192 ret
= clock_class
->precision
;
197 int bt_ctf_clock_class_set_precision(struct bt_ctf_clock_class
*clock_class
,
202 if (!clock_class
|| clock_class
->frozen
) {
207 clock_class
->precision
= precision
;
212 int bt_ctf_clock_class_get_offset_s(struct bt_ctf_clock_class
*clock_class
,
217 if (!clock_class
|| !offset_s
) {
222 *offset_s
= clock_class
->offset_s
;
227 int bt_ctf_clock_class_set_offset_s(struct bt_ctf_clock_class
*clock_class
,
232 if (!clock_class
|| clock_class
->frozen
) {
237 clock_class
->offset_s
= offset_s
;
242 int bt_ctf_clock_class_get_offset_cycles(struct bt_ctf_clock_class
*clock_class
,
247 if (!clock_class
|| !offset
) {
252 *offset
= clock_class
->offset
;
257 int bt_ctf_clock_class_set_offset_cycles(struct bt_ctf_clock_class
*clock_class
,
262 if (!clock_class
|| clock_class
->frozen
) {
267 clock_class
->offset
= offset
;
272 int bt_ctf_clock_class_get_is_absolute(struct bt_ctf_clock_class
*clock_class
)
280 ret
= clock_class
->absolute
;
285 int bt_ctf_clock_class_set_is_absolute(struct bt_ctf_clock_class
*clock_class
,
290 if (!clock_class
|| clock_class
->frozen
) {
295 clock_class
->absolute
= !!is_absolute
;
300 const unsigned char *bt_ctf_clock_class_get_uuid(
301 struct bt_ctf_clock_class
*clock_class
)
303 const unsigned char *ret
;
305 if (!clock_class
|| !clock_class
->uuid_set
) {
310 ret
= clock_class
->uuid
;
315 int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class
*clock_class
,
316 const unsigned char *uuid
)
320 if (!clock_class
|| !uuid
|| clock_class
->frozen
) {
325 memcpy(clock_class
->uuid
, uuid
, sizeof(uuid_t
));
326 clock_class
->uuid_set
= 1;
331 static uint64_t ns_from_value(uint64_t frequency
, uint64_t value
)
335 if (frequency
== 1000000000) {
338 ns
= (uint64_t) ((1e9
* (double) value
) / (double) frequency
);
345 void bt_ctf_clock_class_freeze(struct bt_ctf_clock_class
*clock_class
)
351 clock_class
->frozen
= 1;
355 void bt_ctf_clock_class_serialize(struct bt_ctf_clock_class
*clock_class
,
356 struct metadata_context
*context
)
360 if (!clock_class
|| !context
) {
364 uuid
= clock_class
->uuid
;
365 g_string_append(context
->string
, "clock {\n");
366 g_string_append_printf(context
->string
, "\tname = %s;\n",
367 clock_class
->name
->str
);
368 g_string_append_printf(context
->string
,
369 "\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n",
370 uuid
[0], uuid
[1], uuid
[2], uuid
[3],
371 uuid
[4], uuid
[5], uuid
[6], uuid
[7],
372 uuid
[8], uuid
[9], uuid
[10], uuid
[11],
373 uuid
[12], uuid
[13], uuid
[14], uuid
[15]);
374 if (clock_class
->description
) {
375 g_string_append_printf(context
->string
, "\tdescription = \"%s\";\n",
376 clock_class
->description
->str
);
379 g_string_append_printf(context
->string
, "\tfreq = %" PRIu64
";\n",
380 clock_class
->frequency
);
381 g_string_append_printf(context
->string
, "\tprecision = %" PRIu64
";\n",
382 clock_class
->precision
);
383 g_string_append_printf(context
->string
, "\toffset_s = %" PRIu64
";\n",
384 clock_class
->offset_s
);
385 g_string_append_printf(context
->string
, "\toffset = %" PRIu64
";\n",
386 clock_class
->offset
);
387 g_string_append_printf(context
->string
, "\tabsolute = %s;\n",
388 clock_class
->absolute
? "TRUE" : "FALSE");
389 g_string_append(context
->string
, "};\n\n");
393 void bt_ctf_clock_class_destroy(struct bt_object
*obj
)
395 struct bt_ctf_clock_class
*clock_class
;
397 clock_class
= container_of(obj
, struct bt_ctf_clock_class
, base
);
398 if (clock_class
->name
) {
399 g_string_free(clock_class
->name
, TRUE
);
401 if (clock_class
->description
) {
402 g_string_free(clock_class
->description
, TRUE
);
409 void bt_ctf_clock_value_destroy(struct bt_object
*obj
)
411 struct bt_ctf_clock_value
*value
;
417 value
= container_of(obj
, struct bt_ctf_clock_value
, base
);
418 bt_put(value
->clock_class
);
422 struct bt_ctf_clock_value
*bt_ctf_clock_value_create(
423 struct bt_ctf_clock_class
*clock_class
, uint64_t value
)
425 struct bt_ctf_clock_value
*ret
= NULL
;
431 ret
= g_new0(struct bt_ctf_clock_value
, 1);
436 bt_object_init(ret
, bt_ctf_clock_value_destroy
);
437 ret
->clock_class
= bt_get(clock_class
);
443 int bt_ctf_clock_value_get_value(
444 struct bt_ctf_clock_value
*clock_value
, uint64_t *raw_value
)
448 if (!clock_value
|| !raw_value
) {
453 *raw_value
= clock_value
->value
;
458 int bt_ctf_clock_value_get_value_ns_from_epoch(struct bt_ctf_clock_value
*value
,
459 int64_t *ret_value_ns
)
464 if (!value
|| !ret_value_ns
) {
469 /* Initialize nanosecond timestamp to clock's offset in seconds. */
470 ns
= value
->clock_class
->offset_s
* 1000000000;
472 /* Add offset in cycles, converted to nanoseconds. */
473 ns
+= ns_from_value(value
->clock_class
->frequency
,
474 value
->clock_class
->offset
);
476 /* Add given value, converter to nanoseconds. */
477 ns
+= ns_from_value(value
->clock_class
->frequency
, value
->value
);
484 struct bt_ctf_clock_class
*bt_ctf_clock_value_get_class(
485 struct bt_ctf_clock_value
*clock_value
)
487 struct bt_ctf_clock_class
*clock_class
= NULL
;
493 clock_class
= bt_get(clock_value
->clock_class
);