Move to kernel style SPDX license identifiers
[babeltrace.git] / src / lib / trace-ir / clock-class.c
CommitLineData
273b65be 1/*
0235b0db
MJ
2 * SPDX-License-Identifier: MIT
3 *
e2f7325d 4 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
de9dd397 5 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
273b65be
JG
6 */
7
350ad6c1 8#define BT_LOG_TAG "LIB/CLOCK-CLASS"
c2d9d9cf 9#include "lib/logging.h"
0f5e83e5 10
578e048b 11#include "lib/assert-pre.h"
6162e6b7 12#include "common/uuid.h"
3fadfbc0 13#include <babeltrace2/trace-ir/clock-class.h>
578e048b
MJ
14#include "clock-class.h"
15#include "clock-snapshot.h"
16#include "utils.h"
17#include "compat/compiler.h"
3fadfbc0 18#include <babeltrace2/types.h>
578e048b 19#include "compat/string.h"
273b65be 20#include <inttypes.h>
c4f23e30 21#include <stdbool.h>
578e048b
MJ
22#include "lib/object.h"
23#include "common/assert.h"
d24d5663 24#include "lib/func-status.h"
c6962c96 25#include "lib/value.h"
5134570b 26
bdb288b3
PP
27#define BT_ASSERT_PRE_DEV_CLOCK_CLASS_HOT(_cc) \
28 BT_ASSERT_PRE_DEV_HOT((_cc), "Clock class", ": %!+K", (_cc))
312c056a
PP
29
30static
44c440bc 31void destroy_clock_class(struct bt_object *obj)
c06116f3 32{
44c440bc 33 struct bt_clock_class *clock_class = (void *) obj;
c06116f3 34
44c440bc 35 BT_LIB_LOGD("Destroying clock class: %!+K", clock_class);
c6962c96 36 BT_OBJECT_PUT_REF_AND_RESET(clock_class->user_attributes);
273b65be 37
44c440bc
PP
38 if (clock_class->name.str) {
39 g_string_free(clock_class->name.str, TRUE);
238b7404
PP
40 clock_class->name.str = NULL;
41 clock_class->name.value = NULL;
5134570b
PP
42 }
43
44c440bc
PP
44 if (clock_class->description.str) {
45 g_string_free(clock_class->description.str, TRUE);
238b7404
PP
46 clock_class->description.str = NULL;
47 clock_class->description.value = NULL;
273b65be
JG
48 }
49
605e1019 50 bt_object_pool_finalize(&clock_class->cs_pool);
44c440bc 51 g_free(clock_class);
4c426c17
JG
52}
53
f3534905 54static
605e1019 55void free_clock_snapshot(struct bt_clock_snapshot *clock_snapshot,
44c440bc 56 struct bt_clock_class *clock_class)
f3534905 57{
605e1019 58 bt_clock_snapshot_destroy(clock_snapshot);
f3534905
PP
59}
60
44c440bc
PP
61static inline
62void set_base_offset(struct bt_clock_class *clock_class)
312c056a 63{
0f2d58c9
PP
64 clock_class->base_offset.overflows = bt_util_get_base_offset_ns(
65 clock_class->offset_seconds, clock_class->offset_cycles,
66 clock_class->frequency, &clock_class->base_offset.value_ns);
312c056a
PP
67}
68
7fcdb0a9 69struct bt_clock_class *bt_clock_class_create(bt_self_component *self_comp)
4c426c17
JG
70{
71 int ret;
50842bdc 72 struct bt_clock_class *clock_class = NULL;
4c426c17 73
17f3083a 74 BT_ASSERT_PRE_NO_ERROR();
7fcdb0a9 75 BT_ASSERT_PRE_NON_NULL(self_comp, "Self component");
44c440bc 76 BT_LOGD_STR("Creating default clock class object");
f3534905 77
50842bdc 78 clock_class = g_new0(struct bt_clock_class, 1);
ac0c6bdd 79 if (!clock_class) {
870631a2 80 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one clock class.");
4c426c17
JG
81 goto error;
82 }
83
44c440bc 84 bt_object_init_shared(&clock_class->base, destroy_clock_class);
c6962c96
PP
85
86 clock_class->user_attributes = bt_value_map_create();
87 if (!clock_class->user_attributes) {
88 BT_LIB_LOGE_APPEND_CAUSE(
89 "Failed to create a map value object.");
90 goto error;
91 }
92
44c440bc
PP
93 clock_class->name.str = g_string_new(NULL);
94 if (!clock_class->name.str) {
870631a2 95 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
44c440bc
PP
96 goto error;
97 }
85380e99 98
44c440bc
PP
99 clock_class->description.str = g_string_new(NULL);
100 if (!clock_class->description.str) {
870631a2 101 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
44c440bc 102 goto error;
273b65be
JG
103 }
104
44c440bc 105 clock_class->frequency = UINT64_C(1000000000);
5552377a 106 clock_class->origin_is_unix_epoch = BT_TRUE;
44c440bc 107 set_base_offset(clock_class);
605e1019
PP
108 ret = bt_object_pool_initialize(&clock_class->cs_pool,
109 (bt_object_pool_new_object_func) bt_clock_snapshot_new,
312c056a 110 (bt_object_pool_destroy_object_func)
605e1019 111 free_clock_snapshot,
312c056a
PP
112 clock_class);
113 if (ret) {
870631a2
PP
114 BT_LIB_LOGE_APPEND_CAUSE(
115 "Failed to initialize clock snapshot pool: ret=%d",
312c056a
PP
116 ret);
117 goto error;
118 }
119
44c440bc
PP
120 BT_LIB_LOGD("Created clock class object: %!+K", clock_class);
121 goto end;
122
273b65be 123error:
65300d60 124 BT_OBJECT_PUT_REF_AND_RESET(clock_class);
87d76bb1
JG
125
126end:
40f4ba76 127 return clock_class;
87d76bb1
JG
128}
129
40f4ba76 130const char *bt_clock_class_get_name(const struct bt_clock_class *clock_class)
87d76bb1 131{
bdb288b3 132 BT_ASSERT_PRE_DEV_NON_NULL(clock_class, "Clock class");
44c440bc
PP
133 return clock_class->name.value;
134}
87d76bb1 135
d24d5663 136enum bt_clock_class_set_name_status bt_clock_class_set_name(
8c41fd73 137 struct bt_clock_class *clock_class, const char *name)
44c440bc 138{
17f3083a 139 BT_ASSERT_PRE_NO_ERROR();
44c440bc
PP
140 BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
141 BT_ASSERT_PRE_NON_NULL(name, "Name");
bdb288b3 142 BT_ASSERT_PRE_DEV_CLOCK_CLASS_HOT(clock_class);
44c440bc
PP
143 g_string_assign(clock_class->name.str, name);
144 clock_class->name.value = clock_class->name.str->str;
3f7d4d90 145 BT_LIB_LOGD("Set clock class's name: %!+K", clock_class);
d24d5663 146 return BT_FUNC_STATUS_OK;
44c440bc 147}
87d76bb1 148
40f4ba76
PP
149const char *bt_clock_class_get_description(
150 const struct bt_clock_class *clock_class)
44c440bc 151{
bdb288b3 152 BT_ASSERT_PRE_DEV_NON_NULL(clock_class, "Clock class");
44c440bc 153 return clock_class->description.value;
273b65be
JG
154}
155
d24d5663 156enum bt_clock_class_set_description_status bt_clock_class_set_description(
8c41fd73 157 struct bt_clock_class *clock_class, const char *descr)
273b65be 158{
17f3083a 159 BT_ASSERT_PRE_NO_ERROR();
44c440bc
PP
160 BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
161 BT_ASSERT_PRE_NON_NULL(descr, "Description");
bdb288b3 162 BT_ASSERT_PRE_DEV_CLOCK_CLASS_HOT(clock_class);
44c440bc
PP
163 g_string_assign(clock_class->description.str, descr);
164 clock_class->description.value = clock_class->description.str->str;
3f7d4d90 165 BT_LIB_LOGD("Set clock class's description: %!+K",
44c440bc 166 clock_class);
d24d5663 167 return BT_FUNC_STATUS_OK;
273b65be
JG
168}
169
40f4ba76 170uint64_t bt_clock_class_get_frequency(const struct bt_clock_class *clock_class)
87d76bb1 171{
bdb288b3 172 BT_ASSERT_PRE_DEV_NON_NULL(clock_class, "Clock class");
44c440bc 173 return clock_class->frequency;
87d76bb1
JG
174}
175
40f4ba76 176void bt_clock_class_set_frequency(struct bt_clock_class *clock_class,
44c440bc 177 uint64_t frequency)
273b65be 178{
44c440bc 179 BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
bdb288b3 180 BT_ASSERT_PRE_DEV_CLOCK_CLASS_HOT(clock_class);
44c440bc
PP
181 BT_ASSERT_PRE(frequency != UINT64_C(-1) && frequency != 0,
182 "Invalid frequency: %![cc-]+K, new-freq=%" PRIu64,
183 clock_class, frequency);
184 BT_ASSERT_PRE(clock_class->offset_cycles < frequency,
185 "Offset (cycles) is greater than clock class's frequency: "
186 "%![cc-]+K, new-freq=%" PRIu64, clock_class, frequency);
187 clock_class->frequency = frequency;
188 set_base_offset(clock_class);
3f7d4d90 189 BT_LIB_LOGD("Set clock class's frequency: %!+K", clock_class);
273b65be
JG
190}
191
40f4ba76 192uint64_t bt_clock_class_get_precision(const struct bt_clock_class *clock_class)
87d76bb1 193{
bdb288b3 194 BT_ASSERT_PRE_DEV_NON_NULL(clock_class, "Clock class");
44c440bc 195 return clock_class->precision;
87d76bb1
JG
196}
197
40f4ba76 198void bt_clock_class_set_precision(struct bt_clock_class *clock_class,
ac0c6bdd 199 uint64_t precision)
273b65be 200{
44c440bc 201 BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
bdb288b3 202 BT_ASSERT_PRE_DEV_CLOCK_CLASS_HOT(clock_class);
44c440bc
PP
203 BT_ASSERT_PRE(precision != UINT64_C(-1),
204 "Invalid precision: %![cc-]+K, new-precision=%" PRIu64,
205 clock_class, precision);
ac0c6bdd 206 clock_class->precision = precision;
3f7d4d90 207 BT_LIB_LOGD("Set clock class's precision: %!+K", clock_class);
273b65be
JG
208}
209
40f4ba76 210void bt_clock_class_get_offset(const struct bt_clock_class *clock_class,
44c440bc 211 int64_t *seconds, uint64_t *cycles)
87d76bb1 212{
bdb288b3
PP
213 BT_ASSERT_PRE_DEV_NON_NULL(clock_class, "Clock class");
214 BT_ASSERT_PRE_DEV_NON_NULL(seconds, "Seconds (output)");
215 BT_ASSERT_PRE_DEV_NON_NULL(cycles, "Cycles (output)");
44c440bc
PP
216 *seconds = clock_class->offset_seconds;
217 *cycles = clock_class->offset_cycles;
87d76bb1
JG
218}
219
40f4ba76 220void bt_clock_class_set_offset(struct bt_clock_class *clock_class,
44c440bc 221 int64_t seconds, uint64_t cycles)
273b65be 222{
44c440bc 223 BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
bdb288b3 224 BT_ASSERT_PRE_DEV_CLOCK_CLASS_HOT(clock_class);
44c440bc
PP
225 BT_ASSERT_PRE(cycles < clock_class->frequency,
226 "Offset (cycles) is greater than clock class's frequency: "
227 "%![cc-]+K, new-offset-cycles=%" PRIu64, clock_class, cycles);
228 clock_class->offset_seconds = seconds;
229 clock_class->offset_cycles = cycles;
230 set_base_offset(clock_class);
3f7d4d90 231 BT_LIB_LOGD("Set clock class's offset: %!+K", clock_class);
273b65be
JG
232}
233
5552377a 234bt_bool bt_clock_class_origin_is_unix_epoch(const struct bt_clock_class *clock_class)
87d76bb1 235{
bdb288b3 236 BT_ASSERT_PRE_DEV_NON_NULL(clock_class, "Clock class");
5552377a 237 return (bool) clock_class->origin_is_unix_epoch;
87d76bb1
JG
238}
239
5552377a
PP
240void bt_clock_class_set_origin_is_unix_epoch(struct bt_clock_class *clock_class,
241 bt_bool origin_is_unix_epoch)
273b65be 242{
44c440bc 243 BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
bdb288b3 244 BT_ASSERT_PRE_DEV_CLOCK_CLASS_HOT(clock_class);
5552377a 245 clock_class->origin_is_unix_epoch = (bool) origin_is_unix_epoch;
3f7d4d90 246 BT_LIB_LOGD("Set clock class's origin is Unix epoch property: %!+K",
44c440bc 247 clock_class);
273b65be
JG
248}
249
40f4ba76 250bt_uuid bt_clock_class_get_uuid(const struct bt_clock_class *clock_class)
85b743f4 251{
bdb288b3 252 BT_ASSERT_PRE_DEV_NON_NULL(clock_class, "Clock class");
44c440bc 253 return clock_class->uuid.value;
85b743f4
JG
254}
255
40f4ba76 256void bt_clock_class_set_uuid(struct bt_clock_class *clock_class,
44c440bc 257 bt_uuid uuid)
85b743f4 258{
44c440bc
PP
259 BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
260 BT_ASSERT_PRE_NON_NULL(uuid, "UUID");
bdb288b3 261 BT_ASSERT_PRE_DEV_CLOCK_CLASS_HOT(clock_class);
6162e6b7 262 bt_uuid_copy(clock_class->uuid.uuid, uuid);
44c440bc 263 clock_class->uuid.value = clock_class->uuid.uuid;
3f7d4d90 264 BT_LIB_LOGD("Set clock class's UUID: %!+K", clock_class);
312c056a
PP
265}
266
267BT_HIDDEN
40f4ba76 268void _bt_clock_class_freeze(const struct bt_clock_class *clock_class)
312c056a 269{
312c056a 270 BT_ASSERT(clock_class);
6f57e458 271
44c440bc
PP
272 if (clock_class->frozen) {
273 return;
93dda901
PP
274 }
275
c6962c96
PP
276 BT_LIB_LOGD("Freezing clock class's user attributes: %!+v",
277 clock_class->user_attributes);
278 bt_value_freeze(clock_class->user_attributes);
44c440bc 279 BT_LIB_LOGD("Freezing clock class: %!+K", clock_class);
40f4ba76 280 ((struct bt_clock_class *) clock_class)->frozen = 1;
93dda901 281}
312c056a 282
d24d5663
PP
283enum bt_clock_class_cycles_to_ns_from_origin_status
284bt_clock_class_cycles_to_ns_from_origin(
40f4ba76 285 const struct bt_clock_class *clock_class,
312c056a
PP
286 uint64_t cycles, int64_t *ns)
287{
288 int ret;
312c056a 289
17f3083a 290 BT_ASSERT_PRE_DEV_NO_ERROR();
bdb288b3
PP
291 BT_ASSERT_PRE_DEV_NON_NULL(clock_class, "Clock class");
292 BT_ASSERT_PRE_DEV_NON_NULL(ns, "Nanoseconds (output)");
0f2d58c9 293 ret = bt_util_ns_from_origin_clock_class(clock_class, cycles, ns);
312c056a 294 if (ret) {
bc3d9692 295 BT_LIB_LOGE_APPEND_CAUSE("Cannot convert cycles to nanoseconds "
44c440bc
PP
296 "from origin for given clock class: "
297 "value overflows the signed 64-bit integer range: "
298 "%![cc-]+K, cycles=%" PRIu64,
299 clock_class, cycles);
520cdc82 300 ret = BT_FUNC_STATUS_OVERFLOW_ERROR;
312c056a
PP
301 }
302
312c056a
PP
303 return ret;
304}
c5b9b441 305
c6962c96
PP
306const struct bt_value *bt_clock_class_borrow_user_attributes_const(
307 const struct bt_clock_class *clock_class)
308{
309 BT_ASSERT_PRE_DEV_NON_NULL(clock_class, "Clock class");
310 return clock_class->user_attributes;
311}
312
313struct bt_value *bt_clock_class_borrow_user_attributes(
314 struct bt_clock_class *clock_class)
315{
316 return (void *) bt_clock_class_borrow_user_attributes_const(
317 (void *) clock_class);
318}
319
320void bt_clock_class_set_user_attributes(
321 struct bt_clock_class *clock_class,
322 const struct bt_value *user_attributes)
323{
324 BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
325 BT_ASSERT_PRE_NON_NULL(user_attributes, "User attributes");
326 BT_ASSERT_PRE(user_attributes->type == BT_VALUE_TYPE_MAP,
327 "User attributes object is not a map value object.");
328 BT_ASSERT_PRE_DEV_CLOCK_CLASS_HOT(clock_class);
6871026b 329 bt_object_put_ref_no_null_check(clock_class->user_attributes);
c6962c96 330 clock_class->user_attributes = (void *) user_attributes;
6871026b 331 bt_object_get_ref_no_null_check(clock_class->user_attributes);
c6962c96
PP
332}
333
c5b9b441
PP
334void bt_clock_class_get_ref(const struct bt_clock_class *clock_class)
335{
336 bt_object_get_ref(clock_class);
337}
338
339void bt_clock_class_put_ref(const struct bt_clock_class *clock_class)
340{
341 bt_object_put_ref(clock_class);
342}
This page took 0.105842 seconds and 4 git commands to generate.