Fix: variable declaration shadows previously declared variable
[babeltrace.git] / lib / ctf-ir / clock-class.c
CommitLineData
273b65be 1/*
ac0c6bdd 2 * clock-class.c
273b65be 3 *
ac0c6bdd 4 * Babeltrace CTF IR - Clock class
273b65be 5 *
de9dd397 6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
273b65be
JG
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
0f5e83e5 29#define BT_LOG_TAG "CLOCK-CLASS"
40547d22 30#include <babeltrace/lib-logging-internal.h>
0f5e83e5 31
75c3fca1 32#include <babeltrace/compat/uuid-internal.h>
ac0c6bdd 33#include <babeltrace/ctf-ir/clock-class-internal.h>
c057dea0 34#include <babeltrace/ctf-ir/clock-value-internal.h>
654c1444 35#include <babeltrace/ctf-ir/utils.h>
83509119 36#include <babeltrace/ref.h>
3d9990ac 37#include <babeltrace/compiler-internal.h>
c55a9f58 38#include <babeltrace/types.h>
ee389f01 39#include <babeltrace/compat/string-internal.h>
273b65be 40#include <inttypes.h>
0f5e83e5 41#include <babeltrace/object-internal.h>
5134570b 42
273b65be 43static
ac0c6bdd 44void bt_ctf_clock_class_destroy(struct bt_object *obj);
273b65be 45
4c426c17 46BT_HIDDEN
c55a9f58 47bt_bool bt_ctf_clock_class_is_valid(struct bt_ctf_clock_class *clock_class)
c06116f3 48{
ac0c6bdd 49 return clock_class && clock_class->name;
c06116f3
PP
50}
51
ac0c6bdd 52int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class *clock_class,
4c426c17
JG
53 const char *name)
54{
55 int ret = 0;
273b65be 56
5134570b
PP
57 if (!clock_class) {
58 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
59 ret = -1;
60 goto end;
61 }
62
63 if (clock_class->frozen) {
2cf0acd7
PP
64 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
65 clock_class, bt_ctf_clock_class_get_name(clock_class));
c06116f3
PP
66 ret = -1;
67 goto end;
68 }
69
654c1444 70 if (bt_ctf_validate_identifier(name)) {
5134570b 71 BT_LOGE("Clock class's name is not a valid CTF identifier: "
2cf0acd7 72 "addr=%p, name=\"%s\"",
5134570b 73 clock_class, name);
4c426c17
JG
74 ret = -1;
75 goto end;
273b65be
JG
76 }
77
ac0c6bdd
PP
78 if (clock_class->name) {
79 g_string_assign(clock_class->name, name);
e1ae7645 80 } else {
ac0c6bdd
PP
81 clock_class->name = g_string_new(name);
82 if (!clock_class->name) {
5134570b 83 BT_LOGE_STR("Failed to allocate a GString.");
e1ae7645
JG
84 ret = -1;
85 goto end;
86 }
273b65be
JG
87 }
88
2cf0acd7 89 BT_LOGV("Set clock class's name: addr=%p, name=\"%s\"",
5134570b
PP
90 clock_class, name);
91
4c426c17
JG
92end:
93 return ret;
94}
95
f3534905
PP
96static
97bool validate_freq(struct bt_ctf_clock_class *clock_class,
98 const char *name, uint64_t freq)
99{
100 bool is_valid = true;
101
102 if (freq == -1ULL || freq == 0) {
103 BT_LOGW("Invalid parameter: frequency is invalid: "
104 "addr=%p, name=\"%s\", freq=%" PRIu64,
105 clock_class, name, freq);
106 is_valid = false;
107 goto end;
108 }
109
110end:
111 return is_valid;
112}
113
114struct bt_ctf_clock_class *bt_ctf_clock_class_create(const char *name,
115 uint64_t freq)
4c426c17
JG
116{
117 int ret;
f3534905 118 struct bt_ctf_clock_class *clock_class = NULL;
4c426c17 119
5134570b
PP
120 BT_LOGD("Creating default clock class object: name=\"%s\"",
121 name);
f3534905
PP
122
123 if (!validate_freq(NULL, name, freq)) {
124 /* validate_freq() logs errors */
125 goto error;
126 }
127
5134570b 128 clock_class = g_new0(struct bt_ctf_clock_class, 1);
ac0c6bdd 129 if (!clock_class) {
5134570b 130 BT_LOGE_STR("Failed to allocate one clock class.");
4c426c17
JG
131 goto error;
132 }
133
ac0c6bdd 134 clock_class->precision = 1;
f3534905 135 clock_class->frequency = freq;
ac0c6bdd 136 bt_object_init(clock_class, bt_ctf_clock_class_destroy);
85380e99
JG
137
138 if (name) {
ac0c6bdd 139 ret = bt_ctf_clock_class_set_name(clock_class, name);
85380e99 140 if (ret) {
5134570b 141 BT_LOGE("Cannot set clock class's name: "
2cf0acd7 142 "addr=%p, name=\"%s\"",
5134570b 143 clock_class, name);
85380e99
JG
144 goto error;
145 }
273b65be
JG
146 }
147
2cf0acd7
PP
148 BT_LOGD("Created clock class object: addr=%p, name=\"%s\"",
149 clock_class, name);
ac0c6bdd 150 return clock_class;
273b65be 151error:
ac0c6bdd
PP
152 BT_PUT(clock_class);
153 return clock_class;
87d76bb1
JG
154}
155
ac0c6bdd 156const char *bt_ctf_clock_class_get_name(struct bt_ctf_clock_class *clock_class)
87d76bb1
JG
157{
158 const char *ret = NULL;
159
ac0c6bdd 160 if (!clock_class) {
5134570b 161 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
87d76bb1
JG
162 goto end;
163 }
164
ac0c6bdd
PP
165 if (clock_class->name) {
166 ret = clock_class->name->str;
87d76bb1
JG
167 }
168
169end:
170 return ret;
171}
172
ac0c6bdd
PP
173const char *bt_ctf_clock_class_get_description(
174 struct bt_ctf_clock_class *clock_class)
87d76bb1
JG
175{
176 const char *ret = NULL;
177
ac0c6bdd 178 if (!clock_class) {
5134570b 179 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
87d76bb1
JG
180 goto end;
181 }
182
ac0c6bdd
PP
183 if (clock_class->description) {
184 ret = clock_class->description->str;
87d76bb1
JG
185 }
186end:
187 return ret;
273b65be
JG
188}
189
ac0c6bdd
PP
190int bt_ctf_clock_class_set_description(struct bt_ctf_clock_class *clock_class,
191 const char *desc)
273b65be
JG
192{
193 int ret = 0;
194
5134570b
PP
195 if (!clock_class || !desc) {
196 BT_LOGW("Invalid parameter: clock class or description is NULL: "
2cf0acd7
PP
197 "clock-class-addr=%p, name=\"%s\", desc-addr=%p",
198 clock_class, bt_ctf_clock_class_get_name(clock_class),
199 desc);
5134570b
PP
200 ret = -1;
201 goto end;
202 }
203
204 if (clock_class->frozen) {
2cf0acd7
PP
205 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
206 clock_class, bt_ctf_clock_class_get_name(clock_class));
273b65be
JG
207 ret = -1;
208 goto end;
209 }
210
ac0c6bdd
PP
211 clock_class->description = g_string_new(desc);
212 ret = clock_class->description ? 0 : -1;
2cf0acd7
PP
213 BT_LOGV("Set clock class's description: addr=%p, "
214 "name=\"%s\", desc=\"%s\"",
215 clock_class, bt_ctf_clock_class_get_name(clock_class), desc);
273b65be
JG
216end:
217 return ret;
218}
219
ac0c6bdd
PP
220uint64_t bt_ctf_clock_class_get_frequency(
221 struct bt_ctf_clock_class *clock_class)
87d76bb1
JG
222{
223 uint64_t ret = -1ULL;
224
ac0c6bdd 225 if (!clock_class) {
5134570b 226 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
87d76bb1
JG
227 goto end;
228 }
229
ac0c6bdd 230 ret = clock_class->frequency;
87d76bb1
JG
231end:
232 return ret;
233}
234
ac0c6bdd
PP
235int bt_ctf_clock_class_set_frequency(struct bt_ctf_clock_class *clock_class,
236 uint64_t freq)
273b65be
JG
237{
238 int ret = 0;
239
f3534905 240 if (!clock_class) {
5134570b 241 BT_LOGW("Invalid parameter: clock class is NULL or frequency is invalid: "
f3534905
PP
242 "addr=%p, name=\"%s\"",
243 clock_class, bt_ctf_clock_class_get_name(clock_class));
5134570b
PP
244 ret = -1;
245 goto end;
246 }
247
f3534905
PP
248 if (!validate_freq(clock_class, bt_ctf_clock_class_get_name(clock_class),
249 freq)) {
250 /* validate_freq() logs errors */
251 goto end;
252 }
253
5134570b 254 if (clock_class->frozen) {
2cf0acd7
PP
255 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
256 clock_class, bt_ctf_clock_class_get_name(clock_class));
273b65be
JG
257 ret = -1;
258 goto end;
259 }
260
ac0c6bdd 261 clock_class->frequency = freq;
2cf0acd7
PP
262 BT_LOGV("Set clock class's frequency: addr=%p, name=\"%s\", freq=%" PRIu64,
263 clock_class, bt_ctf_clock_class_get_name(clock_class), freq);
273b65be
JG
264end:
265 return ret;
266}
267
ac0c6bdd 268uint64_t bt_ctf_clock_class_get_precision(struct bt_ctf_clock_class *clock_class)
87d76bb1
JG
269{
270 uint64_t ret = -1ULL;
271
ac0c6bdd 272 if (!clock_class) {
5134570b 273 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
87d76bb1
JG
274 goto end;
275 }
276
ac0c6bdd 277 ret = clock_class->precision;
87d76bb1
JG
278end:
279 return ret;
280}
281
ac0c6bdd
PP
282int bt_ctf_clock_class_set_precision(struct bt_ctf_clock_class *clock_class,
283 uint64_t precision)
273b65be
JG
284{
285 int ret = 0;
286
5134570b
PP
287 if (!clock_class || precision == -1ULL) {
288 BT_LOGW("Invalid parameter: clock class is NULL or precision is invalid: "
2cf0acd7
PP
289 "addr=%p, name=\"%s\", precision=%" PRIu64,
290 clock_class, bt_ctf_clock_class_get_name(clock_class),
291 precision);
5134570b
PP
292 ret = -1;
293 goto end;
294 }
295
296 if (clock_class->frozen) {
2cf0acd7
PP
297 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
298 clock_class, bt_ctf_clock_class_get_name(clock_class));
273b65be
JG
299 ret = -1;
300 goto end;
301 }
302
ac0c6bdd 303 clock_class->precision = precision;
2cf0acd7
PP
304 BT_LOGV("Set clock class's precision: addr=%p, name=\"%s\", precision=%" PRIu64,
305 clock_class, bt_ctf_clock_class_get_name(clock_class),
306 precision);
273b65be
JG
307end:
308 return ret;
309}
310
ac0c6bdd
PP
311int bt_ctf_clock_class_get_offset_s(struct bt_ctf_clock_class *clock_class,
312 int64_t *offset_s)
87d76bb1 313{
61cf588b 314 int ret = 0;
87d76bb1 315
ac0c6bdd 316 if (!clock_class || !offset_s) {
5134570b 317 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
2cf0acd7
PP
318 "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
319 clock_class, bt_ctf_clock_class_get_name(clock_class),
320 offset_s);
61cf588b 321 ret = -1;
87d76bb1
JG
322 goto end;
323 }
324
ac0c6bdd 325 *offset_s = clock_class->offset_s;
87d76bb1
JG
326end:
327 return ret;
328}
329
ac0c6bdd
PP
330int bt_ctf_clock_class_set_offset_s(struct bt_ctf_clock_class *clock_class,
331 int64_t offset_s)
273b65be
JG
332{
333 int ret = 0;
334
5134570b
PP
335 if (!clock_class) {
336 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
337 ret = -1;
338 goto end;
339 }
340
341 if (clock_class->frozen) {
2cf0acd7
PP
342 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
343 clock_class, bt_ctf_clock_class_get_name(clock_class));
273b65be
JG
344 ret = -1;
345 goto end;
346 }
347
ac0c6bdd 348 clock_class->offset_s = offset_s;
2cf0acd7
PP
349 BT_LOGV("Set clock class's offset (seconds): "
350 "addr=%p, name=\"%s\", offset-s=%" PRId64,
351 clock_class, bt_ctf_clock_class_get_name(clock_class),
352 offset_s);
273b65be
JG
353end:
354 return ret;
355}
356
ac0c6bdd
PP
357int bt_ctf_clock_class_get_offset_cycles(struct bt_ctf_clock_class *clock_class,
358 int64_t *offset)
87d76bb1 359{
61cf588b 360 int ret = 0;
87d76bb1 361
ac0c6bdd 362 if (!clock_class || !offset) {
5134570b 363 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
2cf0acd7
PP
364 "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
365 clock_class, bt_ctf_clock_class_get_name(clock_class),
366 offset);
61cf588b 367 ret = -1;
87d76bb1
JG
368 goto end;
369 }
370
ac0c6bdd 371 *offset = clock_class->offset;
87d76bb1
JG
372end:
373 return ret;
374}
375
ac0c6bdd
PP
376int bt_ctf_clock_class_set_offset_cycles(struct bt_ctf_clock_class *clock_class,
377 int64_t offset)
273b65be
JG
378{
379 int ret = 0;
380
5134570b
PP
381 if (!clock_class) {
382 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
383 ret = -1;
384 goto end;
385 }
386
387 if (clock_class->frozen) {
2cf0acd7
PP
388 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
389 clock_class, bt_ctf_clock_class_get_name(clock_class));
273b65be
JG
390 ret = -1;
391 goto end;
392 }
393
ac0c6bdd 394 clock_class->offset = offset;
2cf0acd7
PP
395 BT_LOGV("Set clock class's offset (cycles): addr=%p, name=\"%s\", offset-cycles=%" PRId64,
396 clock_class, bt_ctf_clock_class_get_name(clock_class), offset);
273b65be
JG
397end:
398 return ret;
399}
400
a2b94977 401bt_bool bt_ctf_clock_class_is_absolute(struct bt_ctf_clock_class *clock_class)
87d76bb1
JG
402{
403 int ret = -1;
404
ac0c6bdd 405 if (!clock_class) {
5134570b 406 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
87d76bb1
JG
407 goto end;
408 }
409
ac0c6bdd 410 ret = clock_class->absolute;
87d76bb1
JG
411end:
412 return ret;
413}
414
ac0c6bdd 415int bt_ctf_clock_class_set_is_absolute(struct bt_ctf_clock_class *clock_class,
a2b94977 416 bt_bool is_absolute)
273b65be
JG
417{
418 int ret = 0;
419
5134570b
PP
420 if (!clock_class) {
421 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
422 ret = -1;
423 goto end;
424 }
425
426 if (clock_class->frozen) {
2cf0acd7
PP
427 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
428 clock_class, bt_ctf_clock_class_get_name(clock_class));
273b65be
JG
429 ret = -1;
430 goto end;
431 }
432
ac0c6bdd 433 clock_class->absolute = !!is_absolute;
2cf0acd7
PP
434 BT_LOGV("Set clock class's absolute flag: addr=%p, name=\"%s\", is-absolute=%d",
435 clock_class, bt_ctf_clock_class_get_name(clock_class),
436 is_absolute);
273b65be
JG
437end:
438 return ret;
439}
440
ac0c6bdd
PP
441const unsigned char *bt_ctf_clock_class_get_uuid(
442 struct bt_ctf_clock_class *clock_class)
85b743f4
JG
443{
444 const unsigned char *ret;
445
5134570b
PP
446 if (!clock_class) {
447 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
448 ret = NULL;
449 goto end;
450 }
451
452 if (!clock_class->uuid_set) {
2cf0acd7
PP
453 BT_LOGV("Clock class's UUID is not set: addr=%p, name=\"%s\"",
454 clock_class, bt_ctf_clock_class_get_name(clock_class));
85b743f4
JG
455 ret = NULL;
456 goto end;
457 }
458
ac0c6bdd 459 ret = clock_class->uuid;
85b743f4
JG
460end:
461 return ret;
462}
463
ac0c6bdd
PP
464int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class *clock_class,
465 const unsigned char *uuid)
85b743f4
JG
466{
467 int ret = 0;
468
5134570b
PP
469 if (!clock_class || !uuid) {
470 BT_LOGW("Invalid parameter: clock class or UUID is NULL: "
2cf0acd7
PP
471 "clock-class-addr=%p, name=\"%s\", uuid-addr=%p",
472 clock_class, bt_ctf_clock_class_get_name(clock_class),
473 uuid);
5134570b
PP
474 ret = -1;
475 goto end;
476 }
477
478 if (clock_class->frozen) {
2cf0acd7
PP
479 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
480 clock_class, bt_ctf_clock_class_get_name(clock_class));
85b743f4
JG
481 ret = -1;
482 goto end;
483 }
484
20eee76e 485 memcpy(clock_class->uuid, uuid, BABELTRACE_UUID_LEN);
ac0c6bdd 486 clock_class->uuid_set = 1;
2cf0acd7 487 BT_LOGV("Set clock class's UUID: addr=%p, name=\"%s\", "
5134570b 488 "uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"",
2cf0acd7 489 clock_class, bt_ctf_clock_class_get_name(clock_class),
5134570b
PP
490 (unsigned int) uuid[0],
491 (unsigned int) uuid[1],
492 (unsigned int) uuid[2],
493 (unsigned int) uuid[3],
494 (unsigned int) uuid[4],
495 (unsigned int) uuid[5],
496 (unsigned int) uuid[6],
497 (unsigned int) uuid[7],
498 (unsigned int) uuid[8],
499 (unsigned int) uuid[9],
500 (unsigned int) uuid[10],
501 (unsigned int) uuid[11],
502 (unsigned int) uuid[12],
503 (unsigned int) uuid[13],
504 (unsigned int) uuid[14],
505 (unsigned int) uuid[15]);
85b743f4
JG
506end:
507 return ret;
508}
509
ac0c6bdd 510static uint64_t ns_from_value(uint64_t frequency, uint64_t value)
4ef18cab
PP
511{
512 uint64_t ns;
513
514 if (frequency == 1000000000) {
515 ns = value;
516 } else {
036a7cac
PP
517 double dblres = ((1e9 * (double) value) / (double) frequency);
518
519 if (dblres >= (double) UINT64_MAX) {
520 /* Overflows uint64_t */
521 ns = -1ULL;
522 } else {
523 ns = (uint64_t) dblres;
524 }
4ef18cab
PP
525 }
526
527 return ns;
528}
529
273b65be 530BT_HIDDEN
ac0c6bdd 531void bt_ctf_clock_class_freeze(struct bt_ctf_clock_class *clock_class)
273b65be 532{
ac0c6bdd 533 if (!clock_class) {
5134570b 534 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
273b65be
JG
535 return;
536 }
537
5134570b 538 if (!clock_class->frozen) {
2cf0acd7
PP
539 BT_LOGD("Freezing clock class: addr=%p, name=\"%s\"",
540 clock_class, bt_ctf_clock_class_get_name(clock_class));
5134570b
PP
541 clock_class->frozen = 1;
542 }
273b65be
JG
543}
544
545BT_HIDDEN
ac0c6bdd 546void bt_ctf_clock_class_serialize(struct bt_ctf_clock_class *clock_class,
273b65be
JG
547 struct metadata_context *context)
548{
549 unsigned char *uuid;
550
5134570b 551 BT_LOGD("Serializing clock class's metadata: clock-class-addr=%p, "
2cf0acd7
PP
552 "name=\"%s\", metadata-context-addr=%p", clock_class,
553 bt_ctf_clock_class_get_name(clock_class), context);
5134570b 554
ac0c6bdd 555 if (!clock_class || !context) {
5134570b 556 BT_LOGW("Invalid parameter: clock class or metadata context is NULL: "
2cf0acd7
PP
557 "clock-class-addr=%p, name=\"%s\", metadata-context-addr=%p",
558 clock_class, bt_ctf_clock_class_get_name(clock_class),
559 context);
273b65be
JG
560 return;
561 }
562
ac0c6bdd 563 uuid = clock_class->uuid;
273b65be
JG
564 g_string_append(context->string, "clock {\n");
565 g_string_append_printf(context->string, "\tname = %s;\n",
ac0c6bdd 566 clock_class->name->str);
ce57dd3c
PP
567
568 if (clock_class->uuid_set) {
569 g_string_append_printf(context->string,
570 "\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n",
571 uuid[0], uuid[1], uuid[2], uuid[3],
572 uuid[4], uuid[5], uuid[6], uuid[7],
573 uuid[8], uuid[9], uuid[10], uuid[11],
574 uuid[12], uuid[13], uuid[14], uuid[15]);
575 }
576
ac0c6bdd 577 if (clock_class->description) {
273b65be 578 g_string_append_printf(context->string, "\tdescription = \"%s\";\n",
ac0c6bdd 579 clock_class->description->str);
273b65be
JG
580 }
581
582 g_string_append_printf(context->string, "\tfreq = %" PRIu64 ";\n",
ac0c6bdd 583 clock_class->frequency);
273b65be 584 g_string_append_printf(context->string, "\tprecision = %" PRIu64 ";\n",
ac0c6bdd 585 clock_class->precision);
273b65be 586 g_string_append_printf(context->string, "\toffset_s = %" PRIu64 ";\n",
ac0c6bdd 587 clock_class->offset_s);
273b65be 588 g_string_append_printf(context->string, "\toffset = %" PRIu64 ";\n",
ac0c6bdd 589 clock_class->offset);
273b65be 590 g_string_append_printf(context->string, "\tabsolute = %s;\n",
115d6070 591 clock_class->absolute ? "true" : "false");
273b65be
JG
592 g_string_append(context->string, "};\n\n");
593}
594
273b65be 595static
ac0c6bdd 596void bt_ctf_clock_class_destroy(struct bt_object *obj)
273b65be 597{
ac0c6bdd 598 struct bt_ctf_clock_class *clock_class;
273b65be 599
ac0c6bdd 600 clock_class = container_of(obj, struct bt_ctf_clock_class, base);
2cf0acd7
PP
601 BT_LOGD("Destroying clock class: addr=%p, name=\"%s\"",
602 obj, bt_ctf_clock_class_get_name(clock_class));
ac0c6bdd
PP
603 if (clock_class->name) {
604 g_string_free(clock_class->name, TRUE);
273b65be 605 }
ac0c6bdd
PP
606 if (clock_class->description) {
607 g_string_free(clock_class->description, TRUE);
273b65be
JG
608 }
609
ac0c6bdd 610 g_free(clock_class);
273b65be 611}
4ef18cab 612
61ec14e6
JG
613static
614void bt_ctf_clock_value_destroy(struct bt_object *obj)
615{
616 struct bt_ctf_clock_value *value;
617
618 if (!obj) {
619 return;
620 }
621
622 value = container_of(obj, struct bt_ctf_clock_value, base);
2cf0acd7
PP
623 BT_LOGD("Destroying clock value: addr=%p, clock-class-addr=%p, "
624 "clock-class-name=\"%s\"", obj, value->clock_class,
625 bt_ctf_clock_class_get_name(value->clock_class));
61ec14e6
JG
626 bt_put(value->clock_class);
627 g_free(value);
628}
629
036a7cac
PP
630static
631void set_ns_from_epoch(struct bt_ctf_clock_value *clock_value)
632{
633 struct bt_ctf_clock_class *clock_class = clock_value->clock_class;
634 int64_t diff;
635 int64_t s_ns;
636 uint64_t u_ns;
637 uint64_t cycles;
638
639 /* Initialize nanosecond timestamp to clock's offset in seconds */
640 if (clock_class->offset_s <= (INT64_MIN / 1000000000) ||
641 clock_class->offset_s >= (INT64_MAX / 1000000000)) {
642 /*
643 * Overflow: offset in seconds converted to nanoseconds
644 * is outside the int64_t range.
645 */
646 clock_value->ns_from_epoch_overflows = true;
647 goto end;
648 }
649
650 clock_value->ns_from_epoch = clock_class->offset_s * (int64_t) 1000000000;
651
652 /* Add offset in cycles */
653 if (clock_class->offset < 0) {
654 cycles = (uint64_t) (-clock_class->offset);
655 } else {
656 cycles = (uint64_t) clock_class->offset;
657 }
658
659 u_ns = ns_from_value(clock_class->frequency, cycles);
660
661 if (u_ns == -1ULL || u_ns >= INT64_MAX) {
662 /*
663 * Overflow: offset in cycles converted to nanoseconds
664 * is outside the int64_t range.
665 */
666 clock_value->ns_from_epoch_overflows = true;
667 goto end;
668 }
669
670 s_ns = (int64_t) u_ns;
671 assert(s_ns >= 0);
672
673 if (clock_class->offset < 0) {
674 if (clock_value->ns_from_epoch >= 0) {
675 /*
676 * Offset in cycles is negative so it must also
677 * be negative once converted to nanoseconds.
678 */
679 s_ns = -s_ns;
680 goto offset_ok;
681 }
682
683 diff = clock_value->ns_from_epoch - INT64_MIN;
684
685 if (s_ns >= diff) {
686 /*
687 * Overflow: current timestamp in nanoseconds
688 * plus the offset in cycles converted to
689 * nanoseconds is outside the int64_t range.
690 */
691 clock_value->ns_from_epoch_overflows = true;
692 goto end;
693 }
694
695 /*
696 * Offset in cycles is negative so it must also be
697 * negative once converted to nanoseconds.
698 */
699 s_ns = -s_ns;
700 } else {
701 if (clock_value->ns_from_epoch <= 0) {
702 goto offset_ok;
703 }
704
705 diff = INT64_MAX - clock_value->ns_from_epoch;
706
707 if (s_ns >= diff) {
708 /*
709 * Overflow: current timestamp in nanoseconds
710 * plus the offset in cycles converted to
711 * nanoseconds is outside the int64_t range.
712 */
713 clock_value->ns_from_epoch_overflows = true;
714 goto end;
715 }
716 }
717
718offset_ok:
719 clock_value->ns_from_epoch += s_ns;
720
721 /* Add clock value (cycles) */
722 u_ns = ns_from_value(clock_class->frequency, clock_value->value);
723
724 if (u_ns == -1ULL || u_ns >= INT64_MAX) {
725 /*
726 * Overflow: value converted to nanoseconds is outside
727 * the int64_t range.
728 */
729 clock_value->ns_from_epoch_overflows = true;
730 goto end;
731 }
732
733 s_ns = (int64_t) u_ns;
734 assert(s_ns >= 0);
735
736 /* Clock value (cycles) is always positive */
737 if (clock_value->ns_from_epoch <= 0) {
738 goto value_ok;
739 }
740
741 diff = INT64_MAX - clock_value->ns_from_epoch;
742
743 if (s_ns >= diff) {
744 /*
745 * Overflow: current timestamp in nanoseconds plus the
746 * clock value converted to nanoseconds is outside the
747 * int64_t range.
748 */
749 clock_value->ns_from_epoch_overflows = true;
750 goto end;
751 }
752
753value_ok:
754 clock_value->ns_from_epoch += s_ns;
755
756end:
757 if (clock_value->ns_from_epoch_overflows) {
758 clock_value->ns_from_epoch = 0;
759 }
760}
761
61ec14e6 762struct bt_ctf_clock_value *bt_ctf_clock_value_create(
ac0c6bdd 763 struct bt_ctf_clock_class *clock_class, uint64_t value)
4ef18cab 764{
61ec14e6 765 struct bt_ctf_clock_value *ret = NULL;
4ef18cab 766
5134570b 767 BT_LOGD("Creating clock value object: clock-class-addr=%p, "
2cf0acd7
PP
768 "clock-class-name=\"%s\", value=%" PRIu64, clock_class,
769 bt_ctf_clock_class_get_name(clock_class), value);
5134570b 770
ac0c6bdd 771 if (!clock_class) {
5134570b 772 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
4ef18cab
PP
773 goto end;
774 }
775
61ec14e6
JG
776 ret = g_new0(struct bt_ctf_clock_value, 1);
777 if (!ret) {
5134570b 778 BT_LOGE_STR("Failed to allocate one clock value.");
61ec14e6
JG
779 goto end;
780 }
781
782 bt_object_init(ret, bt_ctf_clock_value_destroy);
ac0c6bdd 783 ret->clock_class = bt_get(clock_class);
61ec14e6 784 ret->value = value;
036a7cac 785 set_ns_from_epoch(ret);
0b4b8df9 786 bt_ctf_clock_class_freeze(clock_class);
2cf0acd7 787 BT_LOGD("Created clock value object: clock-value-addr=%p, "
036a7cac
PP
788 "clock-class-addr=%p, clock-class-name=\"%s\", "
789 "ns-from-epoch=%" PRId64 ", ns-from-epoch-overflows=%d",
790 ret, clock_class, bt_ctf_clock_class_get_name(clock_class),
791 ret->ns_from_epoch, ret->ns_from_epoch_overflows);
792
61ec14e6
JG
793end:
794 return ret;
795}
4ef18cab 796
61ec14e6
JG
797int bt_ctf_clock_value_get_value(
798 struct bt_ctf_clock_value *clock_value, uint64_t *raw_value)
799{
800 int ret = 0;
4ef18cab 801
61ec14e6 802 if (!clock_value || !raw_value) {
5134570b
PP
803 BT_LOGW("Invalid parameter: clock value or raw value is NULL: "
804 "clock-value-addr=%p, raw-value-addr=%p",
805 clock_value, raw_value);
61ec14e6
JG
806 ret = -1;
807 goto end;
808 }
4ef18cab 809
61ec14e6 810 *raw_value = clock_value->value;
4ef18cab 811end:
61ec14e6
JG
812 return ret;
813}
814
1556a1af 815int bt_ctf_clock_value_get_value_ns_from_epoch(struct bt_ctf_clock_value *value,
61ec14e6
JG
816 int64_t *ret_value_ns)
817{
818 int ret = 0;
61ec14e6
JG
819
820 if (!value || !ret_value_ns) {
5134570b
PP
821 BT_LOGW("Invalid parameter: clock value or return value pointer is NULL: "
822 "clock-value-addr=%p, ret-value-addr=%p",
823 value, ret_value_ns);
61ec14e6
JG
824 ret = -1;
825 goto end;
826 }
827
036a7cac
PP
828 if (value->ns_from_epoch_overflows) {
829 BT_LOGW("Clock value converted to nanoseconds from Epoch overflows the signed 64-bit integer range: "
830 "clock-value-addr=%p, "
831 "clock-class-offset-s=%" PRId64 ", "
832 "clock-class-offset-cycles=%" PRId64 ", "
833 "value=%" PRIu64,
834 value, value->clock_class->offset_s,
835 value->clock_class->offset,
836 value->value);
837 ret = -1;
838 goto end;
839 }
61ec14e6 840
036a7cac 841 *ret_value_ns = value->ns_from_epoch;
61ec14e6 842
61ec14e6
JG
843end:
844 return ret;
4ef18cab 845}
6f57e458
PP
846
847struct bt_ctf_clock_class *bt_ctf_clock_value_get_class(
848 struct bt_ctf_clock_value *clock_value)
849{
850 struct bt_ctf_clock_class *clock_class = NULL;
851
852 if (!clock_value) {
5134570b 853 BT_LOGW_STR("Invalid parameter: clock value is NULL.");
6f57e458
PP
854 goto end;
855 }
856
857 clock_class = bt_get(clock_value->clock_class);
858
859end:
860 return clock_class;
861}
This page took 0.084539 seconds and 4 git commands to generate.