Workaround glib g_module_open bug
[babeltrace.git] / formats / ctf / ir / clock.c
CommitLineData
273b65be
JG
1/*
2 * clock.c
3 *
d2dc44b6 4 * Babeltrace CTF IR - Clock
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
adc315b8 29#include <babeltrace/ctf-ir/clock-internal.h>
654c1444 30#include <babeltrace/ctf-ir/utils.h>
83509119 31#include <babeltrace/ref.h>
273b65be 32#include <babeltrace/ctf-writer/writer-internal.h>
83509119 33#include <babeltrace/object-internal.h>
273b65be
JG
34#include <babeltrace/compiler.h>
35#include <inttypes.h>
36
37static
83509119 38void bt_ctf_clock_destroy(struct bt_object *obj);
273b65be 39
4c426c17
JG
40BT_HIDDEN
41struct bt_ctf_clock *_bt_ctf_clock_create(void)
273b65be 42{
4c426c17
JG
43 struct bt_ctf_clock *clock = g_new0(
44 struct bt_ctf_clock, 1);
45
46 if (!clock) {
47 goto end;
48 }
49
50 clock->precision = 1;
51 clock->frequency = 1000000000;
83509119 52 bt_object_init(clock, bt_ctf_clock_destroy);
4c426c17
JG
53end:
54 return clock;
55}
56
57BT_HIDDEN
58int bt_ctf_clock_set_name(struct bt_ctf_clock *clock,
59 const char *name)
60{
61 int ret = 0;
273b65be 62
654c1444 63 if (bt_ctf_validate_identifier(name)) {
4c426c17
JG
64 ret = -1;
65 goto end;
273b65be
JG
66 }
67
4c426c17 68 if (clock->name) {
e1ae7645
JG
69 g_string_assign(clock->name, name);
70 } else {
71 clock->name = g_string_new(name);
72 if (!clock->name) {
73 ret = -1;
74 goto end;
75 }
273b65be
JG
76 }
77
4c426c17
JG
78end:
79 return ret;
80}
81
82struct bt_ctf_clock *bt_ctf_clock_create(const char *name)
83{
84 int ret;
85 struct bt_ctf_clock *clock = NULL;
86
87 clock = _bt_ctf_clock_create();
88 if (!clock) {
89 goto error;
90 }
91
92 ret = bt_ctf_clock_set_name(clock, name);
93 if (ret) {
83509119 94 goto error;
273b65be
JG
95 }
96
19dd40db 97 ret = bt_uuid_generate(clock->uuid);
be018f15 98 if (ret) {
83509119 99 goto error;
be018f15
JG
100 }
101
cfeb617e
PP
102 /*
103 * For backward compatibility reasons, a fresh clock can have
104 * a value because it could be added to a trace created by a
105 * CTF writer. As soon as this clock is added to a non-writer
106 * trace, then its value/time functions will be disabled.
107 */
108 clock->has_value = 1;
be018f15 109 clock->uuid_set = 1;
273b65be 110 return clock;
273b65be 111error:
83509119
JG
112 BT_PUT(clock);
113 return clock;
87d76bb1
JG
114}
115
116const char *bt_ctf_clock_get_name(struct bt_ctf_clock *clock)
117{
118 const char *ret = NULL;
119
120 if (!clock) {
121 goto end;
122 }
123
124 if (clock->name) {
125 ret = clock->name->str;
126 }
127
128end:
129 return ret;
130}
131
132const char *bt_ctf_clock_get_description(struct bt_ctf_clock *clock)
133{
134 const char *ret = NULL;
135
136 if (!clock) {
137 goto end;
138 }
139
140 if (clock->description) {
141 ret = clock->description->str;
142 }
143end:
144 return ret;
273b65be
JG
145}
146
147int bt_ctf_clock_set_description(struct bt_ctf_clock *clock, const char *desc)
148{
149 int ret = 0;
150
151 if (!clock || !desc || clock->frozen) {
152 ret = -1;
153 goto end;
154 }
155
87d76bb1 156 clock->description = g_string_new(desc);
273b65be
JG
157 ret = clock->description ? 0 : -1;
158end:
159 return ret;
160}
161
87d76bb1
JG
162uint64_t bt_ctf_clock_get_frequency(struct bt_ctf_clock *clock)
163{
164 uint64_t ret = -1ULL;
165
166 if (!clock) {
167 goto end;
168 }
169
170 ret = clock->frequency;
171end:
172 return ret;
173}
174
273b65be
JG
175int bt_ctf_clock_set_frequency(struct bt_ctf_clock *clock, uint64_t freq)
176{
177 int ret = 0;
178
179 if (!clock || clock->frozen) {
180 ret = -1;
181 goto end;
182 }
183
184 clock->frequency = freq;
185end:
186 return ret;
187}
188
87d76bb1
JG
189uint64_t bt_ctf_clock_get_precision(struct bt_ctf_clock *clock)
190{
191 uint64_t ret = -1ULL;
192
193 if (!clock) {
194 goto end;
195 }
196
197 ret = clock->precision;
198end:
199 return ret;
200}
201
273b65be
JG
202int bt_ctf_clock_set_precision(struct bt_ctf_clock *clock, uint64_t precision)
203{
204 int ret = 0;
205
206 if (!clock || clock->frozen) {
207 ret = -1;
208 goto end;
209 }
210
211 clock->precision = precision;
212end:
213 return ret;
214}
215
61cf588b 216int bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock, int64_t *offset_s)
87d76bb1 217{
61cf588b 218 int ret = 0;
87d76bb1 219
61cf588b
MD
220 if (!clock || !offset_s) {
221 ret = -1;
87d76bb1
JG
222 goto end;
223 }
224
61cf588b 225 *offset_s = clock->offset_s;
87d76bb1
JG
226end:
227 return ret;
228}
229
61cf588b 230int bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock, int64_t offset_s)
273b65be
JG
231{
232 int ret = 0;
233
234 if (!clock || clock->frozen) {
235 ret = -1;
236 goto end;
237 }
238
239 clock->offset_s = offset_s;
240end:
241 return ret;
242}
243
61cf588b 244int bt_ctf_clock_get_offset(struct bt_ctf_clock *clock, int64_t *offset)
87d76bb1 245{
61cf588b 246 int ret = 0;
87d76bb1 247
61cf588b
MD
248 if (!clock || !offset) {
249 ret = -1;
87d76bb1
JG
250 goto end;
251 }
252
61cf588b 253 *offset = clock->offset;
87d76bb1
JG
254end:
255 return ret;
256}
257
61cf588b 258int bt_ctf_clock_set_offset(struct bt_ctf_clock *clock, int64_t offset)
273b65be
JG
259{
260 int ret = 0;
261
262 if (!clock || clock->frozen) {
263 ret = -1;
264 goto end;
265 }
266
267 clock->offset = offset;
268end:
269 return ret;
270}
271
87d76bb1
JG
272int bt_ctf_clock_get_is_absolute(struct bt_ctf_clock *clock)
273{
274 int ret = -1;
275
276 if (!clock) {
277 goto end;
278 }
279
280 ret = clock->absolute;
281end:
282 return ret;
283}
284
273b65be
JG
285int bt_ctf_clock_set_is_absolute(struct bt_ctf_clock *clock, int is_absolute)
286{
287 int ret = 0;
288
289 if (!clock || clock->frozen) {
290 ret = -1;
291 goto end;
292 }
293
294 clock->absolute = !!is_absolute;
295end:
296 return ret;
297}
298
85b743f4
JG
299const unsigned char *bt_ctf_clock_get_uuid(struct bt_ctf_clock *clock)
300{
301 const unsigned char *ret;
302
be018f15 303 if (!clock || !clock->uuid_set) {
85b743f4
JG
304 ret = NULL;
305 goto end;
306 }
307
308 ret = clock->uuid;
309end:
310 return ret;
311}
312
313int bt_ctf_clock_set_uuid(struct bt_ctf_clock *clock, const unsigned char *uuid)
314{
315 int ret = 0;
316
be018f15 317 if (!clock || !uuid || clock->frozen) {
85b743f4
JG
318 ret = -1;
319 goto end;
320 }
321
322 memcpy(clock->uuid, uuid, sizeof(uuid_t));
be018f15 323 clock->uuid_set = 1;
85b743f4
JG
324end:
325 return ret;
326}
327
4ef18cab
PP
328uint64_t ns_from_value(uint64_t frequency, uint64_t value)
329{
330 uint64_t ns;
331
332 if (frequency == 1000000000) {
333 ns = value;
334 } else {
335 ns = (uint64_t) ((1e9 * (double) value) / (double) frequency);
336 }
337
338 return ns;
339}
340
61cf588b 341int bt_ctf_clock_get_time(struct bt_ctf_clock *clock, int64_t *time)
87d76bb1 342{
61cf588b 343 int ret = 0;
87d76bb1 344
61cf588b
MD
345 if (!clock || !time) {
346 ret = -1;
87d76bb1
JG
347 goto end;
348 }
349
cfeb617e
PP
350
351 if (!clock->has_value) {
352 /*
353 * Clock belongs to a non-writer mode trace and thus
354 * this function is disabled.
355 */
356 goto end;
357 }
358
4ef18cab 359 *time = (int64_t) ns_from_value(clock->frequency, clock->value);
e1e30a8c 360
87d76bb1
JG
361end:
362 return ret;
363}
364
61cf588b 365int bt_ctf_clock_set_time(struct bt_ctf_clock *clock, int64_t time)
273b65be
JG
366{
367 int ret = 0;
49e545f5 368 int64_t value;
273b65be
JG
369
370 /* Timestamps are strictly monotonic */
e1e30a8c
PP
371 if (!clock) {
372 ret = -1;
373 goto end;
374 }
375
cfeb617e
PP
376
377 if (!clock->has_value) {
378 /*
379 * Clock belongs to a non-writer mode trace and thus
380 * this function is disabled.
381 */
382 ret = -1;
383 goto end;
384 }
385
e1e30a8c
PP
386 /* Common case where cycles are actually nanoseconds */
387 if (clock->frequency == 1000000000) {
49e545f5
JG
388 value = time;
389 } else {
390 value = (uint64_t) (((double) time *
391 (double) clock->frequency) / 1e9);
e1e30a8c
PP
392 }
393
49e545f5 394 ret = bt_ctf_clock_set_value(clock, value);
e1e30a8c
PP
395end:
396 return ret;
397}
398
399uint64_t bt_ctf_clock_get_value(struct bt_ctf_clock *clock)
400{
401 uint64_t ret = -1ULL;
402
403 if (!clock) {
404 goto end;
405 }
406
cfeb617e
PP
407 if (!clock->has_value) {
408 /*
409 * Clock belongs to a non-writer mode trace and thus
410 * this function is disabled.
411 */
412 goto end;
413 }
414
e1e30a8c
PP
415 ret = clock->value;
416end:
417 return ret;
418}
419
420int bt_ctf_clock_set_value(struct bt_ctf_clock *clock, uint64_t value)
421{
422 int ret = 0;
423
cfeb617e
PP
424 if (!clock) {
425 ret = -1;
426 goto end;
427 }
428
429 if (!clock->has_value) {
430 /*
431 * Clock belongs to a non-writer mode trace and thus
432 * this function is disabled.
433 */
434 ret = -1;
435 goto end;
436 }
437
e1e30a8c 438 /* Timestamps are strictly monotonic */
cfeb617e 439 if (value < clock->value) {
273b65be
JG
440 ret = -1;
441 goto end;
442 }
443
e1e30a8c 444 clock->value = value;
273b65be
JG
445end:
446 return ret;
447}
448
449void bt_ctf_clock_get(struct bt_ctf_clock *clock)
450{
83509119 451 bt_get(clock);
273b65be
JG
452}
453
454void bt_ctf_clock_put(struct bt_ctf_clock *clock)
455{
83509119 456 bt_put(clock);
273b65be
JG
457}
458
459BT_HIDDEN
460void bt_ctf_clock_freeze(struct bt_ctf_clock *clock)
461{
462 if (!clock) {
463 return;
464 }
465
466 clock->frozen = 1;
467}
468
469BT_HIDDEN
470void bt_ctf_clock_serialize(struct bt_ctf_clock *clock,
471 struct metadata_context *context)
472{
473 unsigned char *uuid;
474
475 if (!clock || !context) {
476 return;
477 }
478
479 uuid = clock->uuid;
480 g_string_append(context->string, "clock {\n");
481 g_string_append_printf(context->string, "\tname = %s;\n",
482 clock->name->str);
483 g_string_append_printf(context->string,
484 "\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n",
485 uuid[0], uuid[1], uuid[2], uuid[3],
486 uuid[4], uuid[5], uuid[6], uuid[7],
487 uuid[8], uuid[9], uuid[10], uuid[11],
488 uuid[12], uuid[13], uuid[14], uuid[15]);
7a69f348 489 if (clock->description) {
273b65be
JG
490 g_string_append_printf(context->string, "\tdescription = \"%s\";\n",
491 clock->description->str);
492 }
493
494 g_string_append_printf(context->string, "\tfreq = %" PRIu64 ";\n",
495 clock->frequency);
496 g_string_append_printf(context->string, "\tprecision = %" PRIu64 ";\n",
497 clock->precision);
498 g_string_append_printf(context->string, "\toffset_s = %" PRIu64 ";\n",
499 clock->offset_s);
500 g_string_append_printf(context->string, "\toffset = %" PRIu64 ";\n",
501 clock->offset);
502 g_string_append_printf(context->string, "\tabsolute = %s;\n",
503 clock->absolute ? "TRUE" : "FALSE");
504 g_string_append(context->string, "};\n\n");
505}
506
273b65be 507static
83509119 508void bt_ctf_clock_destroy(struct bt_object *obj)
273b65be
JG
509{
510 struct bt_ctf_clock *clock;
273b65be 511
83509119 512 clock = container_of(obj, struct bt_ctf_clock, base);
273b65be
JG
513 if (clock->name) {
514 g_string_free(clock->name, TRUE);
515 }
516
517 if (clock->description) {
518 g_string_free(clock->description, TRUE);
519 }
520
521 g_free(clock);
522}
4ef18cab
PP
523
524int64_t bt_ctf_clock_ns_from_value(struct bt_ctf_clock *clock, uint64_t value)
525{
526 int64_t ns = -1ULL;
527
528 if (!clock) {
529 goto end;
530 }
531
532 /* Initialize nanosecond timestamp to clock's offset in seconds */
533 ns = clock->offset_s * 1000000000;
534
535 /* Add offset in cycles, converted to nanoseconds */
536 ns += ns_from_value(clock->frequency, clock->offset);
537
538 /* Add given value, converter to nanoseconds */
539 ns += ns_from_value(clock->frequency, value);
540
541end:
542 return ns;
543}
This page took 0.053431 seconds and 4 git commands to generate.