Visibility hidden by default
[babeltrace.git] / src / ctf-writer / clock-class.c
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 *
6 * Babeltrace CTF writer - Clock class
7 */
8
9 #define BT_LOG_TAG "CTF-WRITER/CLOCK-CLASS"
10 #include "logging.h"
11
12 #include "common/uuid.h"
13 #include <babeltrace2-ctf-writer/utils.h>
14 #include <babeltrace2-ctf-writer/object.h>
15 #include "compat/compiler.h"
16 #include <babeltrace2/types.h>
17 #include "compat/string.h"
18 #include <stdbool.h>
19 #include <inttypes.h>
20 #include "common/assert.h"
21
22 #include "assert-pre.h"
23 #include "clock-class.h"
24 #include "object.h"
25
26 static
27 void bt_ctf_clock_class_destroy(struct bt_ctf_object *obj);
28
29 bt_ctf_bool bt_ctf_clock_class_is_valid(struct bt_ctf_clock_class *clock_class)
30 {
31 return clock_class && clock_class->name;
32 }
33
34 int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class *clock_class,
35 const char *name)
36 {
37 int ret = 0;
38
39 if (!clock_class) {
40 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
41 ret = -1;
42 goto end;
43 }
44
45 if (clock_class->frozen) {
46 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
47 clock_class, bt_ctf_clock_class_get_name(clock_class));
48 ret = -1;
49 goto end;
50 }
51
52 if (!bt_ctf_identifier_is_valid(name)) {
53 BT_LOGW("Clock class's name is not a valid CTF identifier: "
54 "addr=%p, name=\"%s\"",
55 clock_class, name);
56 ret = -1;
57 goto end;
58 }
59
60 if (clock_class->name) {
61 g_string_assign(clock_class->name, name);
62 } else {
63 clock_class->name = g_string_new(name);
64 if (!clock_class->name) {
65 BT_LOGE_STR("Failed to allocate a GString.");
66 ret = -1;
67 goto end;
68 }
69 }
70
71 BT_LOGT("Set clock class's name: addr=%p, name=\"%s\"",
72 clock_class, name);
73
74 end:
75 return ret;
76 }
77
78 static
79 bool validate_freq(struct bt_ctf_clock_class *clock_class,
80 const char *name, uint64_t freq)
81 {
82 bool is_valid = true;
83
84 if (freq == -1ULL || freq == 0) {
85 BT_LOGW("Invalid parameter: frequency is invalid: "
86 "addr=%p, name=\"%s\", freq=%" PRIu64,
87 clock_class, name, freq);
88 is_valid = false;
89 goto end;
90 }
91
92 end:
93 return is_valid;
94 }
95
96 struct bt_ctf_clock_class *bt_ctf_clock_class_create(const char *name,
97 uint64_t freq)
98 {
99 int ret;
100 struct bt_ctf_clock_class *clock_class = NULL;
101
102 BT_LOGD("Creating default clock class object: name=\"%s\"",
103 name);
104
105 if (!validate_freq(NULL, name, freq)) {
106 /* validate_freq() logs errors */
107 goto error;
108 }
109
110 clock_class = g_new0(struct bt_ctf_clock_class, 1);
111 if (!clock_class) {
112 BT_LOGE_STR("Failed to allocate one clock class.");
113 goto error;
114 }
115
116 clock_class->precision = 1;
117 clock_class->frequency = freq;
118 bt_ctf_object_init_shared(&clock_class->base, bt_ctf_clock_class_destroy);
119
120 if (name) {
121 ret = bt_ctf_clock_class_set_name(clock_class, name);
122 if (ret) {
123 /* bt_ctf_clock_class_set_name() logs errors */
124 goto error;
125 }
126 }
127
128 BT_LOGD("Created clock class object: addr=%p, name=\"%s\"",
129 clock_class, name);
130 return clock_class;
131 error:
132 BT_CTF_OBJECT_PUT_REF_AND_RESET(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_LOGT("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) {
221 BT_LOGW("Invalid parameter: clock class is NULL or frequency is invalid: "
222 "addr=%p, name=\"%s\"",
223 clock_class, bt_ctf_clock_class_get_name(clock_class));
224 ret = -1;
225 goto end;
226 }
227
228 if (!validate_freq(clock_class, bt_ctf_clock_class_get_name(clock_class),
229 freq)) {
230 /* validate_freq() logs errors */
231 goto end;
232 }
233
234 if (clock_class->frozen) {
235 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
236 clock_class, bt_ctf_clock_class_get_name(clock_class));
237 ret = -1;
238 goto end;
239 }
240
241 clock_class->frequency = freq;
242 BT_LOGT("Set clock class's frequency: addr=%p, name=\"%s\", freq=%" PRIu64,
243 clock_class, bt_ctf_clock_class_get_name(clock_class), freq);
244 end:
245 return ret;
246 }
247
248 uint64_t bt_ctf_clock_class_get_precision(struct bt_ctf_clock_class *clock_class)
249 {
250 uint64_t ret = -1ULL;
251
252 if (!clock_class) {
253 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
254 goto end;
255 }
256
257 ret = clock_class->precision;
258 end:
259 return ret;
260 }
261
262 int bt_ctf_clock_class_set_precision(struct bt_ctf_clock_class *clock_class,
263 uint64_t precision)
264 {
265 int ret = 0;
266
267 if (!clock_class || precision == -1ULL) {
268 BT_LOGW("Invalid parameter: clock class is NULL or precision is invalid: "
269 "addr=%p, name=\"%s\", precision=%" PRIu64,
270 clock_class, bt_ctf_clock_class_get_name(clock_class),
271 precision);
272 ret = -1;
273 goto end;
274 }
275
276 if (clock_class->frozen) {
277 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
278 clock_class, bt_ctf_clock_class_get_name(clock_class));
279 ret = -1;
280 goto end;
281 }
282
283 clock_class->precision = precision;
284 BT_LOGT("Set clock class's precision: addr=%p, name=\"%s\", precision=%" PRIu64,
285 clock_class, bt_ctf_clock_class_get_name(clock_class),
286 precision);
287 end:
288 return ret;
289 }
290
291 int bt_ctf_clock_class_get_offset_s(struct bt_ctf_clock_class *clock_class,
292 int64_t *offset_s)
293 {
294 int ret = 0;
295
296 if (!clock_class || !offset_s) {
297 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
298 "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
299 clock_class, bt_ctf_clock_class_get_name(clock_class),
300 offset_s);
301 ret = -1;
302 goto end;
303 }
304
305 *offset_s = clock_class->offset_s;
306 end:
307 return ret;
308 }
309
310 int bt_ctf_clock_class_set_offset_s(struct bt_ctf_clock_class *clock_class,
311 int64_t offset_s)
312 {
313 int ret = 0;
314
315 if (!clock_class) {
316 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
317 ret = -1;
318 goto end;
319 }
320
321 if (clock_class->frozen) {
322 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
323 clock_class, bt_ctf_clock_class_get_name(clock_class));
324 ret = -1;
325 goto end;
326 }
327
328 clock_class->offset_s = offset_s;
329 BT_LOGT("Set clock class's offset (seconds): "
330 "addr=%p, name=\"%s\", offset-s=%" PRId64,
331 clock_class, bt_ctf_clock_class_get_name(clock_class),
332 offset_s);
333 end:
334 return ret;
335 }
336
337 int bt_ctf_clock_class_get_offset_cycles(struct bt_ctf_clock_class *clock_class,
338 int64_t *offset)
339 {
340 int ret = 0;
341
342 if (!clock_class || !offset) {
343 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
344 "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
345 clock_class, bt_ctf_clock_class_get_name(clock_class),
346 offset);
347 ret = -1;
348 goto end;
349 }
350
351 *offset = clock_class->offset;
352 end:
353 return ret;
354 }
355
356 int bt_ctf_clock_class_set_offset_cycles(struct bt_ctf_clock_class *clock_class,
357 int64_t offset)
358 {
359 int ret = 0;
360
361 if (!clock_class) {
362 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
363 ret = -1;
364 goto end;
365 }
366
367 if (clock_class->frozen) {
368 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
369 clock_class, bt_ctf_clock_class_get_name(clock_class));
370 ret = -1;
371 goto end;
372 }
373
374 clock_class->offset = offset;
375 BT_LOGT("Set clock class's offset (cycles): addr=%p, name=\"%s\", offset-cycles=%" PRId64,
376 clock_class, bt_ctf_clock_class_get_name(clock_class), offset);
377 end:
378 return ret;
379 }
380
381 bt_ctf_bool bt_ctf_clock_class_is_absolute(struct bt_ctf_clock_class *clock_class)
382 {
383 int ret = -1;
384
385 if (!clock_class) {
386 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
387 goto end;
388 }
389
390 ret = clock_class->absolute;
391 end:
392 return ret;
393 }
394
395 int bt_ctf_clock_class_set_is_absolute(struct bt_ctf_clock_class *clock_class,
396 bt_ctf_bool is_absolute)
397 {
398 int ret = 0;
399
400 if (!clock_class) {
401 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
402 ret = -1;
403 goto end;
404 }
405
406 if (clock_class->frozen) {
407 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
408 clock_class, bt_ctf_clock_class_get_name(clock_class));
409 ret = -1;
410 goto end;
411 }
412
413 clock_class->absolute = !!is_absolute;
414 BT_LOGT("Set clock class's absolute flag: addr=%p, name=\"%s\", is-absolute=%d",
415 clock_class, bt_ctf_clock_class_get_name(clock_class),
416 is_absolute);
417 end:
418 return ret;
419 }
420
421 const uint8_t *bt_ctf_clock_class_get_uuid(
422 struct bt_ctf_clock_class *clock_class)
423 {
424 const uint8_t *ret;
425
426 if (!clock_class) {
427 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
428 ret = NULL;
429 goto end;
430 }
431
432 if (!clock_class->uuid_set) {
433 BT_LOGT("Clock class's UUID is not set: addr=%p, name=\"%s\"",
434 clock_class, bt_ctf_clock_class_get_name(clock_class));
435 ret = NULL;
436 goto end;
437 }
438
439 ret = clock_class->uuid;
440 end:
441 return ret;
442 }
443
444 int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class *clock_class,
445 const uint8_t *uuid)
446 {
447 int ret = 0;
448
449 if (!clock_class || !uuid) {
450 BT_LOGW("Invalid parameter: clock class or UUID is NULL: "
451 "clock-class-addr=%p, name=\"%s\", uuid-addr=%p",
452 clock_class, bt_ctf_clock_class_get_name(clock_class),
453 uuid);
454 ret = -1;
455 goto end;
456 }
457
458 if (clock_class->frozen) {
459 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
460 clock_class, bt_ctf_clock_class_get_name(clock_class));
461 ret = -1;
462 goto end;
463 }
464
465 bt_uuid_copy(clock_class->uuid, uuid);
466 clock_class->uuid_set = 1;
467 BT_LOGT("Set clock class's UUID: addr=%p, name=\"%s\", uuid=\"" BT_UUID_FMT "\"",
468 clock_class, bt_ctf_clock_class_get_name(clock_class),
469 BT_UUID_FMT_VALUES(uuid));
470 end:
471 return ret;
472 }
473
474 void bt_ctf_clock_class_freeze(struct bt_ctf_clock_class *clock_class)
475 {
476 if (!clock_class || clock_class->frozen) {
477 return;
478 }
479
480 BT_LOGD("Freezing clock class: addr=%p, name=\"%s\"",
481 clock_class, bt_ctf_clock_class_get_name(clock_class));
482 clock_class->frozen = 1;
483 }
484
485 static
486 void bt_ctf_clock_class_destroy(struct bt_ctf_object *obj)
487 {
488 struct bt_ctf_clock_class *clock_class;
489
490 clock_class = container_of(obj, struct bt_ctf_clock_class, base);
491 BT_LOGD("Destroying clock class: addr=%p, name=\"%s\"",
492 obj, bt_ctf_clock_class_get_name(clock_class));
493
494 if (clock_class->name) {
495 g_string_free(clock_class->name, TRUE);
496 }
497
498 if (clock_class->description) {
499 g_string_free(clock_class->description, TRUE);
500 }
501
502 g_free(clock_class);
503 }
504
505 int bt_ctf_clock_class_compare(struct bt_ctf_clock_class *clock_class_a,
506 struct bt_ctf_clock_class *clock_class_b)
507 {
508 int ret = 1;
509 BT_ASSERT_DBG(clock_class_a);
510 BT_ASSERT_DBG(clock_class_b);
511
512 /* Name */
513 if (strcmp(clock_class_a->name->str, clock_class_b->name->str) != 0) {
514 BT_LOGT("Clock classes differ: different names: "
515 "cc-a-name=\"%s\", cc-b-name=\"%s\"",
516 clock_class_a->name->str,
517 clock_class_b->name->str);
518 goto end;
519 }
520
521 /* Description */
522 if (clock_class_a->description) {
523 if (!clock_class_b->description) {
524 BT_LOGT_STR("Clock classes differ: clock class A has a "
525 "description, but clock class B does not.");
526 goto end;
527 }
528
529 if (strcmp(clock_class_a->name->str, clock_class_b->name->str)
530 != 0) {
531 BT_LOGT("Clock classes differ: different descriptions: "
532 "cc-a-descr=\"%s\", cc-b-descr=\"%s\"",
533 clock_class_a->description->str,
534 clock_class_b->description->str);
535 goto end;
536 }
537 } else {
538 if (clock_class_b->description) {
539 BT_LOGT_STR("Clock classes differ: clock class A has "
540 "no description, but clock class B has one.");
541 goto end;
542 }
543 }
544
545 /* Frequency */
546 if (clock_class_a->frequency != clock_class_b->frequency) {
547 BT_LOGT("Clock classes differ: different frequencies: "
548 "cc-a-freq=%" PRIu64 ", cc-b-freq=%" PRIu64,
549 clock_class_a->frequency,
550 clock_class_b->frequency);
551 goto end;
552 }
553
554 /* Precision */
555 if (clock_class_a->precision != clock_class_b->precision) {
556 BT_LOGT("Clock classes differ: different precisions: "
557 "cc-a-freq=%" PRIu64 ", cc-b-freq=%" PRIu64,
558 clock_class_a->precision,
559 clock_class_b->precision);
560 goto end;
561 }
562
563 /* Offset (seconds) */
564 if (clock_class_a->offset_s != clock_class_b->offset_s) {
565 BT_LOGT("Clock classes differ: different offsets (seconds): "
566 "cc-a-offset-s=%" PRId64 ", cc-b-offset-s=%" PRId64,
567 clock_class_a->offset_s,
568 clock_class_b->offset_s);
569 goto end;
570 }
571
572 /* Offset (cycles) */
573 if (clock_class_a->offset != clock_class_b->offset) {
574 BT_LOGT("Clock classes differ: different offsets (cycles): "
575 "cc-a-offset-s=%" PRId64 ", cc-b-offset-s=%" PRId64,
576 clock_class_a->offset,
577 clock_class_b->offset);
578 goto end;
579 }
580
581 /* UUIDs */
582 if (clock_class_a->uuid_set) {
583 if (!clock_class_b->uuid_set) {
584 BT_LOGT_STR("Clock classes differ: clock class A has a "
585 "UUID, but clock class B does not.");
586 goto end;
587 }
588
589 if (bt_uuid_compare(clock_class_a->uuid, clock_class_b->uuid) != 0) {
590 BT_LOGT("Clock classes differ: different UUIDs: "
591 "cc-a-uuid=\"" BT_UUID_FMT "\", "
592 "cc-b-uuid=\"" BT_UUID_FMT "\"",
593 BT_UUID_FMT_VALUES(clock_class_a->uuid),
594 BT_UUID_FMT_VALUES(clock_class_b->uuid));
595 goto end;
596 }
597 } else {
598 if (clock_class_b->uuid_set) {
599 BT_LOGT_STR("Clock classes differ: clock class A has "
600 "no UUID, but clock class B has one.");
601 goto end;
602 }
603 }
604
605 /* Absolute */
606 if (!!clock_class_a->absolute != !!clock_class_b->absolute) {
607 BT_LOGT("Clock classes differ: one is absolute, the other "
608 "is not: cc-a-is-absolute=%d, cc-b-is-absolute=%d",
609 !!clock_class_a->absolute,
610 !!clock_class_b->absolute);
611 goto end;
612 }
613
614 /* Equal */
615 ret = 0;
616
617 end:
618 return ret;
619 }
This page took 0.059368 seconds and 4 git commands to generate.