ctf, ir: escape and unescape enumeration FT labels starting with `_`
[babeltrace.git] / lib / ctf-ir / clock-class.c
1 /*
2 * clock-class.c
3 *
4 * Babeltrace CTF IR - Clock class
5 *
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
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:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
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
26 * SOFTWARE.
27 */
28
29 #define BT_LOG_TAG "CLOCK-CLASS"
30 #include <babeltrace/lib-logging-internal.h>
31
32 #include <babeltrace/compat/uuid-internal.h>
33 #include <babeltrace/ctf-ir/clock-class-internal.h>
34 #include <babeltrace/ctf-ir/clock-value-internal.h>
35 #include <babeltrace/ctf-ir/utils.h>
36 #include <babeltrace/ref.h>
37 #include <babeltrace/compiler-internal.h>
38 #include <babeltrace/types.h>
39 #include <babeltrace/compat/string-internal.h>
40 #include <inttypes.h>
41 #include <babeltrace/object-internal.h>
42
43 static
44 void bt_clock_class_destroy(struct bt_object *obj);
45
46 BT_HIDDEN
47 bt_bool bt_clock_class_is_valid(struct bt_clock_class *clock_class)
48 {
49 return clock_class && clock_class->name;
50 }
51
52 int bt_clock_class_set_name(struct bt_clock_class *clock_class,
53 const char *name)
54 {
55 int ret = 0;
56
57 if (!clock_class) {
58 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
59 ret = -1;
60 goto end;
61 }
62
63 if (clock_class->frozen) {
64 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
65 clock_class, bt_clock_class_get_name(clock_class));
66 ret = -1;
67 goto end;
68 }
69
70 if (!bt_identifier_is_valid(name)) {
71 BT_LOGE("Clock class's name is not a valid CTF identifier: "
72 "addr=%p, name=\"%s\"",
73 clock_class, name);
74 ret = -1;
75 goto end;
76 }
77
78 if (clock_class->name) {
79 g_string_assign(clock_class->name, name);
80 } else {
81 clock_class->name = g_string_new(name);
82 if (!clock_class->name) {
83 BT_LOGE_STR("Failed to allocate a GString.");
84 ret = -1;
85 goto end;
86 }
87 }
88
89 BT_LOGV("Set clock class's name: addr=%p, name=\"%s\"",
90 clock_class, name);
91
92 end:
93 return ret;
94 }
95
96 static
97 bool validate_freq(struct bt_clock_class *clock_class,
98 const char *name, uint64_t freq)
99 {
100 bool is_valid = true;
101
102 if (freq == -1ULL || freq == 0) {
103 BT_LOGW("Invalid parameter: frequency is invalid: "
104 "addr=%p, name=\"%s\", freq=%" PRIu64,
105 clock_class, name, freq);
106 is_valid = false;
107 goto end;
108 }
109
110 end:
111 return is_valid;
112 }
113
114 struct bt_clock_class *bt_clock_class_create(const char *name,
115 uint64_t freq)
116 {
117 int ret;
118 struct bt_clock_class *clock_class = NULL;
119
120 BT_LOGD("Creating default clock class object: name=\"%s\"",
121 name);
122
123 if (!validate_freq(NULL, name, freq)) {
124 /* validate_freq() logs errors */
125 goto error;
126 }
127
128 clock_class = g_new0(struct bt_clock_class, 1);
129 if (!clock_class) {
130 BT_LOGE_STR("Failed to allocate one clock class.");
131 goto error;
132 }
133
134 clock_class->precision = 1;
135 clock_class->frequency = freq;
136 bt_object_init(clock_class, bt_clock_class_destroy);
137
138 if (name) {
139 ret = bt_clock_class_set_name(clock_class, name);
140 if (ret) {
141 BT_LOGE("Cannot set clock class's name: "
142 "addr=%p, name=\"%s\"",
143 clock_class, name);
144 goto error;
145 }
146 }
147
148 BT_LOGD("Created clock class object: addr=%p, name=\"%s\"",
149 clock_class, name);
150 return clock_class;
151 error:
152 BT_PUT(clock_class);
153 return clock_class;
154 }
155
156 const char *bt_clock_class_get_name(struct bt_clock_class *clock_class)
157 {
158 const char *ret = NULL;
159
160 if (!clock_class) {
161 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
162 goto end;
163 }
164
165 if (clock_class->name) {
166 ret = clock_class->name->str;
167 }
168
169 end:
170 return ret;
171 }
172
173 const char *bt_clock_class_get_description(
174 struct bt_clock_class *clock_class)
175 {
176 const char *ret = NULL;
177
178 if (!clock_class) {
179 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
180 goto end;
181 }
182
183 if (clock_class->description) {
184 ret = clock_class->description->str;
185 }
186 end:
187 return ret;
188 }
189
190 int bt_clock_class_set_description(struct bt_clock_class *clock_class,
191 const char *desc)
192 {
193 int ret = 0;
194
195 if (!clock_class || !desc) {
196 BT_LOGW("Invalid parameter: clock class or description is NULL: "
197 "clock-class-addr=%p, name=\"%s\", desc-addr=%p",
198 clock_class, bt_clock_class_get_name(clock_class),
199 desc);
200 ret = -1;
201 goto end;
202 }
203
204 if (clock_class->frozen) {
205 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
206 clock_class, bt_clock_class_get_name(clock_class));
207 ret = -1;
208 goto end;
209 }
210
211 clock_class->description = g_string_new(desc);
212 ret = clock_class->description ? 0 : -1;
213 BT_LOGV("Set clock class's description: addr=%p, "
214 "name=\"%s\", desc=\"%s\"",
215 clock_class, bt_clock_class_get_name(clock_class), desc);
216 end:
217 return ret;
218 }
219
220 uint64_t bt_clock_class_get_frequency(
221 struct bt_clock_class *clock_class)
222 {
223 uint64_t ret = -1ULL;
224
225 if (!clock_class) {
226 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
227 goto end;
228 }
229
230 ret = clock_class->frequency;
231 end:
232 return ret;
233 }
234
235 int bt_clock_class_set_frequency(struct bt_clock_class *clock_class,
236 uint64_t freq)
237 {
238 int ret = 0;
239
240 if (!clock_class) {
241 BT_LOGW("Invalid parameter: clock class is NULL or frequency is invalid: "
242 "addr=%p, name=\"%s\"",
243 clock_class, bt_clock_class_get_name(clock_class));
244 ret = -1;
245 goto end;
246 }
247
248 if (!validate_freq(clock_class, bt_clock_class_get_name(clock_class),
249 freq)) {
250 /* validate_freq() logs errors */
251 goto end;
252 }
253
254 if (clock_class->frozen) {
255 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
256 clock_class, bt_clock_class_get_name(clock_class));
257 ret = -1;
258 goto end;
259 }
260
261 clock_class->frequency = freq;
262 BT_LOGV("Set clock class's frequency: addr=%p, name=\"%s\", freq=%" PRIu64,
263 clock_class, bt_clock_class_get_name(clock_class), freq);
264 end:
265 return ret;
266 }
267
268 uint64_t bt_clock_class_get_precision(struct bt_clock_class *clock_class)
269 {
270 uint64_t ret = -1ULL;
271
272 if (!clock_class) {
273 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
274 goto end;
275 }
276
277 ret = clock_class->precision;
278 end:
279 return ret;
280 }
281
282 int bt_clock_class_set_precision(struct bt_clock_class *clock_class,
283 uint64_t precision)
284 {
285 int ret = 0;
286
287 if (!clock_class || precision == -1ULL) {
288 BT_LOGW("Invalid parameter: clock class is NULL or precision is invalid: "
289 "addr=%p, name=\"%s\", precision=%" PRIu64,
290 clock_class, bt_clock_class_get_name(clock_class),
291 precision);
292 ret = -1;
293 goto end;
294 }
295
296 if (clock_class->frozen) {
297 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
298 clock_class, bt_clock_class_get_name(clock_class));
299 ret = -1;
300 goto end;
301 }
302
303 clock_class->precision = precision;
304 BT_LOGV("Set clock class's precision: addr=%p, name=\"%s\", precision=%" PRIu64,
305 clock_class, bt_clock_class_get_name(clock_class),
306 precision);
307 end:
308 return ret;
309 }
310
311 int bt_clock_class_get_offset_s(struct bt_clock_class *clock_class,
312 int64_t *offset_s)
313 {
314 int ret = 0;
315
316 if (!clock_class || !offset_s) {
317 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
318 "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
319 clock_class, bt_clock_class_get_name(clock_class),
320 offset_s);
321 ret = -1;
322 goto end;
323 }
324
325 *offset_s = clock_class->offset_s;
326 end:
327 return ret;
328 }
329
330 int bt_clock_class_set_offset_s(struct bt_clock_class *clock_class,
331 int64_t offset_s)
332 {
333 int ret = 0;
334
335 if (!clock_class) {
336 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
337 ret = -1;
338 goto end;
339 }
340
341 if (clock_class->frozen) {
342 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
343 clock_class, bt_clock_class_get_name(clock_class));
344 ret = -1;
345 goto end;
346 }
347
348 clock_class->offset_s = offset_s;
349 BT_LOGV("Set clock class's offset (seconds): "
350 "addr=%p, name=\"%s\", offset-s=%" PRId64,
351 clock_class, bt_clock_class_get_name(clock_class),
352 offset_s);
353 end:
354 return ret;
355 }
356
357 int bt_clock_class_get_offset_cycles(struct bt_clock_class *clock_class,
358 int64_t *offset)
359 {
360 int ret = 0;
361
362 if (!clock_class || !offset) {
363 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
364 "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
365 clock_class, bt_clock_class_get_name(clock_class),
366 offset);
367 ret = -1;
368 goto end;
369 }
370
371 *offset = clock_class->offset;
372 end:
373 return ret;
374 }
375
376 int bt_clock_class_set_offset_cycles(struct bt_clock_class *clock_class,
377 int64_t offset)
378 {
379 int ret = 0;
380
381 if (!clock_class) {
382 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
383 ret = -1;
384 goto end;
385 }
386
387 if (clock_class->frozen) {
388 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
389 clock_class, bt_clock_class_get_name(clock_class));
390 ret = -1;
391 goto end;
392 }
393
394 clock_class->offset = offset;
395 BT_LOGV("Set clock class's offset (cycles): addr=%p, name=\"%s\", offset-cycles=%" PRId64,
396 clock_class, bt_clock_class_get_name(clock_class), offset);
397 end:
398 return ret;
399 }
400
401 bt_bool bt_clock_class_is_absolute(struct bt_clock_class *clock_class)
402 {
403 int ret = -1;
404
405 if (!clock_class) {
406 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
407 goto end;
408 }
409
410 ret = clock_class->absolute;
411 end:
412 return ret;
413 }
414
415 int bt_clock_class_set_is_absolute(struct bt_clock_class *clock_class,
416 bt_bool is_absolute)
417 {
418 int ret = 0;
419
420 if (!clock_class) {
421 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
422 ret = -1;
423 goto end;
424 }
425
426 if (clock_class->frozen) {
427 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
428 clock_class, bt_clock_class_get_name(clock_class));
429 ret = -1;
430 goto end;
431 }
432
433 clock_class->absolute = !!is_absolute;
434 BT_LOGV("Set clock class's absolute flag: addr=%p, name=\"%s\", is-absolute=%d",
435 clock_class, bt_clock_class_get_name(clock_class),
436 is_absolute);
437 end:
438 return ret;
439 }
440
441 const unsigned char *bt_clock_class_get_uuid(
442 struct bt_clock_class *clock_class)
443 {
444 const unsigned char *ret;
445
446 if (!clock_class) {
447 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
448 ret = NULL;
449 goto end;
450 }
451
452 if (!clock_class->uuid_set) {
453 BT_LOGV("Clock class's UUID is not set: addr=%p, name=\"%s\"",
454 clock_class, bt_clock_class_get_name(clock_class));
455 ret = NULL;
456 goto end;
457 }
458
459 ret = clock_class->uuid;
460 end:
461 return ret;
462 }
463
464 int bt_clock_class_set_uuid(struct bt_clock_class *clock_class,
465 const unsigned char *uuid)
466 {
467 int ret = 0;
468
469 if (!clock_class || !uuid) {
470 BT_LOGW("Invalid parameter: clock class or UUID is NULL: "
471 "clock-class-addr=%p, name=\"%s\", uuid-addr=%p",
472 clock_class, bt_clock_class_get_name(clock_class),
473 uuid);
474 ret = -1;
475 goto end;
476 }
477
478 if (clock_class->frozen) {
479 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
480 clock_class, bt_clock_class_get_name(clock_class));
481 ret = -1;
482 goto end;
483 }
484
485 memcpy(clock_class->uuid, uuid, BABELTRACE_UUID_LEN);
486 clock_class->uuid_set = 1;
487 BT_LOGV("Set clock class's UUID: addr=%p, name=\"%s\", "
488 "uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"",
489 clock_class, bt_clock_class_get_name(clock_class),
490 (unsigned int) uuid[0],
491 (unsigned int) uuid[1],
492 (unsigned int) uuid[2],
493 (unsigned int) uuid[3],
494 (unsigned int) uuid[4],
495 (unsigned int) uuid[5],
496 (unsigned int) uuid[6],
497 (unsigned int) uuid[7],
498 (unsigned int) uuid[8],
499 (unsigned int) uuid[9],
500 (unsigned int) uuid[10],
501 (unsigned int) uuid[11],
502 (unsigned int) uuid[12],
503 (unsigned int) uuid[13],
504 (unsigned int) uuid[14],
505 (unsigned int) uuid[15]);
506 end:
507 return ret;
508 }
509
510 static uint64_t ns_from_value(uint64_t frequency, uint64_t value)
511 {
512 uint64_t ns;
513
514 if (frequency == 1000000000) {
515 ns = value;
516 } else {
517 double dblres = ((1e9 * (double) value) / (double) frequency);
518
519 if (dblres >= (double) UINT64_MAX) {
520 /* Overflows uint64_t */
521 ns = -1ULL;
522 } else {
523 ns = (uint64_t) dblres;
524 }
525 }
526
527 return ns;
528 }
529
530 BT_HIDDEN
531 void bt_clock_class_freeze(struct bt_clock_class *clock_class)
532 {
533 if (!clock_class) {
534 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
535 return;
536 }
537
538 if (!clock_class->frozen) {
539 BT_LOGD("Freezing clock class: addr=%p, name=\"%s\"",
540 clock_class, bt_clock_class_get_name(clock_class));
541 clock_class->frozen = 1;
542 }
543 }
544
545 BT_HIDDEN
546 void bt_clock_class_serialize(struct bt_clock_class *clock_class,
547 struct metadata_context *context)
548 {
549 unsigned char *uuid;
550
551 BT_LOGD("Serializing clock class's metadata: clock-class-addr=%p, "
552 "name=\"%s\", metadata-context-addr=%p", clock_class,
553 bt_clock_class_get_name(clock_class), context);
554
555 if (!clock_class || !context) {
556 BT_LOGW("Invalid parameter: clock class or metadata context is NULL: "
557 "clock-class-addr=%p, name=\"%s\", metadata-context-addr=%p",
558 clock_class, bt_clock_class_get_name(clock_class),
559 context);
560 return;
561 }
562
563 uuid = clock_class->uuid;
564 g_string_append(context->string, "clock {\n");
565 g_string_append_printf(context->string, "\tname = %s;\n",
566 clock_class->name->str);
567
568 if (clock_class->uuid_set) {
569 g_string_append_printf(context->string,
570 "\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n",
571 uuid[0], uuid[1], uuid[2], uuid[3],
572 uuid[4], uuid[5], uuid[6], uuid[7],
573 uuid[8], uuid[9], uuid[10], uuid[11],
574 uuid[12], uuid[13], uuid[14], uuid[15]);
575 }
576
577 if (clock_class->description) {
578 g_string_append_printf(context->string, "\tdescription = \"%s\";\n",
579 clock_class->description->str);
580 }
581
582 g_string_append_printf(context->string, "\tfreq = %" PRIu64 ";\n",
583 clock_class->frequency);
584 g_string_append_printf(context->string, "\tprecision = %" PRIu64 ";\n",
585 clock_class->precision);
586 g_string_append_printf(context->string, "\toffset_s = %" PRIu64 ";\n",
587 clock_class->offset_s);
588 g_string_append_printf(context->string, "\toffset = %" PRIu64 ";\n",
589 clock_class->offset);
590 g_string_append_printf(context->string, "\tabsolute = %s;\n",
591 clock_class->absolute ? "true" : "false");
592 g_string_append(context->string, "};\n\n");
593 }
594
595 static
596 void bt_clock_class_destroy(struct bt_object *obj)
597 {
598 struct bt_clock_class *clock_class;
599
600 clock_class = container_of(obj, struct bt_clock_class, base);
601 BT_LOGD("Destroying clock class: addr=%p, name=\"%s\"",
602 obj, bt_clock_class_get_name(clock_class));
603 if (clock_class->name) {
604 g_string_free(clock_class->name, TRUE);
605 }
606 if (clock_class->description) {
607 g_string_free(clock_class->description, TRUE);
608 }
609
610 g_free(clock_class);
611 }
612
613 static
614 void bt_clock_value_destroy(struct bt_object *obj)
615 {
616 struct bt_clock_value *value;
617
618 if (!obj) {
619 return;
620 }
621
622 value = container_of(obj, struct bt_clock_value, base);
623 BT_LOGD("Destroying clock value: addr=%p, clock-class-addr=%p, "
624 "clock-class-name=\"%s\"", obj, value->clock_class,
625 bt_clock_class_get_name(value->clock_class));
626 bt_put(value->clock_class);
627 g_free(value);
628 }
629
630 static
631 void set_ns_from_epoch(struct bt_clock_value *clock_value)
632 {
633 struct bt_clock_class *clock_class = clock_value->clock_class;
634 int64_t diff;
635 int64_t s_ns;
636 uint64_t u_ns;
637 uint64_t cycles;
638
639 /* Initialize nanosecond timestamp to clock's offset in seconds */
640 if (clock_class->offset_s <= (INT64_MIN / 1000000000) ||
641 clock_class->offset_s >= (INT64_MAX / 1000000000)) {
642 /*
643 * Overflow: offset in seconds converted to nanoseconds
644 * is outside the int64_t range.
645 */
646 clock_value->ns_from_epoch_overflows = true;
647 goto end;
648 }
649
650 clock_value->ns_from_epoch = clock_class->offset_s * (int64_t) 1000000000;
651
652 /* Add offset in cycles */
653 if (clock_class->offset < 0) {
654 cycles = (uint64_t) (-clock_class->offset);
655 } else {
656 cycles = (uint64_t) clock_class->offset;
657 }
658
659 u_ns = ns_from_value(clock_class->frequency, cycles);
660
661 if (u_ns == -1ULL || u_ns >= INT64_MAX) {
662 /*
663 * Overflow: offset in cycles converted to nanoseconds
664 * is outside the int64_t range.
665 */
666 clock_value->ns_from_epoch_overflows = true;
667 goto end;
668 }
669
670 s_ns = (int64_t) u_ns;
671 assert(s_ns >= 0);
672
673 if (clock_class->offset < 0) {
674 if (clock_value->ns_from_epoch >= 0) {
675 /*
676 * Offset in cycles is negative so it must also
677 * be negative once converted to nanoseconds.
678 */
679 s_ns = -s_ns;
680 goto offset_ok;
681 }
682
683 diff = clock_value->ns_from_epoch - INT64_MIN;
684
685 if (s_ns >= diff) {
686 /*
687 * Overflow: current timestamp in nanoseconds
688 * plus the offset in cycles converted to
689 * nanoseconds is outside the int64_t range.
690 */
691 clock_value->ns_from_epoch_overflows = true;
692 goto end;
693 }
694
695 /*
696 * Offset in cycles is negative so it must also be
697 * negative once converted to nanoseconds.
698 */
699 s_ns = -s_ns;
700 } else {
701 if (clock_value->ns_from_epoch <= 0) {
702 goto offset_ok;
703 }
704
705 diff = INT64_MAX - clock_value->ns_from_epoch;
706
707 if (s_ns >= diff) {
708 /*
709 * Overflow: current timestamp in nanoseconds
710 * plus the offset in cycles converted to
711 * nanoseconds is outside the int64_t range.
712 */
713 clock_value->ns_from_epoch_overflows = true;
714 goto end;
715 }
716 }
717
718 offset_ok:
719 clock_value->ns_from_epoch += s_ns;
720
721 /* Add clock value (cycles) */
722 u_ns = ns_from_value(clock_class->frequency, clock_value->value);
723
724 if (u_ns == -1ULL || u_ns >= INT64_MAX) {
725 /*
726 * Overflow: value converted to nanoseconds is outside
727 * the int64_t range.
728 */
729 clock_value->ns_from_epoch_overflows = true;
730 goto end;
731 }
732
733 s_ns = (int64_t) u_ns;
734 assert(s_ns >= 0);
735
736 /* Clock value (cycles) is always positive */
737 if (clock_value->ns_from_epoch <= 0) {
738 goto value_ok;
739 }
740
741 diff = INT64_MAX - clock_value->ns_from_epoch;
742
743 if (s_ns >= diff) {
744 /*
745 * Overflow: current timestamp in nanoseconds plus the
746 * clock value converted to nanoseconds is outside the
747 * int64_t range.
748 */
749 clock_value->ns_from_epoch_overflows = true;
750 goto end;
751 }
752
753 value_ok:
754 clock_value->ns_from_epoch += s_ns;
755
756 end:
757 if (clock_value->ns_from_epoch_overflows) {
758 clock_value->ns_from_epoch = 0;
759 }
760 }
761
762 struct bt_clock_value *bt_clock_value_create(
763 struct bt_clock_class *clock_class, uint64_t value)
764 {
765 struct bt_clock_value *ret = NULL;
766
767 BT_LOGD("Creating clock value object: clock-class-addr=%p, "
768 "clock-class-name=\"%s\", value=%" PRIu64, clock_class,
769 bt_clock_class_get_name(clock_class), value);
770
771 if (!clock_class) {
772 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
773 goto end;
774 }
775
776 ret = g_new0(struct bt_clock_value, 1);
777 if (!ret) {
778 BT_LOGE_STR("Failed to allocate one clock value.");
779 goto end;
780 }
781
782 bt_object_init(ret, bt_clock_value_destroy);
783 ret->clock_class = bt_get(clock_class);
784 ret->value = value;
785 set_ns_from_epoch(ret);
786 bt_clock_class_freeze(clock_class);
787 BT_LOGD("Created clock value object: clock-value-addr=%p, "
788 "clock-class-addr=%p, clock-class-name=\"%s\", "
789 "ns-from-epoch=%" PRId64 ", ns-from-epoch-overflows=%d",
790 ret, clock_class, bt_clock_class_get_name(clock_class),
791 ret->ns_from_epoch, ret->ns_from_epoch_overflows);
792
793 end:
794 return ret;
795 }
796
797 int bt_clock_value_get_value(
798 struct bt_clock_value *clock_value, uint64_t *raw_value)
799 {
800 int ret = 0;
801
802 if (!clock_value || !raw_value) {
803 BT_LOGW("Invalid parameter: clock value or raw value is NULL: "
804 "clock-value-addr=%p, raw-value-addr=%p",
805 clock_value, raw_value);
806 ret = -1;
807 goto end;
808 }
809
810 *raw_value = clock_value->value;
811 end:
812 return ret;
813 }
814
815 int bt_clock_value_get_value_ns_from_epoch(struct bt_clock_value *value,
816 int64_t *ret_value_ns)
817 {
818 int ret = 0;
819
820 if (!value || !ret_value_ns) {
821 BT_LOGW("Invalid parameter: clock value or return value pointer is NULL: "
822 "clock-value-addr=%p, ret-value-addr=%p",
823 value, ret_value_ns);
824 ret = -1;
825 goto end;
826 }
827
828 if (value->ns_from_epoch_overflows) {
829 BT_LOGW("Clock value converted to nanoseconds from Epoch overflows the signed 64-bit integer range: "
830 "clock-value-addr=%p, "
831 "clock-class-offset-s=%" PRId64 ", "
832 "clock-class-offset-cycles=%" PRId64 ", "
833 "value=%" PRIu64,
834 value, value->clock_class->offset_s,
835 value->clock_class->offset,
836 value->value);
837 ret = -1;
838 goto end;
839 }
840
841 *ret_value_ns = value->ns_from_epoch;
842
843 end:
844 return ret;
845 }
846
847 struct bt_clock_class *bt_clock_value_get_class(
848 struct bt_clock_value *clock_value)
849 {
850 struct bt_clock_class *clock_class = NULL;
851
852 if (!clock_value) {
853 BT_LOGW_STR("Invalid parameter: clock value is NULL.");
854 goto end;
855 }
856
857 clock_class = bt_get(clock_value->clock_class);
858
859 end:
860 return clock_class;
861 }
This page took 0.045449 seconds and 5 git commands to generate.