ir: do not automatically generate a UUID in bt_ctf_clock_class_create()
[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/utils.h>
35 #include <babeltrace/ref.h>
36 #include <babeltrace/compiler-internal.h>
37 #include <babeltrace/types.h>
38 #include <babeltrace/compat/string-internal.h>
39 #include <inttypes.h>
40 #include <babeltrace/object-internal.h>
41
42 static
43 void bt_ctf_clock_class_destroy(struct bt_object *obj);
44
45 BT_HIDDEN
46 bt_bool bt_ctf_clock_class_is_valid(struct bt_ctf_clock_class *clock_class)
47 {
48 return clock_class && clock_class->name;
49 }
50
51 int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class *clock_class,
52 const char *name)
53 {
54 int ret = 0;
55
56 if (!clock_class) {
57 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
58 ret = -1;
59 goto end;
60 }
61
62 if (clock_class->frozen) {
63 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
64 clock_class, bt_ctf_clock_class_get_name(clock_class));
65 ret = -1;
66 goto end;
67 }
68
69 if (bt_ctf_validate_identifier(name)) {
70 BT_LOGE("Clock class's name is not a valid CTF identifier: "
71 "addr=%p, name=\"%s\"",
72 clock_class, name);
73 ret = -1;
74 goto end;
75 }
76
77 if (clock_class->name) {
78 g_string_assign(clock_class->name, name);
79 } else {
80 clock_class->name = g_string_new(name);
81 if (!clock_class->name) {
82 BT_LOGE_STR("Failed to allocate a GString.");
83 ret = -1;
84 goto end;
85 }
86 }
87
88 BT_LOGV("Set clock class's name: addr=%p, name=\"%s\"",
89 clock_class, name);
90
91 end:
92 return ret;
93 }
94
95 struct bt_ctf_clock_class *bt_ctf_clock_class_create(const char *name)
96 {
97 int ret;
98 struct bt_ctf_clock_class *clock_class;
99
100 BT_LOGD("Creating default clock class object: name=\"%s\"",
101 name);
102 clock_class = g_new0(struct bt_ctf_clock_class, 1);
103 if (!clock_class) {
104 BT_LOGE_STR("Failed to allocate one clock class.");
105 goto error;
106 }
107
108 clock_class->precision = 1;
109 clock_class->frequency = 1000000000;
110 bt_object_init(clock_class, bt_ctf_clock_class_destroy);
111
112 if (name) {
113 ret = bt_ctf_clock_class_set_name(clock_class, name);
114 if (ret) {
115 BT_LOGE("Cannot set clock class's name: "
116 "addr=%p, name=\"%s\"",
117 clock_class, name);
118 goto error;
119 }
120 }
121
122 BT_LOGD("Created clock class object: addr=%p, name=\"%s\"",
123 clock_class, name);
124 return clock_class;
125 error:
126 BT_PUT(clock_class);
127 return clock_class;
128 }
129
130 const char *bt_ctf_clock_class_get_name(struct bt_ctf_clock_class *clock_class)
131 {
132 const char *ret = NULL;
133
134 if (!clock_class) {
135 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
136 goto end;
137 }
138
139 if (clock_class->name) {
140 ret = clock_class->name->str;
141 }
142
143 end:
144 return ret;
145 }
146
147 const char *bt_ctf_clock_class_get_description(
148 struct bt_ctf_clock_class *clock_class)
149 {
150 const char *ret = NULL;
151
152 if (!clock_class) {
153 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
154 goto end;
155 }
156
157 if (clock_class->description) {
158 ret = clock_class->description->str;
159 }
160 end:
161 return ret;
162 }
163
164 int bt_ctf_clock_class_set_description(struct bt_ctf_clock_class *clock_class,
165 const char *desc)
166 {
167 int ret = 0;
168
169 if (!clock_class || !desc) {
170 BT_LOGW("Invalid parameter: clock class or description is NULL: "
171 "clock-class-addr=%p, name=\"%s\", desc-addr=%p",
172 clock_class, bt_ctf_clock_class_get_name(clock_class),
173 desc);
174 ret = -1;
175 goto end;
176 }
177
178 if (clock_class->frozen) {
179 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
180 clock_class, bt_ctf_clock_class_get_name(clock_class));
181 ret = -1;
182 goto end;
183 }
184
185 clock_class->description = g_string_new(desc);
186 ret = clock_class->description ? 0 : -1;
187 BT_LOGV("Set clock class's description: addr=%p, "
188 "name=\"%s\", desc=\"%s\"",
189 clock_class, bt_ctf_clock_class_get_name(clock_class), desc);
190 end:
191 return ret;
192 }
193
194 uint64_t bt_ctf_clock_class_get_frequency(
195 struct bt_ctf_clock_class *clock_class)
196 {
197 uint64_t ret = -1ULL;
198
199 if (!clock_class) {
200 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
201 goto end;
202 }
203
204 ret = clock_class->frequency;
205 end:
206 return ret;
207 }
208
209 int bt_ctf_clock_class_set_frequency(struct bt_ctf_clock_class *clock_class,
210 uint64_t freq)
211 {
212 int ret = 0;
213
214 if (!clock_class || freq == -1ULL) {
215 BT_LOGW("Invalid parameter: clock class is NULL or frequency is invalid: "
216 "addr=%p, name=\"%s\", freq=%" PRIu64,
217 clock_class, bt_ctf_clock_class_get_name(clock_class),
218 freq);
219 ret = -1;
220 goto end;
221 }
222
223 if (clock_class->frozen) {
224 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
225 clock_class, bt_ctf_clock_class_get_name(clock_class));
226 ret = -1;
227 goto end;
228 }
229
230 clock_class->frequency = freq;
231 BT_LOGV("Set clock class's frequency: addr=%p, name=\"%s\", freq=%" PRIu64,
232 clock_class, bt_ctf_clock_class_get_name(clock_class), freq);
233 end:
234 return ret;
235 }
236
237 uint64_t bt_ctf_clock_class_get_precision(struct bt_ctf_clock_class *clock_class)
238 {
239 uint64_t ret = -1ULL;
240
241 if (!clock_class) {
242 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
243 goto end;
244 }
245
246 ret = clock_class->precision;
247 end:
248 return ret;
249 }
250
251 int bt_ctf_clock_class_set_precision(struct bt_ctf_clock_class *clock_class,
252 uint64_t precision)
253 {
254 int ret = 0;
255
256 if (!clock_class || precision == -1ULL) {
257 BT_LOGW("Invalid parameter: clock class is NULL or precision is invalid: "
258 "addr=%p, name=\"%s\", precision=%" PRIu64,
259 clock_class, bt_ctf_clock_class_get_name(clock_class),
260 precision);
261 ret = -1;
262 goto end;
263 }
264
265 if (clock_class->frozen) {
266 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
267 clock_class, bt_ctf_clock_class_get_name(clock_class));
268 ret = -1;
269 goto end;
270 }
271
272 clock_class->precision = precision;
273 BT_LOGV("Set clock class's precision: addr=%p, name=\"%s\", precision=%" PRIu64,
274 clock_class, bt_ctf_clock_class_get_name(clock_class),
275 precision);
276 end:
277 return ret;
278 }
279
280 int bt_ctf_clock_class_get_offset_s(struct bt_ctf_clock_class *clock_class,
281 int64_t *offset_s)
282 {
283 int ret = 0;
284
285 if (!clock_class || !offset_s) {
286 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
287 "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
288 clock_class, bt_ctf_clock_class_get_name(clock_class),
289 offset_s);
290 ret = -1;
291 goto end;
292 }
293
294 *offset_s = clock_class->offset_s;
295 end:
296 return ret;
297 }
298
299 int bt_ctf_clock_class_set_offset_s(struct bt_ctf_clock_class *clock_class,
300 int64_t offset_s)
301 {
302 int ret = 0;
303
304 if (!clock_class) {
305 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
306 ret = -1;
307 goto end;
308 }
309
310 if (clock_class->frozen) {
311 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
312 clock_class, bt_ctf_clock_class_get_name(clock_class));
313 ret = -1;
314 goto end;
315 }
316
317 clock_class->offset_s = offset_s;
318 BT_LOGV("Set clock class's offset (seconds): "
319 "addr=%p, name=\"%s\", offset-s=%" PRId64,
320 clock_class, bt_ctf_clock_class_get_name(clock_class),
321 offset_s);
322 end:
323 return ret;
324 }
325
326 int bt_ctf_clock_class_get_offset_cycles(struct bt_ctf_clock_class *clock_class,
327 int64_t *offset)
328 {
329 int ret = 0;
330
331 if (!clock_class || !offset) {
332 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
333 "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
334 clock_class, bt_ctf_clock_class_get_name(clock_class),
335 offset);
336 ret = -1;
337 goto end;
338 }
339
340 *offset = clock_class->offset;
341 end:
342 return ret;
343 }
344
345 int bt_ctf_clock_class_set_offset_cycles(struct bt_ctf_clock_class *clock_class,
346 int64_t offset)
347 {
348 int ret = 0;
349
350 if (!clock_class) {
351 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
352 ret = -1;
353 goto end;
354 }
355
356 if (clock_class->frozen) {
357 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
358 clock_class, bt_ctf_clock_class_get_name(clock_class));
359 ret = -1;
360 goto end;
361 }
362
363 clock_class->offset = offset;
364 BT_LOGV("Set clock class's offset (cycles): addr=%p, name=\"%s\", offset-cycles=%" PRId64,
365 clock_class, bt_ctf_clock_class_get_name(clock_class), offset);
366 end:
367 return ret;
368 }
369
370 bt_bool bt_ctf_clock_class_is_absolute(struct bt_ctf_clock_class *clock_class)
371 {
372 int ret = -1;
373
374 if (!clock_class) {
375 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
376 goto end;
377 }
378
379 ret = clock_class->absolute;
380 end:
381 return ret;
382 }
383
384 int bt_ctf_clock_class_set_is_absolute(struct bt_ctf_clock_class *clock_class,
385 bt_bool is_absolute)
386 {
387 int ret = 0;
388
389 if (!clock_class) {
390 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
391 ret = -1;
392 goto end;
393 }
394
395 if (clock_class->frozen) {
396 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
397 clock_class, bt_ctf_clock_class_get_name(clock_class));
398 ret = -1;
399 goto end;
400 }
401
402 clock_class->absolute = !!is_absolute;
403 BT_LOGV("Set clock class's absolute flag: addr=%p, name=\"%s\", is-absolute=%d",
404 clock_class, bt_ctf_clock_class_get_name(clock_class),
405 is_absolute);
406 end:
407 return ret;
408 }
409
410 const unsigned char *bt_ctf_clock_class_get_uuid(
411 struct bt_ctf_clock_class *clock_class)
412 {
413 const unsigned char *ret;
414
415 if (!clock_class) {
416 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
417 ret = NULL;
418 goto end;
419 }
420
421 if (!clock_class->uuid_set) {
422 BT_LOGV("Clock class's UUID is not set: addr=%p, name=\"%s\"",
423 clock_class, bt_ctf_clock_class_get_name(clock_class));
424 ret = NULL;
425 goto end;
426 }
427
428 ret = clock_class->uuid;
429 end:
430 return ret;
431 }
432
433 int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class *clock_class,
434 const unsigned char *uuid)
435 {
436 int ret = 0;
437
438 if (!clock_class || !uuid) {
439 BT_LOGW("Invalid parameter: clock class or UUID is NULL: "
440 "clock-class-addr=%p, name=\"%s\", uuid-addr=%p",
441 clock_class, bt_ctf_clock_class_get_name(clock_class),
442 uuid);
443 ret = -1;
444 goto end;
445 }
446
447 if (clock_class->frozen) {
448 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
449 clock_class, bt_ctf_clock_class_get_name(clock_class));
450 ret = -1;
451 goto end;
452 }
453
454 memcpy(clock_class->uuid, uuid, BABELTRACE_UUID_LEN);
455 clock_class->uuid_set = 1;
456 BT_LOGV("Set clock class's UUID: addr=%p, name=\"%s\", "
457 "uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"",
458 clock_class, bt_ctf_clock_class_get_name(clock_class),
459 (unsigned int) uuid[0],
460 (unsigned int) uuid[1],
461 (unsigned int) uuid[2],
462 (unsigned int) uuid[3],
463 (unsigned int) uuid[4],
464 (unsigned int) uuid[5],
465 (unsigned int) uuid[6],
466 (unsigned int) uuid[7],
467 (unsigned int) uuid[8],
468 (unsigned int) uuid[9],
469 (unsigned int) uuid[10],
470 (unsigned int) uuid[11],
471 (unsigned int) uuid[12],
472 (unsigned int) uuid[13],
473 (unsigned int) uuid[14],
474 (unsigned int) uuid[15]);
475 end:
476 return ret;
477 }
478
479 static uint64_t ns_from_value(uint64_t frequency, uint64_t value)
480 {
481 uint64_t ns;
482
483 if (frequency == 1000000000) {
484 ns = value;
485 } else {
486 ns = (uint64_t) ((1e9 * (double) value) / (double) frequency);
487 }
488
489 return ns;
490 }
491
492 BT_HIDDEN
493 void bt_ctf_clock_class_freeze(struct bt_ctf_clock_class *clock_class)
494 {
495 if (!clock_class) {
496 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
497 return;
498 }
499
500 if (!clock_class->frozen) {
501 BT_LOGD("Freezing clock class: addr=%p, name=\"%s\"",
502 clock_class, bt_ctf_clock_class_get_name(clock_class));
503 clock_class->frozen = 1;
504 }
505 }
506
507 BT_HIDDEN
508 void bt_ctf_clock_class_serialize(struct bt_ctf_clock_class *clock_class,
509 struct metadata_context *context)
510 {
511 unsigned char *uuid;
512
513 BT_LOGD("Serializing clock class's metadata: clock-class-addr=%p, "
514 "name=\"%s\", metadata-context-addr=%p", clock_class,
515 bt_ctf_clock_class_get_name(clock_class), context);
516
517 if (!clock_class || !context) {
518 BT_LOGW("Invalid parameter: clock class or metadata context is NULL: "
519 "clock-class-addr=%p, name=\"%s\", metadata-context-addr=%p",
520 clock_class, bt_ctf_clock_class_get_name(clock_class),
521 context);
522 return;
523 }
524
525 uuid = clock_class->uuid;
526 g_string_append(context->string, "clock {\n");
527 g_string_append_printf(context->string, "\tname = %s;\n",
528 clock_class->name->str);
529 g_string_append_printf(context->string,
530 "\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n",
531 uuid[0], uuid[1], uuid[2], uuid[3],
532 uuid[4], uuid[5], uuid[6], uuid[7],
533 uuid[8], uuid[9], uuid[10], uuid[11],
534 uuid[12], uuid[13], uuid[14], uuid[15]);
535 if (clock_class->description) {
536 g_string_append_printf(context->string, "\tdescription = \"%s\";\n",
537 clock_class->description->str);
538 }
539
540 g_string_append_printf(context->string, "\tfreq = %" PRIu64 ";\n",
541 clock_class->frequency);
542 g_string_append_printf(context->string, "\tprecision = %" PRIu64 ";\n",
543 clock_class->precision);
544 g_string_append_printf(context->string, "\toffset_s = %" PRIu64 ";\n",
545 clock_class->offset_s);
546 g_string_append_printf(context->string, "\toffset = %" PRIu64 ";\n",
547 clock_class->offset);
548 g_string_append_printf(context->string, "\tabsolute = %s;\n",
549 clock_class->absolute ? "TRUE" : "FALSE");
550 g_string_append(context->string, "};\n\n");
551 }
552
553 static
554 void bt_ctf_clock_class_destroy(struct bt_object *obj)
555 {
556 struct bt_ctf_clock_class *clock_class;
557
558 clock_class = container_of(obj, struct bt_ctf_clock_class, base);
559 BT_LOGD("Destroying clock class: addr=%p, name=\"%s\"",
560 obj, bt_ctf_clock_class_get_name(clock_class));
561 if (clock_class->name) {
562 g_string_free(clock_class->name, TRUE);
563 }
564 if (clock_class->description) {
565 g_string_free(clock_class->description, TRUE);
566 }
567
568 g_free(clock_class);
569 }
570
571 static
572 void bt_ctf_clock_value_destroy(struct bt_object *obj)
573 {
574 struct bt_ctf_clock_value *value;
575
576 if (!obj) {
577 return;
578 }
579
580 value = container_of(obj, struct bt_ctf_clock_value, base);
581 BT_LOGD("Destroying clock value: addr=%p, clock-class-addr=%p, "
582 "clock-class-name=\"%s\"", obj, value->clock_class,
583 bt_ctf_clock_class_get_name(value->clock_class));
584 bt_put(value->clock_class);
585 g_free(value);
586 }
587
588 struct bt_ctf_clock_value *bt_ctf_clock_value_create(
589 struct bt_ctf_clock_class *clock_class, uint64_t value)
590 {
591 struct bt_ctf_clock_value *ret = NULL;
592
593 BT_LOGD("Creating clock value object: clock-class-addr=%p, "
594 "clock-class-name=\"%s\", value=%" PRIu64, clock_class,
595 bt_ctf_clock_class_get_name(clock_class), value);
596
597 if (!clock_class) {
598 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
599 goto end;
600 }
601
602 ret = g_new0(struct bt_ctf_clock_value, 1);
603 if (!ret) {
604 BT_LOGE_STR("Failed to allocate one clock value.");
605 goto end;
606 }
607
608 bt_object_init(ret, bt_ctf_clock_value_destroy);
609 ret->clock_class = bt_get(clock_class);
610 ret->value = value;
611 BT_LOGD("Created clock value object: clock-value-addr=%p, "
612 "clock-class-addr=%p, clock-class-name=\"%s\"",
613 ret, clock_class, bt_ctf_clock_class_get_name(clock_class));
614 end:
615 return ret;
616 }
617
618 int bt_ctf_clock_value_get_value(
619 struct bt_ctf_clock_value *clock_value, uint64_t *raw_value)
620 {
621 int ret = 0;
622
623 if (!clock_value || !raw_value) {
624 BT_LOGW("Invalid parameter: clock value or raw value is NULL: "
625 "clock-value-addr=%p, raw-value-addr=%p",
626 clock_value, raw_value);
627 ret = -1;
628 goto end;
629 }
630
631 *raw_value = clock_value->value;
632 end:
633 return ret;
634 }
635
636 int bt_ctf_clock_value_get_value_ns_from_epoch(struct bt_ctf_clock_value *value,
637 int64_t *ret_value_ns)
638 {
639 int ret = 0;
640 int64_t ns;
641
642 if (!value || !ret_value_ns) {
643 BT_LOGW("Invalid parameter: clock value or return value pointer is NULL: "
644 "clock-value-addr=%p, ret-value-addr=%p",
645 value, ret_value_ns);
646 ret = -1;
647 goto end;
648 }
649
650 /* Initialize nanosecond timestamp to clock's offset in seconds. */
651 ns = value->clock_class->offset_s * (int64_t) 1000000000;
652
653 /* Add offset in cycles, converted to nanoseconds. */
654 ns += ns_from_value(value->clock_class->frequency,
655 value->clock_class->offset);
656
657 /* Add given value, converter to nanoseconds. */
658 ns += ns_from_value(value->clock_class->frequency, value->value);
659
660 *ret_value_ns = ns;
661 end:
662 return ret;
663 }
664
665 struct bt_ctf_clock_class *bt_ctf_clock_value_get_class(
666 struct bt_ctf_clock_value *clock_value)
667 {
668 struct bt_ctf_clock_class *clock_class = NULL;
669
670 if (!clock_value) {
671 BT_LOGW_STR("Invalid parameter: clock value is NULL.");
672 goto end;
673 }
674
675 clock_class = bt_get(clock_value->clock_class);
676
677 end:
678 return clock_class;
679 }
This page took 0.050471 seconds and 5 git commands to generate.