Move to kernel style SPDX license identifiers
[babeltrace.git] / src / lib / trace-ir / trace.c
CommitLineData
bc37ae52 1/*
0235b0db
MJ
2 * SPDX-License-Identifier: MIT
3 *
e2f7325d 4 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
bc37ae52 5 * Copyright 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
bc37ae52
JG
6 */
7
350ad6c1 8#define BT_LOG_TAG "LIB/TRACE"
c2d9d9cf 9#include "lib/logging.h"
e011d2c1 10
578e048b 11#include "lib/assert-pre.h"
3c634c85 12#include "lib/assert-post.h"
3fadfbc0 13#include <babeltrace2/trace-ir/trace.h>
3fadfbc0 14#include <babeltrace2/trace-ir/event-class.h>
578e048b
MJ
15#include "ctf-writer/functor.h"
16#include "ctf-writer/clock.h"
17#include "compat/compiler.h"
3fadfbc0 18#include <babeltrace2/value.h>
578e048b 19#include "lib/value.h"
3fadfbc0 20#include <babeltrace2/types.h>
578e048b
MJ
21#include "compat/endian.h"
22#include "common/assert.h"
23#include "compat/glib.h"
dc3fffef 24#include <inttypes.h>
544d0515 25#include <stdint.h>
4a32fda0 26#include <string.h>
c4f23e30 27#include <stdbool.h>
0fbb9a9f 28#include <stdlib.h>
bc37ae52 29
578e048b
MJ
30#include "attributes.h"
31#include "clock-class.h"
32#include "event-class.h"
33#include "event.h"
34#include "field-class.h"
35#include "field-wrapper.h"
36#include "resolve-field-path.h"
37#include "stream-class.h"
38#include "stream.h"
39#include "trace-class.h"
40#include "trace.h"
41#include "utils.h"
c6962c96 42#include "lib/value.h"
d24d5663 43#include "lib/func-status.h"
578e048b 44
ad5268b5
FD
45struct bt_trace_destruction_listener_elem {
46 bt_trace_destruction_listener_func func;
3602afb0
PP
47 void *data;
48};
49
bdb288b3
PP
50#define BT_ASSERT_PRE_DEV_TRACE_HOT(_trace) \
51 BT_ASSERT_PRE_DEV_HOT((_trace), "Trace", ": %!+t", (_trace))
cb6f1f7d 52
bc37ae52 53static
44c440bc 54void destroy_trace(struct bt_object *obj)
3dca2276
PP
55{
56 struct bt_trace *trace = (void *) obj;
bc37ae52 57
44c440bc 58 BT_LIB_LOGD("Destroying trace object: %!+t", trace);
c6962c96 59 BT_OBJECT_PUT_REF_AND_RESET(trace->user_attributes);
bc37ae52 60
3dca2276 61 /*
ad5268b5
FD
62 * Call destruction listener functions so that everything else
63 * still exists in the trace.
3dca2276 64 */
ad5268b5
FD
65 if (trace->destruction_listeners) {
66 uint64_t i;
42a63165
SM
67 const struct bt_error *saved_error;
68
3f7d4d90 69 BT_LIB_LOGD("Calling trace destruction listener(s): %!+t", trace);
c47a6bec
SM
70
71 /*
72 * The trace's reference count is 0 if we're here. Increment
73 * it to avoid a double-destroy (possibly infinitely recursive).
74 * This could happen for example if a destruction listener did
75 * bt_object_get_ref() (or anything that causes
76 * bt_object_get_ref() to be called) on the trace (ref.
77 * count goes from 0 to 1), and then bt_object_put_ref(): the
78 * reference count would go from 1 to 0 again and this function
79 * would be called again.
80 */
81 trace->base.ref_count++;
82
42a63165
SM
83 saved_error = bt_current_thread_take_error();
84
ad5268b5
FD
85 /* Call all the trace destruction listeners */
86 for (i = 0; i < trace->destruction_listeners->len; i++) {
87 struct bt_trace_destruction_listener_elem elem =
88 g_array_index(trace->destruction_listeners,
89 struct bt_trace_destruction_listener_elem, i);
90
91 if (elem.func) {
92 elem.func(trace, elem.data);
6ecdcca3 93 BT_ASSERT_POST_NO_ERROR();
3dca2276 94 }
c47a6bec
SM
95
96 /*
97 * The destruction listener should not have kept a
98 * reference to the trace.
99 */
3c634c85 100 BT_ASSERT_POST(trace->base.ref_count == 1, "Destruction listener kept a reference to the trace being destroyed: %![trace-]+t", trace);
3dca2276 101 }
ad5268b5
FD
102 g_array_free(trace->destruction_listeners, TRUE);
103 trace->destruction_listeners = NULL;
42a63165
SM
104
105 if (saved_error) {
106 BT_CURRENT_THREAD_MOVE_ERROR_AND_RESET(saved_error);
107 }
bc37ae52
JG
108 }
109
44c440bc
PP
110 if (trace->name.str) {
111 g_string_free(trace->name.str, TRUE);
238b7404
PP
112 trace->name.str = NULL;
113 trace->name.value = NULL;
95c09b3a
PP
114 }
115
335a2da5
PP
116 if (trace->environment) {
117 BT_LOGD_STR("Destroying environment attributes.");
118 bt_attributes_destroy(trace->environment);
119 trace->environment = NULL;
120 }
121
44c440bc
PP
122 if (trace->streams) {
123 BT_LOGD_STR("Destroying streams.");
124 g_ptr_array_free(trace->streams, TRUE);
238b7404 125 trace->streams = NULL;
bc37ae52
JG
126 }
127
44c440bc
PP
128 if (trace->stream_classes_stream_count) {
129 g_hash_table_destroy(trace->stream_classes_stream_count);
238b7404 130 trace->stream_classes_stream_count = NULL;
44c440bc 131 }
3dca2276 132
862ca4ed
PP
133 BT_LOGD_STR("Putting trace's class.");
134 bt_object_put_ref(trace->class);
135 trace->class = NULL;
44c440bc 136 g_free(trace);
3dca2276
PP
137}
138
862ca4ed 139struct bt_trace *bt_trace_create(struct bt_trace_class *tc)
3dca2276
PP
140{
141 struct bt_trace *trace = NULL;
3dca2276 142
17f3083a
SM
143 BT_ASSERT_PRE_NO_ERROR();
144
862ca4ed 145 BT_LIB_LOGD("Creating trace object: %![tc-]+T", tc);
3dca2276
PP
146 trace = g_new0(struct bt_trace, 1);
147 if (!trace) {
870631a2 148 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one trace.");
3dca2276
PP
149 goto error;
150 }
151
862ca4ed 152 bt_object_init_shared(&trace->base, destroy_trace);
c6962c96
PP
153 trace->user_attributes = bt_value_map_create();
154 if (!trace->user_attributes) {
155 BT_LIB_LOGE_APPEND_CAUSE(
156 "Failed to create a map value object.");
157 goto error;
158 }
159
44c440bc
PP
160 trace->streams = g_ptr_array_new_with_free_func(
161 (GDestroyNotify) bt_object_try_spec_release);
162 if (!trace->streams) {
870631a2 163 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one GPtrArray.");
3dca2276
PP
164 goto error;
165 }
166
44c440bc
PP
167 trace->stream_classes_stream_count = g_hash_table_new(g_direct_hash,
168 g_direct_equal);
169 if (!trace->stream_classes_stream_count) {
870631a2 170 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one GHashTable.");
44c440bc
PP
171 goto error;
172 }
173
174 trace->name.str = g_string_new(NULL);
175 if (!trace->name.str) {
870631a2 176 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one GString.");
44c440bc
PP
177 goto error;
178 }
179
335a2da5
PP
180 trace->environment = bt_attributes_create();
181 if (!trace->environment) {
182 BT_LIB_LOGE_APPEND_CAUSE("Cannot create empty attributes object.");
183 goto error;
184 }
185
ad5268b5
FD
186 trace->destruction_listeners = g_array_new(FALSE, TRUE,
187 sizeof(struct bt_trace_destruction_listener_elem));
188 if (!trace->destruction_listeners) {
870631a2 189 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one GArray.");
3602afb0
PP
190 goto error;
191 }
192
862ca4ed 193 trace->class = tc;
6871026b 194 bt_object_get_ref_no_null_check(trace->class);
44c440bc
PP
195 BT_LIB_LOGD("Created trace object: %!+t", trace);
196 goto end;
bc37ae52 197
bc37ae52 198error:
65300d60 199 BT_OBJECT_PUT_REF_AND_RESET(trace);
44c440bc
PP
200
201end:
862ca4ed 202 return trace;
bc37ae52
JG
203}
204
40f4ba76 205const char *bt_trace_get_name(const struct bt_trace *trace)
e96045d4 206{
bdb288b3 207 BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace");
44c440bc 208 return trace->name.value;
e96045d4
JG
209}
210
d24d5663
PP
211enum bt_trace_set_name_status bt_trace_set_name(struct bt_trace *trace,
212 const char *name)
e96045d4 213{
17f3083a 214 BT_ASSERT_PRE_NO_ERROR();
44c440bc
PP
215 BT_ASSERT_PRE_NON_NULL(trace, "Trace");
216 BT_ASSERT_PRE_NON_NULL(name, "Name");
bdb288b3 217 BT_ASSERT_PRE_DEV_TRACE_HOT(trace);
44c440bc
PP
218 g_string_assign(trace->name.str, name);
219 trace->name.value = trace->name.str->str;
3f7d4d90 220 BT_LIB_LOGD("Set trace's name: %!+t", trace);
d24d5663 221 return BT_FUNC_STATUS_OK;
e96045d4
JG
222}
223
335a2da5
PP
224bt_uuid bt_trace_get_uuid(const struct bt_trace *trace)
225{
bdb288b3 226 BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace");
335a2da5
PP
227 return trace->uuid.value;
228}
229
230void bt_trace_set_uuid(struct bt_trace *trace, bt_uuid uuid)
231{
232 BT_ASSERT_PRE_NON_NULL(trace, "Trace");
233 BT_ASSERT_PRE_NON_NULL(uuid, "UUID");
bdb288b3 234 BT_ASSERT_PRE_DEV_TRACE_HOT(trace);
6162e6b7 235 bt_uuid_copy(trace->uuid.uuid, uuid);
335a2da5
PP
236 trace->uuid.value = trace->uuid.uuid;
237 BT_LIB_LOGD("Set trace's UUID: %!+t", trace);
238}
239
335a2da5
PP
240static
241bool trace_has_environment_entry(const struct bt_trace *trace, const char *name)
242{
243 BT_ASSERT(trace);
244
245 return bt_attributes_borrow_field_value_by_name(
5084732e 246 trace->environment, name);
335a2da5
PP
247}
248
249static
250enum bt_trace_set_environment_entry_status set_environment_entry(
251 struct bt_trace *trace,
252 const char *name, struct bt_value *value)
253{
254 int ret;
255
256 BT_ASSERT(trace);
257 BT_ASSERT(name);
258 BT_ASSERT(value);
259 BT_ASSERT_PRE(!trace->frozen ||
260 !trace_has_environment_entry(trace, name),
261 "Trace is frozen: cannot replace environment entry: "
262 "%![trace-]+t, entry-name=\"%s\"", trace, name);
263 ret = bt_attributes_set_field_value(trace->environment, name,
264 value);
265 if (ret) {
266 ret = BT_FUNC_STATUS_MEMORY_ERROR;
267 BT_LIB_LOGE_APPEND_CAUSE(
268 "Cannot set trace's environment entry: "
269 "%![trace-]+t, entry-name=\"%s\"", trace, name);
270 } else {
271 bt_value_freeze(value);
272 BT_LIB_LOGD("Set trace's environment entry: "
273 "%![trace-]+t, entry-name=\"%s\"", trace, name);
274 }
275
276 return ret;
277}
278
279enum bt_trace_set_environment_entry_status
280bt_trace_set_environment_entry_string(
281 struct bt_trace *trace, const char *name, const char *value)
282{
283 int ret;
284 struct bt_value *value_obj;
17f3083a
SM
285
286 BT_ASSERT_PRE_NO_ERROR();
335a2da5
PP
287 BT_ASSERT_PRE_NON_NULL(trace, "Trace");
288 BT_ASSERT_PRE_NON_NULL(name, "Name");
289 BT_ASSERT_PRE_NON_NULL(value, "Value");
17f3083a 290
335a2da5
PP
291 value_obj = bt_value_string_create_init(value);
292 if (!value_obj) {
293 BT_LIB_LOGE_APPEND_CAUSE(
294 "Cannot create a string value object.");
295 ret = -1;
296 goto end;
297 }
298
299 /* set_environment_entry() logs errors */
300 ret = set_environment_entry(trace, name, value_obj);
301
302end:
303 bt_object_put_ref(value_obj);
304 return ret;
305}
306
307enum bt_trace_set_environment_entry_status
308bt_trace_set_environment_entry_integer(
309 struct bt_trace *trace, const char *name, int64_t value)
310{
311 int ret;
312 struct bt_value *value_obj;
17f3083a
SM
313
314 BT_ASSERT_PRE_NO_ERROR();
335a2da5
PP
315 BT_ASSERT_PRE_NON_NULL(trace, "Trace");
316 BT_ASSERT_PRE_NON_NULL(name, "Name");
17f3083a 317
9c08c816 318 value_obj = bt_value_integer_signed_create_init(value);
335a2da5
PP
319 if (!value_obj) {
320 BT_LIB_LOGE_APPEND_CAUSE(
321 "Cannot create an integer value object.");
322 ret = BT_FUNC_STATUS_MEMORY_ERROR;
323 goto end;
324 }
325
326 /* set_environment_entry() logs errors */
327 ret = set_environment_entry(trace, name, value_obj);
328
329end:
330 bt_object_put_ref(value_obj);
331 return ret;
332}
333
334uint64_t bt_trace_get_environment_entry_count(const struct bt_trace *trace)
335{
bdb288b3 336 BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace");
99b4b64b 337 return bt_attributes_get_count(trace->environment);
335a2da5
PP
338}
339
340void bt_trace_borrow_environment_entry_by_index_const(
341 const struct bt_trace *trace, uint64_t index,
342 const char **name, const struct bt_value **value)
343{
bdb288b3
PP
344 BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace");
345 BT_ASSERT_PRE_DEV_NON_NULL(name, "Name");
346 BT_ASSERT_PRE_DEV_NON_NULL(value, "Value");
347 BT_ASSERT_PRE_DEV_VALID_INDEX(index,
335a2da5
PP
348 bt_attributes_get_count(trace->environment));
349 *value = bt_attributes_borrow_field_value(trace->environment, index);
350 BT_ASSERT(*value);
351 *name = bt_attributes_get_field_name(trace->environment, index);
352 BT_ASSERT(*name);
353}
354
355const struct bt_value *bt_trace_borrow_environment_entry_value_by_name_const(
356 const struct bt_trace *trace, const char *name)
357{
bdb288b3
PP
358 BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace");
359 BT_ASSERT_PRE_DEV_NON_NULL(name, "Name");
335a2da5
PP
360 return bt_attributes_borrow_field_value_by_name(trace->environment,
361 name);
362}
363
40f4ba76 364uint64_t bt_trace_get_stream_count(const struct bt_trace *trace)
bc37ae52 365{
bdb288b3 366 BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace");
44c440bc
PP
367 return (uint64_t) trace->streams->len;
368}
95c09b3a 369
44c440bc
PP
370struct bt_stream *bt_trace_borrow_stream_by_index(
371 struct bt_trace *trace, uint64_t index)
372{
bdb288b3
PP
373 BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace");
374 BT_ASSERT_PRE_DEV_VALID_INDEX(index, trace->streams->len);
44c440bc
PP
375 return g_ptr_array_index(trace->streams, index);
376}
cb6f1f7d 377
40f4ba76
PP
378const struct bt_stream *bt_trace_borrow_stream_by_index_const(
379 const struct bt_trace *trace, uint64_t index)
e5be10ef 380{
40f4ba76 381 return bt_trace_borrow_stream_by_index((void *) trace, index);
e5be10ef
PP
382}
383
40f4ba76
PP
384struct bt_stream *bt_trace_borrow_stream_by_id(struct bt_trace *trace,
385 uint64_t id)
44c440bc
PP
386{
387 struct bt_stream *stream = NULL;
388 uint64_t i;
bc37ae52 389
bdb288b3 390 BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace");
bc37ae52 391
44c440bc
PP
392 for (i = 0; i < trace->streams->len; i++) {
393 struct bt_stream *stream_candidate =
394 g_ptr_array_index(trace->streams, i);
cfeb617e 395
44c440bc
PP
396 if (stream_candidate->id == id) {
397 stream = stream_candidate;
398 goto end;
399 }
6474e016 400 }
95c09b3a 401
bc37ae52 402end:
44c440bc 403 return stream;
bc37ae52
JG
404}
405
40f4ba76
PP
406const struct bt_stream *bt_trace_borrow_stream_by_id_const(
407 const struct bt_trace *trace, uint64_t id)
e5be10ef 408{
40f4ba76 409 return bt_trace_borrow_stream_by_id((void *) trace, id);
e5be10ef
PP
410}
411
d24d5663 412enum bt_trace_add_listener_status bt_trace_add_destruction_listener(
40f4ba76 413 const struct bt_trace *c_trace,
ad5268b5 414 bt_trace_destruction_listener_func listener,
2054a0d1 415 void *data, bt_listener_id *listener_id)
3602afb0 416{
40f4ba76 417 struct bt_trace *trace = (void *) c_trace;
44c440bc 418 uint64_t i;
ad5268b5 419 struct bt_trace_destruction_listener_elem new_elem = {
3602afb0
PP
420 .func = listener,
421 .data = data,
422 };
423
17f3083a 424 BT_ASSERT_PRE_NO_ERROR();
44c440bc
PP
425 BT_ASSERT_PRE_NON_NULL(trace, "Trace");
426 BT_ASSERT_PRE_NON_NULL(listener, "Listener");
8480c8cc 427
3602afb0 428 /* Find the next available spot */
ad5268b5
FD
429 for (i = 0; i < trace->destruction_listeners->len; i++) {
430 struct bt_trace_destruction_listener_elem elem =
431 g_array_index(trace->destruction_listeners,
432 struct bt_trace_destruction_listener_elem, i);
3602afb0
PP
433
434 if (!elem.func) {
435 break;
436 }
437 }
438
ad5268b5
FD
439 if (i == trace->destruction_listeners->len) {
440 g_array_append_val(trace->destruction_listeners, new_elem);
3602afb0 441 } else {
ad5268b5 442 g_array_insert_val(trace->destruction_listeners, i, new_elem);
3602afb0
PP
443 }
444
44c440bc
PP
445 if (listener_id) {
446 *listener_id = i;
447 }
3602afb0 448
3f7d4d90 449 BT_LIB_LOGD("Added destruction listener: " "%![trace-]+t, "
ad5268b5 450 "listener-id=%" PRIu64, trace, i);
d24d5663 451 return BT_FUNC_STATUS_OK;
44c440bc
PP
452}
453
44c440bc 454static
40f4ba76 455bool has_listener_id(const struct bt_trace *trace, uint64_t listener_id)
44c440bc 456{
ad5268b5
FD
457 BT_ASSERT(listener_id < trace->destruction_listeners->len);
458 return (&g_array_index(trace->destruction_listeners,
459 struct bt_trace_destruction_listener_elem,
5084732e 460 listener_id))->func;
3602afb0
PP
461}
462
d24d5663 463enum bt_trace_remove_listener_status bt_trace_remove_destruction_listener(
2054a0d1 464 const struct bt_trace *c_trace, bt_listener_id listener_id)
3602afb0 465{
40f4ba76 466 struct bt_trace *trace = (void *) c_trace;
ad5268b5 467 struct bt_trace_destruction_listener_elem *elem;
3602afb0 468
17f3083a 469 BT_ASSERT_PRE_NO_ERROR();
44c440bc 470 BT_ASSERT_PRE_NON_NULL(trace, "Trace");
44c440bc 471 BT_ASSERT_PRE(has_listener_id(trace, listener_id),
ad5268b5 472 "Trace has no such trace destruction listener ID: "
44c440bc 473 "%![trace-]+t, %" PRIu64, trace, listener_id);
ad5268b5
FD
474 elem = &g_array_index(trace->destruction_listeners,
475 struct bt_trace_destruction_listener_elem,
3602afb0 476 listener_id);
44c440bc 477 BT_ASSERT(elem->func);
3602afb0
PP
478
479 elem->func = NULL;
480 elem->data = NULL;
3f7d4d90 481 BT_LIB_LOGD("Removed \"trace destruction listener: "
44c440bc
PP
482 "%![trace-]+t, listener-id=%" PRIu64,
483 trace, listener_id);
d24d5663 484 return BT_FUNC_STATUS_OK;
44c440bc 485}
3602afb0 486
44c440bc 487BT_HIDDEN
40f4ba76 488void _bt_trace_freeze(const struct bt_trace *trace)
44c440bc 489{
44c440bc 490 BT_ASSERT(trace);
862ca4ed
PP
491 BT_LIB_LOGD("Freezing trace's class: %!+T", trace->class);
492 bt_trace_class_freeze(trace->class);
c6962c96
PP
493 BT_LIB_LOGD("Freezing trace's user attributes: %!+v",
494 trace->user_attributes);
495 bt_value_freeze(trace->user_attributes);
44c440bc 496 BT_LIB_LOGD("Freezing trace: %!+t", trace);
40f4ba76 497 ((struct bt_trace *) trace)->frozen = true;
5acf2ae6 498}
312c056a 499
44c440bc
PP
500BT_HIDDEN
501void bt_trace_add_stream(struct bt_trace *trace, struct bt_stream *stream)
502{
503 guint count = 0;
504
505 bt_object_set_parent(&stream->base, &trace->base);
506 g_ptr_array_add(trace->streams, stream);
cb6f1f7d 507 bt_trace_freeze(trace);
312c056a 508
44c440bc
PP
509 if (bt_g_hash_table_contains(trace->stream_classes_stream_count,
510 stream->class)) {
511 count = GPOINTER_TO_UINT(g_hash_table_lookup(
512 trace->stream_classes_stream_count, stream->class));
312c056a
PP
513 }
514
44c440bc
PP
515 g_hash_table_insert(trace->stream_classes_stream_count,
516 stream->class, GUINT_TO_POINTER(count + 1));
517}
518
519BT_HIDDEN
40f4ba76
PP
520uint64_t bt_trace_get_automatic_stream_id(const struct bt_trace *trace,
521 const struct bt_stream_class *stream_class)
44c440bc
PP
522{
523 gpointer orig_key;
524 gpointer value;
525 uint64_t id = 0;
526
527 BT_ASSERT(stream_class);
528 BT_ASSERT(trace);
529 if (g_hash_table_lookup_extended(trace->stream_classes_stream_count,
530 stream_class, &orig_key, &value)) {
531 id = (uint64_t) GPOINTER_TO_UINT(value);
532 }
533
534 return id;
312c056a 535}
862ca4ed
PP
536
537struct bt_trace_class *bt_trace_borrow_class(struct bt_trace *trace)
538{
bdb288b3 539 BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace");
862ca4ed
PP
540 return trace->class;
541}
542
543const struct bt_trace_class *bt_trace_borrow_class_const(
544 const struct bt_trace *trace)
545{
546 return bt_trace_borrow_class((void *) trace);
547}
c5b9b441 548
c6962c96
PP
549const struct bt_value *bt_trace_borrow_user_attributes_const(
550 const struct bt_trace *trace)
551{
552 BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace");
553 return trace->user_attributes;
554}
555
556struct bt_value *bt_trace_borrow_user_attributes(struct bt_trace *trace)
557{
558 return (void *) bt_trace_borrow_user_attributes_const((void *) trace);
559}
560
561void bt_trace_set_user_attributes(
562 struct bt_trace *trace,
563 const struct bt_value *user_attributes)
564{
565 BT_ASSERT_PRE_NON_NULL(trace, "Trace");
566 BT_ASSERT_PRE_NON_NULL(user_attributes, "User attributes");
567 BT_ASSERT_PRE(user_attributes->type == BT_VALUE_TYPE_MAP,
568 "User attributes object is not a map value object.");
569 BT_ASSERT_PRE_DEV_TRACE_HOT(trace);
6871026b 570 bt_object_put_ref_no_null_check(trace->user_attributes);
c6962c96 571 trace->user_attributes = (void *) user_attributes;
6871026b 572 bt_object_get_ref_no_null_check(trace->user_attributes);
c6962c96
PP
573}
574
c5b9b441
PP
575void bt_trace_get_ref(const struct bt_trace *trace)
576{
577 bt_object_get_ref(trace);
578}
579
580void bt_trace_put_ref(const struct bt_trace *trace)
581{
582 bt_object_put_ref(trace);
583}
This page took 0.126816 seconds and 4 git commands to generate.