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