Port: replace strerror_r() with glib g_strerror()
[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/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>
38 #include <inttypes.h>
39 #include <babeltrace/object-internal.h>
40
41 static
42 void bt_ctf_clock_class_destroy(struct bt_object *obj);
43
44 BT_HIDDEN
45 bt_bool bt_ctf_clock_class_is_valid(struct bt_ctf_clock_class *clock_class)
46 {
47 return clock_class && clock_class->name;
48 }
49
50 int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class *clock_class,
51 const char *name)
52 {
53 int ret = 0;
54
55 if (!clock_class) {
56 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
57 ret = -1;
58 goto end;
59 }
60
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));
64 ret = -1;
65 goto end;
66 }
67
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\"",
71 clock_class, name);
72 ret = -1;
73 goto end;
74 }
75
76 if (clock_class->name) {
77 g_string_assign(clock_class->name, name);
78 } else {
79 clock_class->name = g_string_new(name);
80 if (!clock_class->name) {
81 BT_LOGE_STR("Failed to allocate a GString.");
82 ret = -1;
83 goto end;
84 }
85 }
86
87 BT_LOGV("Set clock class's name: addr=%p, name=\"%s\"",
88 clock_class, name);
89
90 end:
91 return ret;
92 }
93
94 struct bt_ctf_clock_class *bt_ctf_clock_class_create(const char *name)
95 {
96 int ret;
97 struct bt_ctf_clock_class *clock_class;
98
99 BT_LOGD("Creating default clock class object: name=\"%s\"",
100 name);
101 clock_class = g_new0(struct bt_ctf_clock_class, 1);
102 if (!clock_class) {
103 BT_LOGE_STR("Failed to allocate one clock class.");
104 goto error;
105 }
106
107 clock_class->precision = 1;
108 clock_class->frequency = 1000000000;
109 bt_object_init(clock_class, bt_ctf_clock_class_destroy);
110
111 if (name) {
112 ret = bt_ctf_clock_class_set_name(clock_class, name);
113 if (ret) {
114 BT_LOGE("Cannot set clock class's name: "
115 "addr=%p, name=\"%s\"",
116 clock_class, name);
117 goto error;
118 }
119 }
120
121 ret = bt_uuid_generate(clock_class->uuid);
122 if (ret) {
123 BT_LOGE_STR("Failed to generate a UUID.");
124 goto error;
125 }
126
127 clock_class->uuid_set = 1;
128 BT_LOGD("Created clock class object: addr=%p, name=\"%s\"",
129 clock_class, name);
130 return clock_class;
131 error:
132 BT_PUT(clock_class);
133 return clock_class;
134 }
135
136 const char *bt_ctf_clock_class_get_name(struct bt_ctf_clock_class *clock_class)
137 {
138 const char *ret = NULL;
139
140 if (!clock_class) {
141 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
142 goto end;
143 }
144
145 if (clock_class->name) {
146 ret = clock_class->name->str;
147 }
148
149 end:
150 return ret;
151 }
152
153 const char *bt_ctf_clock_class_get_description(
154 struct bt_ctf_clock_class *clock_class)
155 {
156 const char *ret = NULL;
157
158 if (!clock_class) {
159 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
160 goto end;
161 }
162
163 if (clock_class->description) {
164 ret = clock_class->description->str;
165 }
166 end:
167 return ret;
168 }
169
170 int bt_ctf_clock_class_set_description(struct bt_ctf_clock_class *clock_class,
171 const char *desc)
172 {
173 int ret = 0;
174
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),
179 desc);
180 ret = -1;
181 goto end;
182 }
183
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));
187 ret = -1;
188 goto end;
189 }
190
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);
196 end:
197 return ret;
198 }
199
200 uint64_t bt_ctf_clock_class_get_frequency(
201 struct bt_ctf_clock_class *clock_class)
202 {
203 uint64_t ret = -1ULL;
204
205 if (!clock_class) {
206 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
207 goto end;
208 }
209
210 ret = clock_class->frequency;
211 end:
212 return ret;
213 }
214
215 int bt_ctf_clock_class_set_frequency(struct bt_ctf_clock_class *clock_class,
216 uint64_t freq)
217 {
218 int ret = 0;
219
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),
224 freq);
225 ret = -1;
226 goto end;
227 }
228
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));
232 ret = -1;
233 goto end;
234 }
235
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);
239 end:
240 return ret;
241 }
242
243 uint64_t bt_ctf_clock_class_get_precision(struct bt_ctf_clock_class *clock_class)
244 {
245 uint64_t ret = -1ULL;
246
247 if (!clock_class) {
248 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
249 goto end;
250 }
251
252 ret = clock_class->precision;
253 end:
254 return ret;
255 }
256
257 int bt_ctf_clock_class_set_precision(struct bt_ctf_clock_class *clock_class,
258 uint64_t precision)
259 {
260 int ret = 0;
261
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),
266 precision);
267 ret = -1;
268 goto end;
269 }
270
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));
274 ret = -1;
275 goto end;
276 }
277
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),
281 precision);
282 end:
283 return ret;
284 }
285
286 int bt_ctf_clock_class_get_offset_s(struct bt_ctf_clock_class *clock_class,
287 int64_t *offset_s)
288 {
289 int ret = 0;
290
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),
295 offset_s);
296 ret = -1;
297 goto end;
298 }
299
300 *offset_s = clock_class->offset_s;
301 end:
302 return ret;
303 }
304
305 int bt_ctf_clock_class_set_offset_s(struct bt_ctf_clock_class *clock_class,
306 int64_t offset_s)
307 {
308 int ret = 0;
309
310 if (!clock_class) {
311 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
312 ret = -1;
313 goto end;
314 }
315
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));
319 ret = -1;
320 goto end;
321 }
322
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),
327 offset_s);
328 end:
329 return ret;
330 }
331
332 int bt_ctf_clock_class_get_offset_cycles(struct bt_ctf_clock_class *clock_class,
333 int64_t *offset)
334 {
335 int ret = 0;
336
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),
341 offset);
342 ret = -1;
343 goto end;
344 }
345
346 *offset = clock_class->offset;
347 end:
348 return ret;
349 }
350
351 int bt_ctf_clock_class_set_offset_cycles(struct bt_ctf_clock_class *clock_class,
352 int64_t offset)
353 {
354 int ret = 0;
355
356 if (!clock_class) {
357 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
358 ret = -1;
359 goto end;
360 }
361
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));
365 ret = -1;
366 goto end;
367 }
368
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);
372 end:
373 return ret;
374 }
375
376 bt_bool bt_ctf_clock_class_is_absolute(struct bt_ctf_clock_class *clock_class)
377 {
378 int ret = -1;
379
380 if (!clock_class) {
381 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
382 goto end;
383 }
384
385 ret = clock_class->absolute;
386 end:
387 return ret;
388 }
389
390 int bt_ctf_clock_class_set_is_absolute(struct bt_ctf_clock_class *clock_class,
391 bt_bool is_absolute)
392 {
393 int ret = 0;
394
395 if (!clock_class) {
396 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
397 ret = -1;
398 goto end;
399 }
400
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));
404 ret = -1;
405 goto end;
406 }
407
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),
411 is_absolute);
412 end:
413 return ret;
414 }
415
416 const unsigned char *bt_ctf_clock_class_get_uuid(
417 struct bt_ctf_clock_class *clock_class)
418 {
419 const unsigned char *ret;
420
421 if (!clock_class) {
422 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
423 ret = NULL;
424 goto end;
425 }
426
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));
430 ret = NULL;
431 goto end;
432 }
433
434 ret = clock_class->uuid;
435 end:
436 return ret;
437 }
438
439 int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class *clock_class,
440 const unsigned char *uuid)
441 {
442 int ret = 0;
443
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),
448 uuid);
449 ret = -1;
450 goto end;
451 }
452
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));
456 ret = -1;
457 goto end;
458 }
459
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]);
481 end:
482 return ret;
483 }
484
485 static uint64_t ns_from_value(uint64_t frequency, uint64_t value)
486 {
487 uint64_t ns;
488
489 if (frequency == 1000000000) {
490 ns = value;
491 } else {
492 ns = (uint64_t) ((1e9 * (double) value) / (double) frequency);
493 }
494
495 return ns;
496 }
497
498 BT_HIDDEN
499 void bt_ctf_clock_class_freeze(struct bt_ctf_clock_class *clock_class)
500 {
501 if (!clock_class) {
502 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
503 return;
504 }
505
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;
510 }
511 }
512
513 BT_HIDDEN
514 void bt_ctf_clock_class_serialize(struct bt_ctf_clock_class *clock_class,
515 struct metadata_context *context)
516 {
517 unsigned char *uuid;
518
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);
522
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),
527 context);
528 return;
529 }
530
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);
544 }
545
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");
557 }
558
559 static
560 void bt_ctf_clock_class_destroy(struct bt_object *obj)
561 {
562 struct bt_ctf_clock_class *clock_class;
563
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);
569 }
570 if (clock_class->description) {
571 g_string_free(clock_class->description, TRUE);
572 }
573
574 g_free(clock_class);
575 }
576
577 static
578 void bt_ctf_clock_value_destroy(struct bt_object *obj)
579 {
580 struct bt_ctf_clock_value *value;
581
582 if (!obj) {
583 return;
584 }
585
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);
591 g_free(value);
592 }
593
594 struct bt_ctf_clock_value *bt_ctf_clock_value_create(
595 struct bt_ctf_clock_class *clock_class, uint64_t value)
596 {
597 struct bt_ctf_clock_value *ret = NULL;
598
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);
602
603 if (!clock_class) {
604 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
605 goto end;
606 }
607
608 ret = g_new0(struct bt_ctf_clock_value, 1);
609 if (!ret) {
610 BT_LOGE_STR("Failed to allocate one clock value.");
611 goto end;
612 }
613
614 bt_object_init(ret, bt_ctf_clock_value_destroy);
615 ret->clock_class = bt_get(clock_class);
616 ret->value = value;
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));
620 end:
621 return ret;
622 }
623
624 int bt_ctf_clock_value_get_value(
625 struct bt_ctf_clock_value *clock_value, uint64_t *raw_value)
626 {
627 int ret = 0;
628
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);
633 ret = -1;
634 goto end;
635 }
636
637 *raw_value = clock_value->value;
638 end:
639 return ret;
640 }
641
642 int bt_ctf_clock_value_get_value_ns_from_epoch(struct bt_ctf_clock_value *value,
643 int64_t *ret_value_ns)
644 {
645 int ret = 0;
646 int64_t ns;
647
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);
652 ret = -1;
653 goto end;
654 }
655
656 /* Initialize nanosecond timestamp to clock's offset in seconds. */
657 ns = value->clock_class->offset_s * (int64_t) 1000000000;
658
659 /* Add offset in cycles, converted to nanoseconds. */
660 ns += ns_from_value(value->clock_class->frequency,
661 value->clock_class->offset);
662
663 /* Add given value, converter to nanoseconds. */
664 ns += ns_from_value(value->clock_class->frequency, value->value);
665
666 *ret_value_ns = ns;
667 end:
668 return ret;
669 }
670
671 struct bt_ctf_clock_class *bt_ctf_clock_value_get_class(
672 struct bt_ctf_clock_value *clock_value)
673 {
674 struct bt_ctf_clock_class *clock_class = NULL;
675
676 if (!clock_value) {
677 BT_LOGW_STR("Invalid parameter: clock value is NULL.");
678 goto end;
679 }
680
681 clock_class = bt_get(clock_value->clock_class);
682
683 end:
684 return clock_class;
685 }
This page took 0.043096 seconds and 5 git commands to generate.