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 | ||
0f5e83e5 | 29 | #define BT_LOG_TAG "CLOCK-CLASS" |
40547d22 | 30 | #include <babeltrace/lib-logging-internal.h> |
0f5e83e5 | 31 | |
a6918753 | 32 | #include <babeltrace/assert-pre-internal.h> |
75c3fca1 | 33 | #include <babeltrace/compat/uuid-internal.h> |
ac0c6bdd | 34 | #include <babeltrace/ctf-ir/clock-class-internal.h> |
a62f9ba0 | 35 | #include <babeltrace/ctf-ir/clock-value-internal.h> |
654c1444 | 36 | #include <babeltrace/ctf-ir/utils.h> |
83509119 | 37 | #include <babeltrace/ref.h> |
3d9990ac | 38 | #include <babeltrace/compiler-internal.h> |
c55a9f58 | 39 | #include <babeltrace/types.h> |
ee389f01 | 40 | #include <babeltrace/compat/string-internal.h> |
273b65be | 41 | #include <inttypes.h> |
0f5e83e5 | 42 | #include <babeltrace/object-internal.h> |
8b45963b | 43 | #include <babeltrace/assert-internal.h> |
5134570b | 44 | |
273b65be | 45 | static |
839d52a5 | 46 | void bt_clock_class_destroy(struct bt_object *obj); |
273b65be | 47 | |
a6918753 PP |
48 | static |
49 | struct bt_clock_value *bt_clock_value_new(struct bt_clock_class *clock_class); | |
50 | ||
51 | static | |
52 | void bt_clock_value_destroy(struct bt_clock_value *clock_value); | |
53 | ||
4c426c17 | 54 | BT_HIDDEN |
839d52a5 | 55 | bt_bool bt_clock_class_is_valid(struct bt_clock_class *clock_class) |
c06116f3 | 56 | { |
ac0c6bdd | 57 | return clock_class && clock_class->name; |
c06116f3 PP |
58 | } |
59 | ||
839d52a5 | 60 | int bt_clock_class_set_name(struct bt_clock_class *clock_class, |
4c426c17 JG |
61 | const char *name) |
62 | { | |
63 | int ret = 0; | |
273b65be | 64 | |
5134570b PP |
65 | if (!clock_class) { |
66 | BT_LOGW_STR("Invalid parameter: clock class is NULL."); | |
67 | ret = -1; | |
68 | goto end; | |
69 | } | |
70 | ||
71 | if (clock_class->frozen) { | |
2cf0acd7 | 72 | BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"", |
839d52a5 | 73 | clock_class, bt_clock_class_get_name(clock_class)); |
c06116f3 PP |
74 | ret = -1; |
75 | goto end; | |
76 | } | |
77 | ||
792defbe | 78 | if (!bt_identifier_is_valid(name)) { |
8deee039 | 79 | BT_LOGW("Clock class's name is not a valid CTF identifier: " |
2cf0acd7 | 80 | "addr=%p, name=\"%s\"", |
5134570b | 81 | clock_class, name); |
4c426c17 JG |
82 | ret = -1; |
83 | goto end; | |
273b65be JG |
84 | } |
85 | ||
ac0c6bdd PP |
86 | if (clock_class->name) { |
87 | g_string_assign(clock_class->name, name); | |
e1ae7645 | 88 | } else { |
ac0c6bdd PP |
89 | clock_class->name = g_string_new(name); |
90 | if (!clock_class->name) { | |
5134570b | 91 | BT_LOGE_STR("Failed to allocate a GString."); |
e1ae7645 JG |
92 | ret = -1; |
93 | goto end; | |
94 | } | |
273b65be JG |
95 | } |
96 | ||
2cf0acd7 | 97 | BT_LOGV("Set clock class's name: addr=%p, name=\"%s\"", |
5134570b PP |
98 | clock_class, name); |
99 | ||
4c426c17 JG |
100 | end: |
101 | return ret; | |
102 | } | |
103 | ||
15260cc8 | 104 | static |
839d52a5 | 105 | bool validate_freq(struct bt_clock_class *clock_class, |
15260cc8 PP |
106 | const char *name, uint64_t freq) |
107 | { | |
108 | bool is_valid = true; | |
109 | ||
110 | if (freq == -1ULL || freq == 0) { | |
111 | BT_LOGW("Invalid parameter: frequency is invalid: " | |
112 | "addr=%p, name=\"%s\", freq=%" PRIu64, | |
113 | clock_class, name, freq); | |
114 | is_valid = false; | |
115 | goto end; | |
116 | } | |
117 | ||
118 | end: | |
119 | return is_valid; | |
120 | } | |
121 | ||
a6918753 PP |
122 | static |
123 | void bt_clock_class_free_clock_value(struct bt_clock_value *clock_value, | |
124 | struct bt_clock_class *clock_class) | |
125 | { | |
126 | bt_clock_value_destroy(clock_value); | |
127 | } | |
128 | ||
839d52a5 | 129 | struct bt_clock_class *bt_clock_class_create(const char *name, |
15260cc8 | 130 | uint64_t freq) |
4c426c17 JG |
131 | { |
132 | int ret; | |
839d52a5 | 133 | struct bt_clock_class *clock_class = NULL; |
4c426c17 | 134 | |
5134570b PP |
135 | BT_LOGD("Creating default clock class object: name=\"%s\"", |
136 | name); | |
15260cc8 PP |
137 | |
138 | if (!validate_freq(NULL, name, freq)) { | |
139 | /* validate_freq() logs errors */ | |
140 | goto error; | |
141 | } | |
142 | ||
839d52a5 | 143 | clock_class = g_new0(struct bt_clock_class, 1); |
ac0c6bdd | 144 | if (!clock_class) { |
5134570b | 145 | BT_LOGE_STR("Failed to allocate one clock class."); |
4c426c17 JG |
146 | goto error; |
147 | } | |
148 | ||
ac0c6bdd | 149 | clock_class->precision = 1; |
15260cc8 | 150 | clock_class->frequency = freq; |
839d52a5 | 151 | bt_object_init(clock_class, bt_clock_class_destroy); |
85380e99 JG |
152 | |
153 | if (name) { | |
839d52a5 | 154 | ret = bt_clock_class_set_name(clock_class, name); |
85380e99 | 155 | if (ret) { |
8deee039 | 156 | /* bt_clock_class_set_name() logs errors */ |
85380e99 JG |
157 | goto error; |
158 | } | |
273b65be JG |
159 | } |
160 | ||
a6918753 PP |
161 | ret = bt_object_pool_initialize(&clock_class->cv_pool, |
162 | (bt_object_pool_new_object_func) bt_clock_value_new, | |
163 | (bt_object_pool_destroy_object_func) | |
164 | bt_clock_class_free_clock_value, | |
165 | clock_class); | |
166 | if (ret) { | |
167 | BT_LOGE("Failed to initialize clock value pool: ret=%d", | |
168 | ret); | |
169 | goto error; | |
170 | } | |
171 | ||
2cf0acd7 PP |
172 | BT_LOGD("Created clock class object: addr=%p, name=\"%s\"", |
173 | clock_class, name); | |
ac0c6bdd | 174 | return clock_class; |
273b65be | 175 | error: |
ac0c6bdd PP |
176 | BT_PUT(clock_class); |
177 | return clock_class; | |
87d76bb1 JG |
178 | } |
179 | ||
839d52a5 | 180 | const char *bt_clock_class_get_name(struct bt_clock_class *clock_class) |
87d76bb1 JG |
181 | { |
182 | const char *ret = NULL; | |
183 | ||
ac0c6bdd | 184 | if (!clock_class) { |
5134570b | 185 | BT_LOGW_STR("Invalid parameter: clock class is NULL."); |
87d76bb1 JG |
186 | goto end; |
187 | } | |
188 | ||
ac0c6bdd PP |
189 | if (clock_class->name) { |
190 | ret = clock_class->name->str; | |
87d76bb1 JG |
191 | } |
192 | ||
193 | end: | |
194 | return ret; | |
195 | } | |
196 | ||
839d52a5 PP |
197 | const char *bt_clock_class_get_description( |
198 | struct bt_clock_class *clock_class) | |
87d76bb1 JG |
199 | { |
200 | const char *ret = NULL; | |
201 | ||
ac0c6bdd | 202 | if (!clock_class) { |
5134570b | 203 | BT_LOGW_STR("Invalid parameter: clock class is NULL."); |
87d76bb1 JG |
204 | goto end; |
205 | } | |
206 | ||
ac0c6bdd PP |
207 | if (clock_class->description) { |
208 | ret = clock_class->description->str; | |
87d76bb1 JG |
209 | } |
210 | end: | |
211 | return ret; | |
273b65be JG |
212 | } |
213 | ||
839d52a5 | 214 | int bt_clock_class_set_description(struct bt_clock_class *clock_class, |
ac0c6bdd | 215 | const char *desc) |
273b65be JG |
216 | { |
217 | int ret = 0; | |
218 | ||
5134570b PP |
219 | if (!clock_class || !desc) { |
220 | BT_LOGW("Invalid parameter: clock class or description is NULL: " | |
2cf0acd7 | 221 | "clock-class-addr=%p, name=\"%s\", desc-addr=%p", |
839d52a5 | 222 | clock_class, bt_clock_class_get_name(clock_class), |
2cf0acd7 | 223 | desc); |
5134570b PP |
224 | ret = -1; |
225 | goto end; | |
226 | } | |
227 | ||
228 | if (clock_class->frozen) { | |
2cf0acd7 | 229 | BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"", |
839d52a5 | 230 | clock_class, bt_clock_class_get_name(clock_class)); |
273b65be JG |
231 | ret = -1; |
232 | goto end; | |
233 | } | |
234 | ||
ac0c6bdd PP |
235 | clock_class->description = g_string_new(desc); |
236 | ret = clock_class->description ? 0 : -1; | |
2cf0acd7 PP |
237 | BT_LOGV("Set clock class's description: addr=%p, " |
238 | "name=\"%s\", desc=\"%s\"", | |
839d52a5 | 239 | clock_class, bt_clock_class_get_name(clock_class), desc); |
273b65be JG |
240 | end: |
241 | return ret; | |
242 | } | |
243 | ||
839d52a5 PP |
244 | uint64_t bt_clock_class_get_frequency( |
245 | struct bt_clock_class *clock_class) | |
87d76bb1 JG |
246 | { |
247 | uint64_t ret = -1ULL; | |
248 | ||
ac0c6bdd | 249 | if (!clock_class) { |
5134570b | 250 | BT_LOGW_STR("Invalid parameter: clock class is NULL."); |
87d76bb1 JG |
251 | goto end; |
252 | } | |
253 | ||
ac0c6bdd | 254 | ret = clock_class->frequency; |
87d76bb1 JG |
255 | end: |
256 | return ret; | |
257 | } | |
258 | ||
839d52a5 | 259 | int bt_clock_class_set_frequency(struct bt_clock_class *clock_class, |
ac0c6bdd | 260 | uint64_t freq) |
273b65be JG |
261 | { |
262 | int ret = 0; | |
263 | ||
15260cc8 | 264 | if (!clock_class) { |
5134570b | 265 | BT_LOGW("Invalid parameter: clock class is NULL or frequency is invalid: " |
15260cc8 | 266 | "addr=%p, name=\"%s\"", |
839d52a5 | 267 | clock_class, bt_clock_class_get_name(clock_class)); |
5134570b PP |
268 | ret = -1; |
269 | goto end; | |
270 | } | |
271 | ||
839d52a5 | 272 | if (!validate_freq(clock_class, bt_clock_class_get_name(clock_class), |
15260cc8 PP |
273 | freq)) { |
274 | /* validate_freq() logs errors */ | |
275 | goto end; | |
276 | } | |
277 | ||
5134570b | 278 | if (clock_class->frozen) { |
2cf0acd7 | 279 | BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"", |
839d52a5 | 280 | clock_class, bt_clock_class_get_name(clock_class)); |
273b65be JG |
281 | ret = -1; |
282 | goto end; | |
283 | } | |
284 | ||
ac0c6bdd | 285 | clock_class->frequency = freq; |
2cf0acd7 | 286 | BT_LOGV("Set clock class's frequency: addr=%p, name=\"%s\", freq=%" PRIu64, |
839d52a5 | 287 | clock_class, bt_clock_class_get_name(clock_class), freq); |
273b65be JG |
288 | end: |
289 | return ret; | |
290 | } | |
291 | ||
839d52a5 | 292 | uint64_t bt_clock_class_get_precision(struct bt_clock_class *clock_class) |
87d76bb1 JG |
293 | { |
294 | uint64_t ret = -1ULL; | |
295 | ||
ac0c6bdd | 296 | if (!clock_class) { |
5134570b | 297 | BT_LOGW_STR("Invalid parameter: clock class is NULL."); |
87d76bb1 JG |
298 | goto end; |
299 | } | |
300 | ||
ac0c6bdd | 301 | ret = clock_class->precision; |
87d76bb1 JG |
302 | end: |
303 | return ret; | |
304 | } | |
305 | ||
839d52a5 | 306 | int bt_clock_class_set_precision(struct bt_clock_class *clock_class, |
ac0c6bdd | 307 | uint64_t precision) |
273b65be JG |
308 | { |
309 | int ret = 0; | |
310 | ||
5134570b PP |
311 | if (!clock_class || precision == -1ULL) { |
312 | BT_LOGW("Invalid parameter: clock class is NULL or precision is invalid: " | |
2cf0acd7 | 313 | "addr=%p, name=\"%s\", precision=%" PRIu64, |
839d52a5 | 314 | clock_class, bt_clock_class_get_name(clock_class), |
2cf0acd7 | 315 | precision); |
5134570b PP |
316 | ret = -1; |
317 | goto end; | |
318 | } | |
319 | ||
320 | if (clock_class->frozen) { | |
2cf0acd7 | 321 | BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"", |
839d52a5 | 322 | clock_class, bt_clock_class_get_name(clock_class)); |
273b65be JG |
323 | ret = -1; |
324 | goto end; | |
325 | } | |
326 | ||
ac0c6bdd | 327 | clock_class->precision = precision; |
2cf0acd7 | 328 | BT_LOGV("Set clock class's precision: addr=%p, name=\"%s\", precision=%" PRIu64, |
839d52a5 | 329 | clock_class, bt_clock_class_get_name(clock_class), |
2cf0acd7 | 330 | precision); |
273b65be JG |
331 | end: |
332 | return ret; | |
333 | } | |
334 | ||
839d52a5 | 335 | int bt_clock_class_get_offset_s(struct bt_clock_class *clock_class, |
ac0c6bdd | 336 | int64_t *offset_s) |
87d76bb1 | 337 | { |
61cf588b | 338 | int ret = 0; |
87d76bb1 | 339 | |
ac0c6bdd | 340 | if (!clock_class || !offset_s) { |
5134570b | 341 | BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: " |
2cf0acd7 | 342 | "clock-class-addr=%p, name=\"%s\", offset-addr=%p", |
839d52a5 | 343 | clock_class, bt_clock_class_get_name(clock_class), |
2cf0acd7 | 344 | offset_s); |
61cf588b | 345 | ret = -1; |
87d76bb1 JG |
346 | goto end; |
347 | } | |
348 | ||
ac0c6bdd | 349 | *offset_s = clock_class->offset_s; |
87d76bb1 JG |
350 | end: |
351 | return ret; | |
352 | } | |
353 | ||
839d52a5 | 354 | int bt_clock_class_set_offset_s(struct bt_clock_class *clock_class, |
ac0c6bdd | 355 | int64_t offset_s) |
273b65be JG |
356 | { |
357 | int ret = 0; | |
358 | ||
5134570b PP |
359 | if (!clock_class) { |
360 | BT_LOGW_STR("Invalid parameter: clock class is NULL."); | |
361 | ret = -1; | |
362 | goto end; | |
363 | } | |
364 | ||
365 | if (clock_class->frozen) { | |
2cf0acd7 | 366 | BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"", |
839d52a5 | 367 | clock_class, bt_clock_class_get_name(clock_class)); |
273b65be JG |
368 | ret = -1; |
369 | goto end; | |
370 | } | |
371 | ||
ac0c6bdd | 372 | clock_class->offset_s = offset_s; |
2cf0acd7 PP |
373 | BT_LOGV("Set clock class's offset (seconds): " |
374 | "addr=%p, name=\"%s\", offset-s=%" PRId64, | |
839d52a5 | 375 | clock_class, bt_clock_class_get_name(clock_class), |
2cf0acd7 | 376 | offset_s); |
273b65be JG |
377 | end: |
378 | return ret; | |
379 | } | |
380 | ||
839d52a5 | 381 | int bt_clock_class_get_offset_cycles(struct bt_clock_class *clock_class, |
ac0c6bdd | 382 | int64_t *offset) |
87d76bb1 | 383 | { |
61cf588b | 384 | int ret = 0; |
87d76bb1 | 385 | |
ac0c6bdd | 386 | if (!clock_class || !offset) { |
5134570b | 387 | BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: " |
2cf0acd7 | 388 | "clock-class-addr=%p, name=\"%s\", offset-addr=%p", |
839d52a5 | 389 | clock_class, bt_clock_class_get_name(clock_class), |
2cf0acd7 | 390 | offset); |
61cf588b | 391 | ret = -1; |
87d76bb1 JG |
392 | goto end; |
393 | } | |
394 | ||
ac0c6bdd | 395 | *offset = clock_class->offset; |
87d76bb1 JG |
396 | end: |
397 | return ret; | |
398 | } | |
399 | ||
839d52a5 | 400 | int bt_clock_class_set_offset_cycles(struct bt_clock_class *clock_class, |
ac0c6bdd | 401 | int64_t offset) |
273b65be JG |
402 | { |
403 | int ret = 0; | |
404 | ||
5134570b PP |
405 | if (!clock_class) { |
406 | BT_LOGW_STR("Invalid parameter: clock class is NULL."); | |
407 | ret = -1; | |
408 | goto end; | |
409 | } | |
410 | ||
411 | if (clock_class->frozen) { | |
2cf0acd7 | 412 | BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"", |
839d52a5 | 413 | clock_class, bt_clock_class_get_name(clock_class)); |
273b65be JG |
414 | ret = -1; |
415 | goto end; | |
416 | } | |
417 | ||
ac0c6bdd | 418 | clock_class->offset = offset; |
2cf0acd7 | 419 | BT_LOGV("Set clock class's offset (cycles): addr=%p, name=\"%s\", offset-cycles=%" PRId64, |
839d52a5 | 420 | clock_class, bt_clock_class_get_name(clock_class), offset); |
273b65be JG |
421 | end: |
422 | return ret; | |
423 | } | |
424 | ||
839d52a5 | 425 | bt_bool bt_clock_class_is_absolute(struct bt_clock_class *clock_class) |
87d76bb1 JG |
426 | { |
427 | int ret = -1; | |
428 | ||
ac0c6bdd | 429 | if (!clock_class) { |
5134570b | 430 | BT_LOGW_STR("Invalid parameter: clock class is NULL."); |
87d76bb1 JG |
431 | goto end; |
432 | } | |
433 | ||
ac0c6bdd | 434 | ret = clock_class->absolute; |
87d76bb1 JG |
435 | end: |
436 | return ret; | |
437 | } | |
438 | ||
839d52a5 | 439 | int bt_clock_class_set_is_absolute(struct bt_clock_class *clock_class, |
a2b94977 | 440 | bt_bool is_absolute) |
273b65be JG |
441 | { |
442 | int ret = 0; | |
443 | ||
5134570b PP |
444 | if (!clock_class) { |
445 | BT_LOGW_STR("Invalid parameter: clock class is NULL."); | |
446 | ret = -1; | |
447 | goto end; | |
448 | } | |
449 | ||
450 | if (clock_class->frozen) { | |
2cf0acd7 | 451 | BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"", |
839d52a5 | 452 | clock_class, bt_clock_class_get_name(clock_class)); |
273b65be JG |
453 | ret = -1; |
454 | goto end; | |
455 | } | |
456 | ||
ac0c6bdd | 457 | clock_class->absolute = !!is_absolute; |
2cf0acd7 | 458 | BT_LOGV("Set clock class's absolute flag: addr=%p, name=\"%s\", is-absolute=%d", |
839d52a5 | 459 | clock_class, bt_clock_class_get_name(clock_class), |
2cf0acd7 | 460 | is_absolute); |
273b65be JG |
461 | end: |
462 | return ret; | |
463 | } | |
464 | ||
839d52a5 PP |
465 | const unsigned char *bt_clock_class_get_uuid( |
466 | struct bt_clock_class *clock_class) | |
85b743f4 JG |
467 | { |
468 | const unsigned char *ret; | |
469 | ||
5134570b PP |
470 | if (!clock_class) { |
471 | BT_LOGW_STR("Invalid parameter: clock class is NULL."); | |
472 | ret = NULL; | |
473 | goto end; | |
474 | } | |
475 | ||
476 | if (!clock_class->uuid_set) { | |
2cf0acd7 | 477 | BT_LOGV("Clock class's UUID is not set: addr=%p, name=\"%s\"", |
839d52a5 | 478 | clock_class, bt_clock_class_get_name(clock_class)); |
85b743f4 JG |
479 | ret = NULL; |
480 | goto end; | |
481 | } | |
482 | ||
ac0c6bdd | 483 | ret = clock_class->uuid; |
85b743f4 JG |
484 | end: |
485 | return ret; | |
486 | } | |
487 | ||
839d52a5 | 488 | int bt_clock_class_set_uuid(struct bt_clock_class *clock_class, |
ac0c6bdd | 489 | const unsigned char *uuid) |
85b743f4 JG |
490 | { |
491 | int ret = 0; | |
492 | ||
5134570b PP |
493 | if (!clock_class || !uuid) { |
494 | BT_LOGW("Invalid parameter: clock class or UUID is NULL: " | |
2cf0acd7 | 495 | "clock-class-addr=%p, name=\"%s\", uuid-addr=%p", |
839d52a5 | 496 | clock_class, bt_clock_class_get_name(clock_class), |
2cf0acd7 | 497 | uuid); |
5134570b PP |
498 | ret = -1; |
499 | goto end; | |
500 | } | |
501 | ||
502 | if (clock_class->frozen) { | |
2cf0acd7 | 503 | BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"", |
839d52a5 | 504 | clock_class, bt_clock_class_get_name(clock_class)); |
85b743f4 JG |
505 | ret = -1; |
506 | goto end; | |
507 | } | |
508 | ||
20eee76e | 509 | memcpy(clock_class->uuid, uuid, BABELTRACE_UUID_LEN); |
ac0c6bdd | 510 | clock_class->uuid_set = 1; |
2cf0acd7 | 511 | BT_LOGV("Set clock class's UUID: addr=%p, name=\"%s\", " |
5134570b | 512 | "uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"", |
839d52a5 | 513 | clock_class, bt_clock_class_get_name(clock_class), |
5134570b PP |
514 | (unsigned int) uuid[0], |
515 | (unsigned int) uuid[1], | |
516 | (unsigned int) uuid[2], | |
517 | (unsigned int) uuid[3], | |
518 | (unsigned int) uuid[4], | |
519 | (unsigned int) uuid[5], | |
520 | (unsigned int) uuid[6], | |
521 | (unsigned int) uuid[7], | |
522 | (unsigned int) uuid[8], | |
523 | (unsigned int) uuid[9], | |
524 | (unsigned int) uuid[10], | |
525 | (unsigned int) uuid[11], | |
526 | (unsigned int) uuid[12], | |
527 | (unsigned int) uuid[13], | |
528 | (unsigned int) uuid[14], | |
529 | (unsigned int) uuid[15]); | |
85b743f4 JG |
530 | end: |
531 | return ret; | |
532 | } | |
533 | ||
a6918753 PP |
534 | static inline |
535 | uint64_t ns_from_value(uint64_t frequency, uint64_t value) | |
4ef18cab PP |
536 | { |
537 | uint64_t ns; | |
538 | ||
a6918753 | 539 | if (frequency == UINT64_C(1000000000)) { |
4ef18cab PP |
540 | ns = value; |
541 | } else { | |
24e770c1 PP |
542 | double dblres = ((1e9 * (double) value) / (double) frequency); |
543 | ||
544 | if (dblres >= (double) UINT64_MAX) { | |
545 | /* Overflows uint64_t */ | |
546 | ns = -1ULL; | |
547 | } else { | |
548 | ns = (uint64_t) dblres; | |
549 | } | |
4ef18cab PP |
550 | } |
551 | ||
552 | return ns; | |
553 | } | |
554 | ||
273b65be | 555 | BT_HIDDEN |
839d52a5 | 556 | void bt_clock_class_freeze(struct bt_clock_class *clock_class) |
273b65be | 557 | { |
8deee039 | 558 | if (!clock_class || clock_class->frozen) { |
273b65be JG |
559 | return; |
560 | } | |
561 | ||
8deee039 PP |
562 | BT_LOGD("Freezing clock class: addr=%p, name=\"%s\"", |
563 | clock_class, bt_clock_class_get_name(clock_class)); | |
564 | clock_class->frozen = 1; | |
273b65be JG |
565 | } |
566 | ||
273b65be | 567 | static |
839d52a5 | 568 | void bt_clock_class_destroy(struct bt_object *obj) |
273b65be | 569 | { |
839d52a5 | 570 | struct bt_clock_class *clock_class; |
273b65be | 571 | |
839d52a5 | 572 | clock_class = container_of(obj, struct bt_clock_class, base); |
2cf0acd7 | 573 | BT_LOGD("Destroying clock class: addr=%p, name=\"%s\"", |
839d52a5 | 574 | obj, bt_clock_class_get_name(clock_class)); |
a6918753 | 575 | |
ac0c6bdd PP |
576 | if (clock_class->name) { |
577 | g_string_free(clock_class->name, TRUE); | |
273b65be | 578 | } |
a6918753 | 579 | |
ac0c6bdd PP |
580 | if (clock_class->description) { |
581 | g_string_free(clock_class->description, TRUE); | |
273b65be JG |
582 | } |
583 | ||
a6918753 | 584 | bt_object_pool_finalize(&clock_class->cv_pool); |
ac0c6bdd | 585 | g_free(clock_class); |
273b65be | 586 | } |
4ef18cab | 587 | |
61ec14e6 | 588 | static |
a6918753 | 589 | void bt_clock_value_destroy(struct bt_clock_value *clock_value) |
61ec14e6 | 590 | { |
2cf0acd7 | 591 | BT_LOGD("Destroying clock value: addr=%p, clock-class-addr=%p, " |
a6918753 PP |
592 | "clock-class-name=\"%s\"", clock_value, |
593 | clock_value->clock_class, | |
594 | bt_clock_class_get_name(clock_value->clock_class)); | |
595 | bt_put(clock_value->clock_class); | |
596 | g_free(clock_value); | |
61ec14e6 JG |
597 | } |
598 | ||
a6918753 PP |
599 | static inline |
600 | int ns_from_epoch(struct bt_clock_class *clock_class, uint64_t value, | |
601 | int64_t *ns_from_epoch, bool *overflows) | |
24e770c1 | 602 | { |
a6918753 | 603 | int ret = 0; |
24e770c1 PP |
604 | int64_t diff; |
605 | int64_t s_ns; | |
606 | uint64_t u_ns; | |
607 | uint64_t cycles; | |
608 | ||
a6918753 PP |
609 | *overflows = false; |
610 | ||
24e770c1 | 611 | /* Initialize nanosecond timestamp to clock's offset in seconds */ |
a6918753 PP |
612 | if (clock_class->offset_s <= (INT64_MIN / INT64_C(1000000000)) || |
613 | clock_class->offset_s >= (INT64_MAX / INT64_C(1000000000))) { | |
24e770c1 PP |
614 | /* |
615 | * Overflow: offset in seconds converted to nanoseconds | |
616 | * is outside the int64_t range. | |
617 | */ | |
a6918753 | 618 | *overflows = true; |
24e770c1 PP |
619 | goto end; |
620 | } | |
621 | ||
a6918753 | 622 | *ns_from_epoch = clock_class->offset_s * INT64_C(1000000000); |
24e770c1 PP |
623 | |
624 | /* Add offset in cycles */ | |
625 | if (clock_class->offset < 0) { | |
a6918753 | 626 | cycles = (uint64_t) -clock_class->offset; |
24e770c1 PP |
627 | } else { |
628 | cycles = (uint64_t) clock_class->offset; | |
629 | } | |
630 | ||
631 | u_ns = ns_from_value(clock_class->frequency, cycles); | |
632 | ||
a6918753 | 633 | if (u_ns == UINT64_C(-1) || u_ns >= INT64_MAX) { |
24e770c1 PP |
634 | /* |
635 | * Overflow: offset in cycles converted to nanoseconds | |
636 | * is outside the int64_t range. | |
637 | */ | |
a6918753 | 638 | *overflows = true; |
24e770c1 PP |
639 | goto end; |
640 | } | |
641 | ||
642 | s_ns = (int64_t) u_ns; | |
8b45963b | 643 | BT_ASSERT(s_ns >= 0); |
24e770c1 PP |
644 | |
645 | if (clock_class->offset < 0) { | |
a6918753 | 646 | if (*ns_from_epoch >= 0) { |
24e770c1 PP |
647 | /* |
648 | * Offset in cycles is negative so it must also | |
649 | * be negative once converted to nanoseconds. | |
650 | */ | |
651 | s_ns = -s_ns; | |
652 | goto offset_ok; | |
653 | } | |
654 | ||
a6918753 | 655 | diff = *ns_from_epoch - INT64_MIN; |
24e770c1 PP |
656 | |
657 | if (s_ns >= diff) { | |
658 | /* | |
659 | * Overflow: current timestamp in nanoseconds | |
660 | * plus the offset in cycles converted to | |
661 | * nanoseconds is outside the int64_t range. | |
662 | */ | |
a6918753 | 663 | *overflows = true; |
24e770c1 PP |
664 | goto end; |
665 | } | |
666 | ||
667 | /* | |
668 | * Offset in cycles is negative so it must also be | |
669 | * negative once converted to nanoseconds. | |
670 | */ | |
671 | s_ns = -s_ns; | |
672 | } else { | |
a6918753 | 673 | if (*ns_from_epoch <= 0) { |
24e770c1 PP |
674 | goto offset_ok; |
675 | } | |
676 | ||
a6918753 | 677 | diff = INT64_MAX - *ns_from_epoch; |
24e770c1 PP |
678 | |
679 | if (s_ns >= diff) { | |
680 | /* | |
681 | * Overflow: current timestamp in nanoseconds | |
682 | * plus the offset in cycles converted to | |
683 | * nanoseconds is outside the int64_t range. | |
684 | */ | |
a6918753 | 685 | *overflows = true; |
24e770c1 PP |
686 | goto end; |
687 | } | |
688 | } | |
689 | ||
690 | offset_ok: | |
a6918753 | 691 | *ns_from_epoch += s_ns; |
24e770c1 PP |
692 | |
693 | /* Add clock value (cycles) */ | |
a6918753 | 694 | u_ns = ns_from_value(clock_class->frequency, value); |
24e770c1 PP |
695 | |
696 | if (u_ns == -1ULL || u_ns >= INT64_MAX) { | |
697 | /* | |
698 | * Overflow: value converted to nanoseconds is outside | |
699 | * the int64_t range. | |
700 | */ | |
a6918753 | 701 | *overflows = true; |
24e770c1 PP |
702 | goto end; |
703 | } | |
704 | ||
705 | s_ns = (int64_t) u_ns; | |
8b45963b | 706 | BT_ASSERT(s_ns >= 0); |
24e770c1 PP |
707 | |
708 | /* Clock value (cycles) is always positive */ | |
a6918753 | 709 | if (*ns_from_epoch <= 0) { |
24e770c1 PP |
710 | goto value_ok; |
711 | } | |
712 | ||
a6918753 | 713 | diff = INT64_MAX - *ns_from_epoch; |
24e770c1 PP |
714 | |
715 | if (s_ns >= diff) { | |
716 | /* | |
717 | * Overflow: current timestamp in nanoseconds plus the | |
718 | * clock value converted to nanoseconds is outside the | |
719 | * int64_t range. | |
720 | */ | |
a6918753 | 721 | *overflows = true; |
24e770c1 PP |
722 | goto end; |
723 | } | |
724 | ||
725 | value_ok: | |
a6918753 | 726 | *ns_from_epoch += s_ns; |
24e770c1 PP |
727 | |
728 | end: | |
a6918753 PP |
729 | if (*overflows) { |
730 | *ns_from_epoch = 0; | |
731 | ret = -1; | |
24e770c1 | 732 | } |
a6918753 PP |
733 | |
734 | return ret; | |
24e770c1 PP |
735 | } |
736 | ||
a6918753 PP |
737 | static |
738 | void set_ns_from_epoch(struct bt_clock_value *clock_value) | |
739 | { | |
740 | (void) ns_from_epoch(clock_value->clock_class, | |
741 | clock_value->value, &clock_value->ns_from_epoch, | |
742 | &clock_value->ns_from_epoch_overflows); | |
743 | } | |
744 | ||
745 | static | |
746 | struct bt_clock_value *bt_clock_value_new(struct bt_clock_class *clock_class) | |
4ef18cab | 747 | { |
839d52a5 | 748 | struct bt_clock_value *ret = NULL; |
4ef18cab | 749 | |
5134570b | 750 | BT_LOGD("Creating clock value object: clock-class-addr=%p, " |
a6918753 PP |
751 | "clock-class-name=\"%s\"", clock_class, |
752 | bt_clock_class_get_name(clock_class)); | |
5134570b | 753 | |
ac0c6bdd | 754 | if (!clock_class) { |
5134570b | 755 | BT_LOGW_STR("Invalid parameter: clock class is NULL."); |
4ef18cab PP |
756 | goto end; |
757 | } | |
758 | ||
839d52a5 | 759 | ret = g_new0(struct bt_clock_value, 1); |
61ec14e6 | 760 | if (!ret) { |
5134570b | 761 | BT_LOGE_STR("Failed to allocate one clock value."); |
61ec14e6 JG |
762 | goto end; |
763 | } | |
764 | ||
a6918753 PP |
765 | bt_object_init(ret, NULL); |
766 | bt_object_set_is_shared((void *) ret, false); | |
ac0c6bdd | 767 | ret->clock_class = bt_get(clock_class); |
839d52a5 | 768 | bt_clock_class_freeze(clock_class); |
2cf0acd7 | 769 | BT_LOGD("Created clock value object: clock-value-addr=%p, " |
24e770c1 PP |
770 | "clock-class-addr=%p, clock-class-name=\"%s\", " |
771 | "ns-from-epoch=%" PRId64 ", ns-from-epoch-overflows=%d", | |
839d52a5 | 772 | ret, clock_class, bt_clock_class_get_name(clock_class), |
24e770c1 PP |
773 | ret->ns_from_epoch, ret->ns_from_epoch_overflows); |
774 | ||
61ec14e6 JG |
775 | end: |
776 | return ret; | |
777 | } | |
4ef18cab | 778 | |
a6918753 PP |
779 | BT_HIDDEN |
780 | struct bt_clock_value *bt_clock_value_create(struct bt_clock_class *clock_class) | |
781 | { | |
782 | struct bt_clock_value *clock_value = NULL; | |
783 | ||
784 | BT_ASSERT(clock_class); | |
785 | clock_value = bt_object_pool_create_object(&clock_class->cv_pool); | |
786 | if (!clock_value) { | |
787 | BT_LIB_LOGE("Cannot allocate one clock value from clock class's clock value pool: " | |
788 | "%![cc-]+K", clock_class); | |
789 | goto error; | |
790 | } | |
791 | ||
792 | if (!clock_value->clock_class) { | |
793 | clock_value->clock_class = bt_get(clock_class); | |
794 | } | |
795 | ||
796 | goto end; | |
797 | ||
798 | error: | |
799 | if (clock_value) { | |
800 | bt_clock_value_recycle(clock_value); | |
801 | clock_value = NULL; | |
802 | } | |
803 | ||
804 | end: | |
805 | return clock_value; | |
806 | } | |
807 | ||
808 | BT_HIDDEN | |
809 | void bt_clock_value_recycle(struct bt_clock_value *clock_value) | |
810 | { | |
811 | struct bt_clock_class *clock_class; | |
812 | ||
813 | BT_ASSERT(clock_value); | |
814 | BT_LIB_LOGD("Recycling clock value: %!+k", clock_value); | |
815 | ||
816 | /* | |
817 | * Those are the important ordered steps: | |
818 | * | |
819 | * 1. Reset the clock value object, but do NOT put its clock | |
820 | * class's reference. This clock class contains the pool to | |
821 | * which we're about to recycle this clock value object, so | |
822 | * we must guarantee its existence thanks to this existing | |
823 | * reference. | |
824 | * | |
825 | * 2. Move the clock class reference to our `clock_class` | |
826 | * variable so that we can set the clock value's clock class | |
827 | * member to NULL before recycling it. We CANNOT do this | |
828 | * after we put the clock class reference because this | |
829 | * bt_put() could destroy the clock class, also destroying | |
830 | * its clock value pool, thus also destroying our clock value | |
831 | * object (this would result in an invalid write access). | |
832 | * | |
833 | * 3. Recycle the clock value object. | |
834 | * | |
835 | * 4. Put our clock class reference. | |
836 | */ | |
837 | bt_clock_value_reset(clock_value); | |
838 | bt_clock_value_set_is_frozen(clock_value, false); | |
839 | clock_class = clock_value->clock_class; | |
840 | BT_ASSERT(clock_class); | |
841 | clock_value->clock_class = NULL; | |
842 | bt_object_pool_recycle_object(&clock_class->cv_pool, clock_value); | |
843 | bt_put(clock_class); | |
844 | } | |
845 | ||
846 | BT_HIDDEN | |
847 | void bt_clock_value_set_raw_value(struct bt_clock_value *clock_value, | |
848 | uint64_t cycles) | |
849 | { | |
850 | BT_ASSERT(clock_value); | |
851 | ||
852 | clock_value->value = cycles; | |
853 | set_ns_from_epoch(clock_value); | |
854 | bt_clock_value_set(clock_value); | |
855 | } | |
856 | ||
857 | int bt_clock_value_set_value(struct bt_clock_value *clock_value, | |
858 | uint64_t raw_value) | |
859 | { | |
860 | BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value"); | |
861 | BT_ASSERT_PRE_HOT(clock_value, "Clock value", ": %!+k", clock_value); | |
862 | bt_clock_value_set_raw_value(clock_value, raw_value); | |
863 | return 0; | |
864 | } | |
865 | ||
866 | int bt_clock_value_get_value(struct bt_clock_value *clock_value, | |
867 | uint64_t *raw_value) | |
61ec14e6 JG |
868 | { |
869 | int ret = 0; | |
4ef18cab | 870 | |
61ec14e6 | 871 | if (!clock_value || !raw_value) { |
5134570b PP |
872 | BT_LOGW("Invalid parameter: clock value or raw value is NULL: " |
873 | "clock-value-addr=%p, raw-value-addr=%p", | |
874 | clock_value, raw_value); | |
61ec14e6 JG |
875 | ret = -1; |
876 | goto end; | |
877 | } | |
4ef18cab | 878 | |
61ec14e6 | 879 | *raw_value = clock_value->value; |
4ef18cab | 880 | end: |
61ec14e6 JG |
881 | return ret; |
882 | } | |
883 | ||
839d52a5 | 884 | int bt_clock_value_get_value_ns_from_epoch(struct bt_clock_value *value, |
61ec14e6 JG |
885 | int64_t *ret_value_ns) |
886 | { | |
887 | int ret = 0; | |
61ec14e6 JG |
888 | |
889 | if (!value || !ret_value_ns) { | |
5134570b PP |
890 | BT_LOGW("Invalid parameter: clock value or return value pointer is NULL: " |
891 | "clock-value-addr=%p, ret-value-addr=%p", | |
892 | value, ret_value_ns); | |
61ec14e6 JG |
893 | ret = -1; |
894 | goto end; | |
895 | } | |
896 | ||
24e770c1 PP |
897 | if (value->ns_from_epoch_overflows) { |
898 | BT_LOGW("Clock value converted to nanoseconds from Epoch overflows the signed 64-bit integer range: " | |
899 | "clock-value-addr=%p, " | |
900 | "clock-class-offset-s=%" PRId64 ", " | |
901 | "clock-class-offset-cycles=%" PRId64 ", " | |
902 | "value=%" PRIu64, | |
903 | value, value->clock_class->offset_s, | |
904 | value->clock_class->offset, | |
905 | value->value); | |
906 | ret = -1; | |
907 | goto end; | |
908 | } | |
61ec14e6 | 909 | |
24e770c1 | 910 | *ret_value_ns = value->ns_from_epoch; |
61ec14e6 | 911 | |
61ec14e6 JG |
912 | end: |
913 | return ret; | |
4ef18cab | 914 | } |
6f57e458 | 915 | |
5fe68922 | 916 | struct bt_clock_class *bt_clock_value_borrow_class( |
839d52a5 | 917 | struct bt_clock_value *clock_value) |
6f57e458 | 918 | { |
839d52a5 | 919 | struct bt_clock_class *clock_class = NULL; |
6f57e458 PP |
920 | |
921 | if (!clock_value) { | |
5134570b | 922 | BT_LOGW_STR("Invalid parameter: clock value is NULL."); |
6f57e458 PP |
923 | goto end; |
924 | } | |
925 | ||
5fe68922 | 926 | clock_class = clock_value->clock_class; |
6f57e458 PP |
927 | |
928 | end: | |
929 | return clock_class; | |
930 | } | |
db3347ac PP |
931 | |
932 | BT_HIDDEN | |
933 | int bt_clock_class_compare(struct bt_clock_class *clock_class_a, | |
934 | struct bt_clock_class *clock_class_b) | |
935 | { | |
936 | int ret = 1; | |
8b45963b PP |
937 | BT_ASSERT(clock_class_a); |
938 | BT_ASSERT(clock_class_b); | |
db3347ac PP |
939 | |
940 | /* Name */ | |
941 | if (strcmp(clock_class_a->name->str, clock_class_b->name->str) != 0) { | |
942 | BT_LOGV("Clock classes differ: different names: " | |
943 | "cc-a-name=\"%s\", cc-b-name=\"%s\"", | |
944 | clock_class_a->name->str, | |
945 | clock_class_b->name->str); | |
946 | goto end; | |
947 | } | |
948 | ||
949 | /* Description */ | |
950 | if (clock_class_a->description) { | |
951 | if (!clock_class_b->description) { | |
952 | BT_LOGV_STR("Clock classes differ: clock class A has a " | |
953 | "description, but clock class B does not."); | |
954 | goto end; | |
955 | } | |
956 | ||
957 | if (strcmp(clock_class_a->name->str, clock_class_b->name->str) | |
958 | != 0) { | |
959 | BT_LOGV("Clock classes differ: different descriptions: " | |
960 | "cc-a-descr=\"%s\", cc-b-descr=\"%s\"", | |
961 | clock_class_a->description->str, | |
962 | clock_class_b->description->str); | |
963 | goto end; | |
964 | } | |
965 | } else { | |
966 | if (clock_class_b->description) { | |
967 | BT_LOGV_STR("Clock classes differ: clock class A has " | |
968 | "no description, but clock class B has one."); | |
969 | goto end; | |
970 | } | |
971 | } | |
972 | ||
973 | /* Frequency */ | |
974 | if (clock_class_a->frequency != clock_class_b->frequency) { | |
975 | BT_LOGV("Clock classes differ: different frequencies: " | |
976 | "cc-a-freq=%" PRIu64 ", cc-b-freq=%" PRIu64, | |
977 | clock_class_a->frequency, | |
978 | clock_class_b->frequency); | |
979 | goto end; | |
980 | } | |
981 | ||
982 | /* Precision */ | |
983 | if (clock_class_a->precision != clock_class_b->precision) { | |
984 | BT_LOGV("Clock classes differ: different precisions: " | |
985 | "cc-a-freq=%" PRIu64 ", cc-b-freq=%" PRIu64, | |
986 | clock_class_a->precision, | |
987 | clock_class_b->precision); | |
988 | goto end; | |
989 | } | |
990 | ||
991 | /* Offset (seconds) */ | |
992 | if (clock_class_a->offset_s != clock_class_b->offset_s) { | |
993 | BT_LOGV("Clock classes differ: different offsets (seconds): " | |
994 | "cc-a-offset-s=%" PRId64 ", cc-b-offset-s=%" PRId64, | |
995 | clock_class_a->offset_s, | |
996 | clock_class_b->offset_s); | |
997 | goto end; | |
998 | } | |
999 | ||
1000 | /* Offset (cycles) */ | |
1001 | if (clock_class_a->offset != clock_class_b->offset) { | |
1002 | BT_LOGV("Clock classes differ: different offsets (cycles): " | |
1003 | "cc-a-offset-s=%" PRId64 ", cc-b-offset-s=%" PRId64, | |
1004 | clock_class_a->offset, | |
1005 | clock_class_b->offset); | |
1006 | goto end; | |
1007 | } | |
1008 | ||
1009 | /* UUIDs */ | |
1010 | if (clock_class_a->uuid_set) { | |
1011 | if (!clock_class_b->uuid_set) { | |
1012 | BT_LOGV_STR("Clock classes differ: clock class A has a " | |
1013 | "UUID, but clock class B does not."); | |
1014 | goto end; | |
1015 | } | |
1016 | ||
1017 | if (memcmp(clock_class_a->uuid, clock_class_b->uuid, | |
1018 | BABELTRACE_UUID_LEN) != 0) { | |
1019 | BT_LOGV("Clock classes differ: different UUIDs: " | |
1020 | "cc-a-uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\", " | |
1021 | "cc-b-uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"", | |
1022 | (unsigned int) clock_class_a->uuid[0], | |
1023 | (unsigned int) clock_class_a->uuid[1], | |
1024 | (unsigned int) clock_class_a->uuid[2], | |
1025 | (unsigned int) clock_class_a->uuid[3], | |
1026 | (unsigned int) clock_class_a->uuid[4], | |
1027 | (unsigned int) clock_class_a->uuid[5], | |
1028 | (unsigned int) clock_class_a->uuid[6], | |
1029 | (unsigned int) clock_class_a->uuid[7], | |
1030 | (unsigned int) clock_class_a->uuid[8], | |
1031 | (unsigned int) clock_class_a->uuid[9], | |
1032 | (unsigned int) clock_class_a->uuid[10], | |
1033 | (unsigned int) clock_class_a->uuid[11], | |
1034 | (unsigned int) clock_class_a->uuid[12], | |
1035 | (unsigned int) clock_class_a->uuid[13], | |
1036 | (unsigned int) clock_class_a->uuid[14], | |
1037 | (unsigned int) clock_class_a->uuid[15], | |
1038 | (unsigned int) clock_class_b->uuid[0], | |
1039 | (unsigned int) clock_class_b->uuid[1], | |
1040 | (unsigned int) clock_class_b->uuid[2], | |
1041 | (unsigned int) clock_class_b->uuid[3], | |
1042 | (unsigned int) clock_class_b->uuid[4], | |
1043 | (unsigned int) clock_class_b->uuid[5], | |
1044 | (unsigned int) clock_class_b->uuid[6], | |
1045 | (unsigned int) clock_class_b->uuid[7], | |
1046 | (unsigned int) clock_class_b->uuid[8], | |
1047 | (unsigned int) clock_class_b->uuid[9], | |
1048 | (unsigned int) clock_class_b->uuid[10], | |
1049 | (unsigned int) clock_class_b->uuid[11], | |
1050 | (unsigned int) clock_class_b->uuid[12], | |
1051 | (unsigned int) clock_class_b->uuid[13], | |
1052 | (unsigned int) clock_class_b->uuid[14], | |
1053 | (unsigned int) clock_class_b->uuid[15]); | |
1054 | goto end; | |
1055 | } | |
1056 | } else { | |
1057 | if (clock_class_b->uuid_set) { | |
1058 | BT_LOGV_STR("Clock classes differ: clock class A has " | |
1059 | "no UUID, but clock class B has one."); | |
1060 | goto end; | |
1061 | } | |
1062 | } | |
1063 | ||
1064 | /* Absolute */ | |
1065 | if (!!clock_class_a->absolute != !!clock_class_b->absolute) { | |
1066 | BT_LOGV("Clock classes differ: one is absolute, the other " | |
1067 | "is not: cc-a-is-absolute=%d, cc-b-is-absolute=%d", | |
1068 | !!clock_class_a->absolute, | |
1069 | !!clock_class_b->absolute); | |
1070 | goto end; | |
1071 | } | |
1072 | ||
1073 | /* Equal */ | |
1074 | ret = 0; | |
1075 | ||
1076 | end: | |
1077 | return ret; | |
1078 | } | |
a6918753 PP |
1079 | |
1080 | int bt_clock_class_cycles_to_ns(struct bt_clock_class *clock_class, | |
1081 | uint64_t cycles, int64_t *ns) | |
1082 | { | |
1083 | int ret; | |
1084 | bool overflows; | |
1085 | ||
1086 | BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class"); | |
1087 | BT_ASSERT_PRE_NON_NULL(ns, "Nanoseconds"); | |
1088 | ||
1089 | ret = ns_from_epoch(clock_class, cycles, ns, &overflows); | |
1090 | if (ret) { | |
1091 | if (overflows) { | |
1092 | BT_LIB_LOGW("Cannot convert cycles to nanoseconds " | |
1093 | "from Epoch for given clock class: " | |
1094 | "value overflow: %![cc-]+K, cycles=%" PRIu64, | |
1095 | clock_class, cycles); | |
1096 | } else { | |
1097 | BT_LIB_LOGW("Cannot convert cycles to nanoseconds " | |
1098 | "from Epoch for given clock class: " | |
1099 | "%![cc-]+K, cycles=%" PRIu64, | |
1100 | clock_class, cycles); | |
1101 | } | |
1102 | ||
1103 | goto end; | |
1104 | } | |
1105 | ||
1106 | end: | |
1107 | return ret; | |
1108 | } |