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