Commit | Line | Data |
---|---|---|
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 | ||
ac0c6bdd | 29 | #include <babeltrace/ctf-ir/clock-class-internal.h> |
654c1444 | 30 | #include <babeltrace/ctf-ir/utils.h> |
83509119 | 31 | #include <babeltrace/ref.h> |
83509119 | 32 | #include <babeltrace/object-internal.h> |
3d9990ac | 33 | #include <babeltrace/compiler-internal.h> |
273b65be JG |
34 | #include <inttypes.h> |
35 | ||
36 | static | |
ac0c6bdd | 37 | void bt_ctf_clock_class_destroy(struct bt_object *obj); |
273b65be | 38 | |
4c426c17 | 39 | BT_HIDDEN |
ac0c6bdd | 40 | bool bt_ctf_clock_class_is_valid(struct bt_ctf_clock_class *clock_class) |
c06116f3 | 41 | { |
ac0c6bdd | 42 | return clock_class && clock_class->name; |
c06116f3 PP |
43 | } |
44 | ||
ac0c6bdd | 45 | int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class *clock_class, |
4c426c17 JG |
46 | const char *name) |
47 | { | |
48 | int ret = 0; | |
273b65be | 49 | |
ac0c6bdd | 50 | if (!clock_class || clock_class->frozen) { |
c06116f3 PP |
51 | ret = -1; |
52 | goto end; | |
53 | } | |
54 | ||
654c1444 | 55 | if (bt_ctf_validate_identifier(name)) { |
4c426c17 JG |
56 | ret = -1; |
57 | goto end; | |
273b65be JG |
58 | } |
59 | ||
ac0c6bdd PP |
60 | if (clock_class->name) { |
61 | g_string_assign(clock_class->name, name); | |
e1ae7645 | 62 | } else { |
ac0c6bdd PP |
63 | clock_class->name = g_string_new(name); |
64 | if (!clock_class->name) { | |
e1ae7645 JG |
65 | ret = -1; |
66 | goto end; | |
67 | } | |
273b65be JG |
68 | } |
69 | ||
4c426c17 JG |
70 | end: |
71 | return ret; | |
72 | } | |
73 | ||
ac0c6bdd | 74 | struct bt_ctf_clock_class *bt_ctf_clock_class_create(const char *name) |
4c426c17 JG |
75 | { |
76 | int ret; | |
ac0c6bdd PP |
77 | struct bt_ctf_clock_class *clock_class = |
78 | g_new0(struct bt_ctf_clock_class, 1); | |
4c426c17 | 79 | |
ac0c6bdd | 80 | if (!clock_class) { |
4c426c17 JG |
81 | goto error; |
82 | } | |
83 | ||
ac0c6bdd PP |
84 | clock_class->precision = 1; |
85 | clock_class->frequency = 1000000000; | |
86 | bt_object_init(clock_class, bt_ctf_clock_class_destroy); | |
85380e99 JG |
87 | |
88 | if (name) { | |
ac0c6bdd | 89 | ret = bt_ctf_clock_class_set_name(clock_class, name); |
85380e99 JG |
90 | if (ret) { |
91 | goto error; | |
92 | } | |
273b65be JG |
93 | } |
94 | ||
ac0c6bdd | 95 | ret = bt_uuid_generate(clock_class->uuid); |
be018f15 | 96 | if (ret) { |
83509119 | 97 | goto error; |
be018f15 JG |
98 | } |
99 | ||
ac0c6bdd PP |
100 | clock_class->uuid_set = 1; |
101 | return clock_class; | |
273b65be | 102 | error: |
ac0c6bdd PP |
103 | BT_PUT(clock_class); |
104 | return clock_class; | |
87d76bb1 JG |
105 | } |
106 | ||
ac0c6bdd | 107 | const char *bt_ctf_clock_class_get_name(struct bt_ctf_clock_class *clock_class) |
87d76bb1 JG |
108 | { |
109 | const char *ret = NULL; | |
110 | ||
ac0c6bdd | 111 | if (!clock_class) { |
87d76bb1 JG |
112 | goto end; |
113 | } | |
114 | ||
ac0c6bdd PP |
115 | if (clock_class->name) { |
116 | ret = clock_class->name->str; | |
87d76bb1 JG |
117 | } |
118 | ||
119 | end: | |
120 | return ret; | |
121 | } | |
122 | ||
ac0c6bdd PP |
123 | const char *bt_ctf_clock_class_get_description( |
124 | struct bt_ctf_clock_class *clock_class) | |
87d76bb1 JG |
125 | { |
126 | const char *ret = NULL; | |
127 | ||
ac0c6bdd | 128 | if (!clock_class) { |
87d76bb1 JG |
129 | goto end; |
130 | } | |
131 | ||
ac0c6bdd PP |
132 | if (clock_class->description) { |
133 | ret = clock_class->description->str; | |
87d76bb1 JG |
134 | } |
135 | end: | |
136 | return ret; | |
273b65be JG |
137 | } |
138 | ||
ac0c6bdd PP |
139 | int bt_ctf_clock_class_set_description(struct bt_ctf_clock_class *clock_class, |
140 | const char *desc) | |
273b65be JG |
141 | { |
142 | int ret = 0; | |
143 | ||
ac0c6bdd | 144 | if (!clock_class || !desc || clock_class->frozen) { |
273b65be JG |
145 | ret = -1; |
146 | goto end; | |
147 | } | |
148 | ||
ac0c6bdd PP |
149 | clock_class->description = g_string_new(desc); |
150 | ret = clock_class->description ? 0 : -1; | |
273b65be JG |
151 | end: |
152 | return ret; | |
153 | } | |
154 | ||
ac0c6bdd PP |
155 | uint64_t bt_ctf_clock_class_get_frequency( |
156 | struct bt_ctf_clock_class *clock_class) | |
87d76bb1 JG |
157 | { |
158 | uint64_t ret = -1ULL; | |
159 | ||
ac0c6bdd | 160 | if (!clock_class) { |
87d76bb1 JG |
161 | goto end; |
162 | } | |
163 | ||
ac0c6bdd | 164 | ret = clock_class->frequency; |
87d76bb1 JG |
165 | end: |
166 | return ret; | |
167 | } | |
168 | ||
ac0c6bdd PP |
169 | int bt_ctf_clock_class_set_frequency(struct bt_ctf_clock_class *clock_class, |
170 | uint64_t freq) | |
273b65be JG |
171 | { |
172 | int ret = 0; | |
173 | ||
9ac68eb1 | 174 | if (!clock_class || clock_class->frozen || freq == -1ULL) { |
273b65be JG |
175 | ret = -1; |
176 | goto end; | |
177 | } | |
178 | ||
ac0c6bdd | 179 | clock_class->frequency = freq; |
273b65be JG |
180 | end: |
181 | return ret; | |
182 | } | |
183 | ||
ac0c6bdd | 184 | uint64_t bt_ctf_clock_class_get_precision(struct bt_ctf_clock_class *clock_class) |
87d76bb1 JG |
185 | { |
186 | uint64_t ret = -1ULL; | |
187 | ||
ac0c6bdd | 188 | if (!clock_class) { |
87d76bb1 JG |
189 | goto end; |
190 | } | |
191 | ||
ac0c6bdd | 192 | ret = clock_class->precision; |
87d76bb1 JG |
193 | end: |
194 | return ret; | |
195 | } | |
196 | ||
ac0c6bdd PP |
197 | int bt_ctf_clock_class_set_precision(struct bt_ctf_clock_class *clock_class, |
198 | uint64_t precision) | |
273b65be JG |
199 | { |
200 | int ret = 0; | |
201 | ||
9ac68eb1 | 202 | if (!clock_class || clock_class->frozen || precision == -1ULL) { |
273b65be JG |
203 | ret = -1; |
204 | goto end; | |
205 | } | |
206 | ||
ac0c6bdd | 207 | clock_class->precision = precision; |
273b65be JG |
208 | end: |
209 | return ret; | |
210 | } | |
211 | ||
ac0c6bdd PP |
212 | int bt_ctf_clock_class_get_offset_s(struct bt_ctf_clock_class *clock_class, |
213 | int64_t *offset_s) | |
87d76bb1 | 214 | { |
61cf588b | 215 | int ret = 0; |
87d76bb1 | 216 | |
ac0c6bdd | 217 | if (!clock_class || !offset_s) { |
61cf588b | 218 | ret = -1; |
87d76bb1 JG |
219 | goto end; |
220 | } | |
221 | ||
ac0c6bdd | 222 | *offset_s = clock_class->offset_s; |
87d76bb1 JG |
223 | end: |
224 | return ret; | |
225 | } | |
226 | ||
ac0c6bdd PP |
227 | int bt_ctf_clock_class_set_offset_s(struct bt_ctf_clock_class *clock_class, |
228 | int64_t offset_s) | |
273b65be JG |
229 | { |
230 | int ret = 0; | |
231 | ||
ac0c6bdd | 232 | if (!clock_class || clock_class->frozen) { |
273b65be JG |
233 | ret = -1; |
234 | goto end; | |
235 | } | |
236 | ||
ac0c6bdd | 237 | clock_class->offset_s = offset_s; |
273b65be JG |
238 | end: |
239 | return ret; | |
240 | } | |
241 | ||
ac0c6bdd PP |
242 | int bt_ctf_clock_class_get_offset_cycles(struct bt_ctf_clock_class *clock_class, |
243 | int64_t *offset) | |
87d76bb1 | 244 | { |
61cf588b | 245 | int ret = 0; |
87d76bb1 | 246 | |
ac0c6bdd | 247 | if (!clock_class || !offset) { |
61cf588b | 248 | ret = -1; |
87d76bb1 JG |
249 | goto end; |
250 | } | |
251 | ||
ac0c6bdd | 252 | *offset = clock_class->offset; |
87d76bb1 JG |
253 | end: |
254 | return ret; | |
255 | } | |
256 | ||
ac0c6bdd PP |
257 | int bt_ctf_clock_class_set_offset_cycles(struct bt_ctf_clock_class *clock_class, |
258 | int64_t offset) | |
273b65be JG |
259 | { |
260 | int ret = 0; | |
261 | ||
ac0c6bdd | 262 | if (!clock_class || clock_class->frozen) { |
273b65be JG |
263 | ret = -1; |
264 | goto end; | |
265 | } | |
266 | ||
ac0c6bdd | 267 | clock_class->offset = offset; |
273b65be JG |
268 | end: |
269 | return ret; | |
270 | } | |
271 | ||
acd6aeb1 | 272 | int bt_ctf_clock_class_is_absolute(struct bt_ctf_clock_class *clock_class) |
87d76bb1 JG |
273 | { |
274 | int ret = -1; | |
275 | ||
ac0c6bdd | 276 | if (!clock_class) { |
87d76bb1 JG |
277 | goto end; |
278 | } | |
279 | ||
ac0c6bdd | 280 | ret = clock_class->absolute; |
87d76bb1 JG |
281 | end: |
282 | return ret; | |
283 | } | |
284 | ||
ac0c6bdd PP |
285 | int bt_ctf_clock_class_set_is_absolute(struct bt_ctf_clock_class *clock_class, |
286 | int is_absolute) | |
273b65be JG |
287 | { |
288 | int ret = 0; | |
289 | ||
ac0c6bdd | 290 | if (!clock_class || clock_class->frozen) { |
273b65be JG |
291 | ret = -1; |
292 | goto end; | |
293 | } | |
294 | ||
ac0c6bdd | 295 | clock_class->absolute = !!is_absolute; |
273b65be JG |
296 | end: |
297 | return ret; | |
298 | } | |
299 | ||
ac0c6bdd PP |
300 | const unsigned char *bt_ctf_clock_class_get_uuid( |
301 | struct bt_ctf_clock_class *clock_class) | |
85b743f4 JG |
302 | { |
303 | const unsigned char *ret; | |
304 | ||
ac0c6bdd | 305 | if (!clock_class || !clock_class->uuid_set) { |
85b743f4 JG |
306 | ret = NULL; |
307 | goto end; | |
308 | } | |
309 | ||
ac0c6bdd | 310 | ret = clock_class->uuid; |
85b743f4 JG |
311 | end: |
312 | return ret; | |
313 | } | |
314 | ||
ac0c6bdd PP |
315 | int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class *clock_class, |
316 | const unsigned char *uuid) | |
85b743f4 JG |
317 | { |
318 | int ret = 0; | |
319 | ||
ac0c6bdd | 320 | if (!clock_class || !uuid || clock_class->frozen) { |
85b743f4 JG |
321 | ret = -1; |
322 | goto end; | |
323 | } | |
324 | ||
ac0c6bdd PP |
325 | memcpy(clock_class->uuid, uuid, sizeof(uuid_t)); |
326 | clock_class->uuid_set = 1; | |
85b743f4 JG |
327 | end: |
328 | return ret; | |
329 | } | |
330 | ||
ac0c6bdd | 331 | static uint64_t ns_from_value(uint64_t frequency, uint64_t value) |
4ef18cab PP |
332 | { |
333 | uint64_t ns; | |
334 | ||
335 | if (frequency == 1000000000) { | |
336 | ns = value; | |
337 | } else { | |
338 | ns = (uint64_t) ((1e9 * (double) value) / (double) frequency); | |
339 | } | |
340 | ||
341 | return ns; | |
342 | } | |
343 | ||
273b65be | 344 | BT_HIDDEN |
ac0c6bdd | 345 | void bt_ctf_clock_class_freeze(struct bt_ctf_clock_class *clock_class) |
273b65be | 346 | { |
ac0c6bdd | 347 | if (!clock_class) { |
273b65be JG |
348 | return; |
349 | } | |
350 | ||
ac0c6bdd | 351 | clock_class->frozen = 1; |
273b65be JG |
352 | } |
353 | ||
354 | BT_HIDDEN | |
ac0c6bdd | 355 | void bt_ctf_clock_class_serialize(struct bt_ctf_clock_class *clock_class, |
273b65be JG |
356 | struct metadata_context *context) |
357 | { | |
358 | unsigned char *uuid; | |
359 | ||
ac0c6bdd | 360 | if (!clock_class || !context) { |
273b65be JG |
361 | return; |
362 | } | |
363 | ||
ac0c6bdd | 364 | uuid = clock_class->uuid; |
273b65be JG |
365 | g_string_append(context->string, "clock {\n"); |
366 | g_string_append_printf(context->string, "\tname = %s;\n", | |
ac0c6bdd | 367 | clock_class->name->str); |
273b65be JG |
368 | g_string_append_printf(context->string, |
369 | "\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n", | |
370 | uuid[0], uuid[1], uuid[2], uuid[3], | |
371 | uuid[4], uuid[5], uuid[6], uuid[7], | |
372 | uuid[8], uuid[9], uuid[10], uuid[11], | |
373 | uuid[12], uuid[13], uuid[14], uuid[15]); | |
ac0c6bdd | 374 | if (clock_class->description) { |
273b65be | 375 | g_string_append_printf(context->string, "\tdescription = \"%s\";\n", |
ac0c6bdd | 376 | clock_class->description->str); |
273b65be JG |
377 | } |
378 | ||
379 | g_string_append_printf(context->string, "\tfreq = %" PRIu64 ";\n", | |
ac0c6bdd | 380 | clock_class->frequency); |
273b65be | 381 | g_string_append_printf(context->string, "\tprecision = %" PRIu64 ";\n", |
ac0c6bdd | 382 | clock_class->precision); |
273b65be | 383 | g_string_append_printf(context->string, "\toffset_s = %" PRIu64 ";\n", |
ac0c6bdd | 384 | clock_class->offset_s); |
273b65be | 385 | g_string_append_printf(context->string, "\toffset = %" PRIu64 ";\n", |
ac0c6bdd | 386 | clock_class->offset); |
273b65be | 387 | g_string_append_printf(context->string, "\tabsolute = %s;\n", |
ac0c6bdd | 388 | clock_class->absolute ? "TRUE" : "FALSE"); |
273b65be JG |
389 | g_string_append(context->string, "};\n\n"); |
390 | } | |
391 | ||
273b65be | 392 | static |
ac0c6bdd | 393 | void bt_ctf_clock_class_destroy(struct bt_object *obj) |
273b65be | 394 | { |
ac0c6bdd | 395 | struct bt_ctf_clock_class *clock_class; |
273b65be | 396 | |
ac0c6bdd PP |
397 | clock_class = container_of(obj, struct bt_ctf_clock_class, base); |
398 | if (clock_class->name) { | |
399 | g_string_free(clock_class->name, TRUE); | |
273b65be | 400 | } |
ac0c6bdd PP |
401 | if (clock_class->description) { |
402 | g_string_free(clock_class->description, TRUE); | |
273b65be JG |
403 | } |
404 | ||
ac0c6bdd | 405 | g_free(clock_class); |
273b65be | 406 | } |
4ef18cab | 407 | |
61ec14e6 JG |
408 | static |
409 | void bt_ctf_clock_value_destroy(struct bt_object *obj) | |
410 | { | |
411 | struct bt_ctf_clock_value *value; | |
412 | ||
413 | if (!obj) { | |
414 | return; | |
415 | } | |
416 | ||
417 | value = container_of(obj, struct bt_ctf_clock_value, base); | |
418 | bt_put(value->clock_class); | |
419 | g_free(value); | |
420 | } | |
421 | ||
422 | struct bt_ctf_clock_value *bt_ctf_clock_value_create( | |
ac0c6bdd | 423 | struct bt_ctf_clock_class *clock_class, uint64_t value) |
4ef18cab | 424 | { |
61ec14e6 | 425 | struct bt_ctf_clock_value *ret = NULL; |
4ef18cab | 426 | |
ac0c6bdd | 427 | if (!clock_class) { |
4ef18cab PP |
428 | goto end; |
429 | } | |
430 | ||
61ec14e6 JG |
431 | ret = g_new0(struct bt_ctf_clock_value, 1); |
432 | if (!ret) { | |
433 | goto end; | |
434 | } | |
435 | ||
436 | bt_object_init(ret, bt_ctf_clock_value_destroy); | |
ac0c6bdd | 437 | ret->clock_class = bt_get(clock_class); |
61ec14e6 JG |
438 | ret->value = value; |
439 | end: | |
440 | return ret; | |
441 | } | |
4ef18cab | 442 | |
61ec14e6 JG |
443 | int bt_ctf_clock_value_get_value( |
444 | struct bt_ctf_clock_value *clock_value, uint64_t *raw_value) | |
445 | { | |
446 | int ret = 0; | |
4ef18cab | 447 | |
61ec14e6 JG |
448 | if (!clock_value || !raw_value) { |
449 | ret = -1; | |
450 | goto end; | |
451 | } | |
4ef18cab | 452 | |
61ec14e6 | 453 | *raw_value = clock_value->value; |
4ef18cab | 454 | end: |
61ec14e6 JG |
455 | return ret; |
456 | } | |
457 | ||
1556a1af | 458 | int bt_ctf_clock_value_get_value_ns_from_epoch(struct bt_ctf_clock_value *value, |
61ec14e6 JG |
459 | int64_t *ret_value_ns) |
460 | { | |
461 | int ret = 0; | |
462 | int64_t ns; | |
463 | ||
464 | if (!value || !ret_value_ns) { | |
465 | ret = -1; | |
466 | goto end; | |
467 | } | |
468 | ||
469 | /* Initialize nanosecond timestamp to clock's offset in seconds. */ | |
9ac68eb1 | 470 | ns = value->clock_class->offset_s * (int64_t) 1000000000; |
61ec14e6 JG |
471 | |
472 | /* Add offset in cycles, converted to nanoseconds. */ | |
473 | ns += ns_from_value(value->clock_class->frequency, | |
474 | value->clock_class->offset); | |
475 | ||
476 | /* Add given value, converter to nanoseconds. */ | |
477 | ns += ns_from_value(value->clock_class->frequency, value->value); | |
478 | ||
479 | *ret_value_ns = ns; | |
480 | end: | |
481 | return ret; | |
4ef18cab | 482 | } |
6f57e458 PP |
483 | |
484 | struct bt_ctf_clock_class *bt_ctf_clock_value_get_class( | |
485 | struct bt_ctf_clock_value *clock_value) | |
486 | { | |
487 | struct bt_ctf_clock_class *clock_class = NULL; | |
488 | ||
489 | if (!clock_value) { | |
490 | goto end; | |
491 | } | |
492 | ||
493 | clock_class = bt_get(clock_value->clock_class); | |
494 | ||
495 | end: | |
496 | return clock_class; | |
497 | } |