Split CTF IR and CTF writer APIs and implementations
[babeltrace.git] / lib / ctf-writer / clock.c
1 /*
2 * clock.c
3 *
4 * Babeltrace CTF IR - Clock
5 *
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
8 *
9 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * SOFTWARE.
28 */
29
30 #define BT_LOG_TAG "CTF-WRITER-CLOCK"
31 #include <babeltrace/lib-logging-internal.h>
32
33 #include <babeltrace/ctf-writer/clock-internal.h>
34 #include <babeltrace/ctf-writer/writer-internal.h>
35 #include <babeltrace/ctf-ir/clock-class.h>
36 #include <babeltrace/ctf-ir/clock-class-internal.h>
37 #include <babeltrace/ctf-ir/utils.h>
38 #include <babeltrace/compat/uuid-internal.h>
39 #include <babeltrace/ref.h>
40 #include <babeltrace/object-internal.h>
41 #include <babeltrace/compiler-internal.h>
42 #include <babeltrace/assert-internal.h>
43 #include <inttypes.h>
44
45 static
46 void bt_ctf_clock_destroy(struct bt_object *obj);
47
48 struct bt_ctf_clock *bt_ctf_clock_create(const char *name)
49 {
50 int ret;
51 struct bt_ctf_clock *clock = NULL;
52 unsigned char cc_uuid[BABELTRACE_UUID_LEN];
53
54 BT_ASSERT_PRE_NON_NULL(name, "Name");
55 clock = g_new0(struct bt_ctf_clock, 1);
56 if (!clock) {
57 goto error;
58 }
59
60 bt_object_init(clock, bt_ctf_clock_destroy);
61 clock->value = 0;
62
63 /* Pre-2.0.0 backward compatibility: default frequency is 1 GHz */
64 clock->clock_class = (void *) bt_clock_class_create(name, 1000000000);
65 if (!clock->clock_class) {
66 goto error;
67 }
68
69 /* Automatically set clock class's UUID. */
70 ret = bt_uuid_generate(cc_uuid);
71 if (ret) {
72 goto error;
73 }
74
75 ret = bt_clock_class_set_uuid(BT_TO_COMMON(clock->clock_class),
76 cc_uuid);
77 BT_ASSERT(ret == 0);
78 return clock;
79
80 error:
81 BT_PUT(clock);
82 return clock;
83 }
84
85 const char *bt_ctf_clock_get_name(struct bt_ctf_clock *clock)
86 {
87 BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
88 return bt_clock_class_get_name(BT_TO_COMMON(clock->clock_class));
89 }
90
91 const char *bt_ctf_clock_get_description(struct bt_ctf_clock *clock)
92 {
93 BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
94 return bt_clock_class_get_description(BT_TO_COMMON(clock->clock_class));
95 }
96
97 int bt_ctf_clock_set_description(struct bt_ctf_clock *clock, const char *desc)
98 {
99 BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
100 return bt_clock_class_set_description(BT_TO_COMMON(clock->clock_class),
101 desc);
102 }
103
104 uint64_t bt_ctf_clock_get_frequency(struct bt_ctf_clock *clock)
105 {
106 BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
107 return bt_clock_class_get_frequency(BT_TO_COMMON(clock->clock_class));
108 }
109
110 int bt_ctf_clock_set_frequency(struct bt_ctf_clock *clock, uint64_t freq)
111 {
112 BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
113 return bt_clock_class_set_frequency(BT_TO_COMMON(clock->clock_class),
114 freq);
115 }
116
117 uint64_t bt_ctf_clock_get_precision(struct bt_ctf_clock *clock)
118 {
119 BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
120 return bt_clock_class_get_precision(BT_TO_COMMON(clock->clock_class));
121 }
122
123 int bt_ctf_clock_set_precision(struct bt_ctf_clock *clock, uint64_t precision)
124 {
125 BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
126 return bt_clock_class_set_precision(BT_TO_COMMON(clock->clock_class),
127 precision);
128 }
129
130 int bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock, int64_t *offset_s)
131 {
132 BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
133 return bt_clock_class_get_offset_s(BT_TO_COMMON(clock->clock_class),
134 offset_s);
135 }
136
137 int bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock, int64_t offset_s)
138 {
139 BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
140 return bt_clock_class_set_offset_s(BT_TO_COMMON(clock->clock_class),
141 offset_s);
142 }
143
144 int bt_ctf_clock_get_offset(struct bt_ctf_clock *clock, int64_t *offset)
145 {
146 BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
147 return bt_clock_class_get_offset_cycles(BT_TO_COMMON(clock->clock_class),
148 offset);
149 }
150
151 int bt_ctf_clock_set_offset(struct bt_ctf_clock *clock, int64_t offset)
152 {
153 BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
154 return bt_clock_class_set_offset_cycles(BT_TO_COMMON(clock->clock_class),
155 offset);
156 }
157
158 int bt_ctf_clock_get_is_absolute(struct bt_ctf_clock *clock)
159 {
160 BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
161 return bt_clock_class_is_absolute(BT_TO_COMMON(clock->clock_class));
162 }
163
164 int bt_ctf_clock_set_is_absolute(struct bt_ctf_clock *clock, int is_absolute)
165 {
166 BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
167 return bt_clock_class_set_is_absolute(BT_TO_COMMON(clock->clock_class),
168 is_absolute);
169 }
170
171 const unsigned char *bt_ctf_clock_get_uuid(struct bt_ctf_clock *clock)
172 {
173 BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
174 return bt_clock_class_get_uuid(BT_TO_COMMON(clock->clock_class));
175 }
176
177 int bt_ctf_clock_set_uuid(struct bt_ctf_clock *clock, const unsigned char *uuid)
178 {
179 BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
180 return bt_clock_class_set_uuid(BT_TO_COMMON(clock->clock_class), uuid);
181 }
182
183 int bt_ctf_clock_set_time(struct bt_ctf_clock *clock, int64_t time)
184 {
185 int64_t value;
186 struct bt_clock_class *cc;
187
188 BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
189 cc = BT_TO_COMMON(clock->clock_class);
190
191 /* Common case where cycles are actually nanoseconds */
192 if (cc->frequency == 1000000000) {
193 value = time;
194 } else {
195 value = (uint64_t) (((double) time *
196 (double) cc->frequency) / 1e9);
197 }
198
199 BT_ASSERT_PRE(clock->value <= value,
200 "CTF writer clock value must be updated monotonically: "
201 "prev-value=%" PRId64 ", new-value=%" PRId64,
202 clock->value, value);
203 clock->value = value;
204 return 0;
205 }
206
207 BT_HIDDEN
208 int bt_ctf_clock_get_value(struct bt_ctf_clock *clock, uint64_t *value)
209 {
210 BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
211 BT_ASSERT_PRE_NON_NULL(value, "Value");
212 *value = clock->value;
213 return 0;
214 }
215
216 static
217 void bt_ctf_clock_destroy(struct bt_object *obj)
218 {
219 struct bt_ctf_clock *clock;
220
221 clock = container_of(obj, struct bt_ctf_clock, base);
222 bt_put(BT_TO_COMMON(clock->clock_class));
223 g_free(clock);
224 }
225
226 BT_HIDDEN
227 void bt_ctf_clock_class_serialize(struct bt_ctf_clock_class *clock_class,
228 struct metadata_context *context)
229 {
230 unsigned char *uuid;
231
232 BT_LOGD("Serializing clock class's metadata: clock-class-addr=%p, "
233 "name=\"%s\", metadata-context-addr=%p", clock_class,
234 bt_clock_class_get_name(BT_TO_COMMON(clock_class)),
235 context);
236
237 if (!clock_class || !context) {
238 BT_LOGW("Invalid parameter: clock class or metadata context is NULL: "
239 "clock-class-addr=%p, name=\"%s\", metadata-context-addr=%p",
240 clock_class,
241 bt_clock_class_get_name(BT_TO_COMMON(clock_class)),
242 context);
243 return;
244 }
245
246 uuid = clock_class->common.uuid;
247 g_string_append(context->string, "clock {\n");
248 g_string_append_printf(context->string, "\tname = %s;\n",
249 clock_class->common.name->str);
250
251 if (clock_class->common.uuid_set) {
252 g_string_append_printf(context->string,
253 "\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n",
254 uuid[0], uuid[1], uuid[2], uuid[3],
255 uuid[4], uuid[5], uuid[6], uuid[7],
256 uuid[8], uuid[9], uuid[10], uuid[11],
257 uuid[12], uuid[13], uuid[14], uuid[15]);
258 }
259
260 if (clock_class->common.description) {
261 g_string_append_printf(context->string, "\tdescription = \"%s\";\n",
262 clock_class->common.description->str);
263 }
264
265 g_string_append_printf(context->string, "\tfreq = %" PRIu64 ";\n",
266 clock_class->common.frequency);
267 g_string_append_printf(context->string, "\tprecision = %" PRIu64 ";\n",
268 clock_class->common.precision);
269 g_string_append_printf(context->string, "\toffset_s = %" PRIu64 ";\n",
270 clock_class->common.offset_s);
271 g_string_append_printf(context->string, "\toffset = %" PRIu64 ";\n",
272 clock_class->common.offset);
273 g_string_append_printf(context->string, "\tabsolute = %s;\n",
274 clock_class->common.absolute ? "true" : "false");
275 g_string_append(context->string, "};\n\n");
276 }
277
278 struct bt_ctf_clock_class *bt_ctf_clock_class_create(const char *name,
279 uint64_t freq)
280 {
281 return BT_FROM_COMMON(bt_clock_class_create(name, freq));
282 }
283
284 const char *bt_ctf_clock_class_get_name(
285 struct bt_ctf_clock_class *clock_class)
286 {
287 return bt_clock_class_get_name(BT_TO_COMMON(clock_class));
288 }
289
290 int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class *clock_class,
291 const char *name)
292 {
293 return bt_clock_class_set_name(BT_TO_COMMON(clock_class), name);
294 }
295
296 const char *bt_ctf_clock_class_get_description(
297 struct bt_ctf_clock_class *clock_class)
298 {
299 return bt_clock_class_get_description(BT_TO_COMMON(clock_class));
300 }
301
302 int bt_ctf_clock_class_set_description(
303 struct bt_ctf_clock_class *clock_class,
304 const char *desc)
305 {
306 return bt_clock_class_set_description(BT_TO_COMMON(clock_class), desc);
307 }
308
309 uint64_t bt_ctf_clock_class_get_frequency(
310 struct bt_ctf_clock_class *clock_class)
311 {
312 return bt_clock_class_get_frequency(BT_TO_COMMON(clock_class));
313 }
314
315 int bt_ctf_clock_class_set_frequency(
316 struct bt_ctf_clock_class *clock_class, uint64_t freq)
317 {
318 return bt_clock_class_set_frequency(BT_TO_COMMON(clock_class), freq);
319 }
320
321 uint64_t bt_ctf_clock_class_get_precision(
322 struct bt_ctf_clock_class *clock_class)
323 {
324 return bt_clock_class_get_precision(BT_TO_COMMON(clock_class));
325 }
326
327 int bt_ctf_clock_class_set_precision(
328 struct bt_ctf_clock_class *clock_class, uint64_t precision)
329 {
330 return bt_clock_class_set_precision(BT_TO_COMMON(clock_class),
331 precision);
332 }
333
334 int bt_ctf_clock_class_get_offset_s(
335 struct bt_ctf_clock_class *clock_class, int64_t *seconds)
336 {
337 return bt_clock_class_get_offset_s(BT_TO_COMMON(clock_class), seconds);
338 }
339
340 int bt_ctf_clock_class_set_offset_s(
341 struct bt_ctf_clock_class *clock_class, int64_t seconds)
342 {
343 return bt_clock_class_set_offset_s(BT_TO_COMMON(clock_class), seconds);
344 }
345
346 int bt_ctf_clock_class_get_offset_cycles(
347 struct bt_ctf_clock_class *clock_class, int64_t *cycles)
348 {
349 return bt_clock_class_get_offset_cycles(BT_TO_COMMON(clock_class),
350 cycles);
351 }
352
353 int bt_ctf_clock_class_set_offset_cycles(
354 struct bt_ctf_clock_class *clock_class, int64_t cycles)
355 {
356 return bt_clock_class_set_offset_cycles(BT_TO_COMMON(clock_class),
357 cycles);
358 }
359
360 bt_bool bt_ctf_clock_class_is_absolute(
361 struct bt_ctf_clock_class *clock_class)
362 {
363 return bt_clock_class_is_absolute(BT_TO_COMMON(clock_class));
364 }
365
366 int bt_ctf_clock_class_set_is_absolute(
367 struct bt_ctf_clock_class *clock_class, bt_bool is_absolute)
368 {
369 return bt_clock_class_set_is_absolute(BT_TO_COMMON(clock_class),
370 is_absolute);
371 }
372
373 const unsigned char *bt_ctf_clock_class_get_uuid(
374 struct bt_ctf_clock_class *clock_class)
375 {
376 return bt_clock_class_get_uuid(BT_TO_COMMON(clock_class));
377 }
378
379 int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class *clock_class,
380 const unsigned char *uuid)
381 {
382 return bt_clock_class_set_uuid(BT_TO_COMMON(clock_class), uuid);
383 }
This page took 0.036418 seconds and 4 git commands to generate.