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