2 * SPDX-License-Identifier: MIT
4 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
5 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
8 #define BT_LOG_TAG "LIB/STREAM"
9 #include "lib/logging.h"
11 #include "lib/assert-cond.h"
12 #include <babeltrace2/trace-ir/stream.h>
13 #include <babeltrace2/trace-ir/stream-class.h>
14 #include <babeltrace2/trace-ir/trace.h>
15 #include "compat/compiler.h"
16 #include "common/align.h"
17 #include "common/assert.h"
18 #include "lib/property.h"
24 #include "stream-class.h"
27 #include "lib/value.h"
28 #include "lib/func-status.h"
30 #define BT_ASSERT_PRE_DEV_STREAM_HOT(_stream) \
31 BT_ASSERT_PRE_DEV_HOT((_stream), "Stream", ": %!+s", (_stream))
34 void destroy_stream(struct bt_object
*obj
)
36 struct bt_stream
*stream
= (void *) obj
;
38 BT_LIB_LOGD("Destroying stream object: %!+s", stream
);
39 BT_OBJECT_PUT_REF_AND_RESET(stream
->user_attributes
);
41 if (stream
->name
.str
) {
42 g_string_free(stream
->name
.str
, TRUE
);
43 stream
->name
.str
= NULL
;
44 stream
->name
.value
= NULL
;
47 BT_LOGD_STR("Putting stream's class.");
48 bt_object_put_ref(stream
->class);
49 bt_object_pool_finalize(&stream
->packet_pool
);
54 void bt_stream_free_packet(struct bt_packet
*packet
, struct bt_stream
*stream
)
56 bt_packet_destroy(packet
);
60 bool stream_id_is_unique(struct bt_trace
*trace
,
61 struct bt_stream_class
*stream_class
, uint64_t id
)
64 bool is_unique
= true;
66 for (i
= 0; i
< trace
->streams
->len
; i
++) {
67 struct bt_stream
*stream
= trace
->streams
->pdata
[i
];
69 if (stream
->class != stream_class
) {
73 if (stream
->id
== id
) {
84 struct bt_stream
*create_stream_with_id(struct bt_stream_class
*stream_class
,
85 struct bt_trace
*trace
, uint64_t id
)
88 struct bt_stream
*stream
;
90 BT_ASSERT(stream_class
);
92 BT_ASSERT_PRE(trace
->class ==
93 bt_stream_class_borrow_trace_class_inline(stream_class
),
94 "Trace's class is different from stream class's parent trace class: "
95 "%![sc-]+S, %![trace-]+t", stream_class
, trace
);
96 BT_ASSERT_PRE(stream_id_is_unique(trace
, stream_class
, id
),
97 "Duplicate stream ID: %![trace-]+t, id=%" PRIu64
, trace
, id
);
98 BT_LIB_LOGD("Creating stream object: %![trace-]+t, id=%" PRIu64
,
100 stream
= g_new0(struct bt_stream
, 1);
102 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one stream.");
106 bt_object_init_shared_with_parent(&stream
->base
, destroy_stream
);
107 stream
->user_attributes
= bt_value_map_create();
108 if (!stream
->user_attributes
) {
109 BT_LIB_LOGE_APPEND_CAUSE(
110 "Failed to create a map value object.");
114 stream
->name
.str
= g_string_new(NULL
);
115 if (!stream
->name
.str
) {
116 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
121 ret
= bt_object_pool_initialize(&stream
->packet_pool
,
122 (bt_object_pool_new_object_func
) bt_packet_new
,
123 (bt_object_pool_destroy_object_func
) bt_stream_free_packet
,
126 BT_LIB_LOGE_APPEND_CAUSE(
127 "Failed to initialize packet pool: ret=%d", ret
);
131 stream
->class = stream_class
;
132 bt_object_get_ref_no_null_check(stream_class
);
134 /* bt_trace_add_stream() sets the parent trace, and freezes the trace */
135 bt_trace_add_stream(trace
, stream
);
137 bt_stream_class_freeze(stream_class
);
138 BT_LIB_LOGD("Created stream object: %!+s", stream
);
142 BT_OBJECT_PUT_REF_AND_RESET(stream
);
148 struct bt_stream
*bt_stream_create(struct bt_stream_class
*stream_class
,
149 struct bt_trace
*trace
)
153 BT_ASSERT_PRE_NO_ERROR();
154 BT_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
155 BT_ASSERT_PRE_NON_NULL(trace
, "Trace");
156 BT_ASSERT_PRE(stream_class
->assigns_automatic_stream_id
,
157 "Stream class does not automatically assigns stream IDs: "
158 "%![sc-]+S", stream_class
);
159 id
= bt_trace_get_automatic_stream_id(trace
, stream_class
);
160 return create_stream_with_id(stream_class
, trace
, id
);
163 struct bt_stream
*bt_stream_create_with_id(struct bt_stream_class
*stream_class
,
164 struct bt_trace
*trace
, uint64_t id
)
166 BT_ASSERT_PRE_NO_ERROR();
167 BT_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
168 BT_ASSERT_PRE_NON_NULL(trace
, "Trace");
169 BT_ASSERT_PRE(!stream_class
->assigns_automatic_stream_id
,
170 "Stream class automatically assigns stream IDs: "
171 "%![sc-]+S", stream_class
);
172 return create_stream_with_id(stream_class
, trace
, id
);
175 struct bt_stream_class
*bt_stream_borrow_class(struct bt_stream
*stream
)
177 BT_ASSERT_PRE_DEV_NON_NULL(stream
, "Stream");
178 return stream
->class;
181 const struct bt_stream_class
*bt_stream_borrow_class_const(
182 const struct bt_stream
*stream
)
184 return bt_stream_borrow_class((void *) stream
);
187 struct bt_trace
*bt_stream_borrow_trace(struct bt_stream
*stream
)
189 BT_ASSERT_PRE_DEV_NON_NULL(stream
, "Stream");
190 return bt_stream_borrow_trace_inline(stream
);
193 const struct bt_trace
*bt_stream_borrow_trace_const(
194 const struct bt_stream
*stream
)
196 return bt_stream_borrow_trace((void *) stream
);
199 const char *bt_stream_get_name(const struct bt_stream
*stream
)
201 BT_ASSERT_PRE_DEV_NON_NULL(stream
, "Stream");
202 return stream
->name
.value
;
205 enum bt_stream_set_name_status
bt_stream_set_name(struct bt_stream
*stream
,
208 BT_ASSERT_PRE_NO_ERROR();
209 BT_ASSERT_PRE_NON_NULL(stream
, "Stream");
210 BT_ASSERT_PRE_NON_NULL(name
, "Name");
211 BT_ASSERT_PRE_DEV_STREAM_HOT(stream
);
212 g_string_assign(stream
->name
.str
, name
);
213 stream
->name
.value
= stream
->name
.str
->str
;
214 BT_LIB_LOGD("Set stream's name: %!+s", stream
);
215 return BT_FUNC_STATUS_OK
;
218 uint64_t bt_stream_get_id(const struct bt_stream
*stream
)
220 BT_ASSERT_PRE_DEV_NON_NULL(stream
, "Stream class");
225 void _bt_stream_freeze(const struct bt_stream
*stream
)
228 BT_LIB_LOGD("Freezing stream's user attributes: %!+v",
229 stream
->user_attributes
);
230 bt_value_freeze(stream
->user_attributes
);
231 BT_LIB_LOGD("Freezing stream: %!+s", stream
);
232 ((struct bt_stream
*) stream
)->frozen
= true;
235 const struct bt_value
*bt_stream_borrow_user_attributes_const(
236 const struct bt_stream
*stream
)
238 BT_ASSERT_PRE_DEV_NON_NULL(stream
, "Stream");
239 return stream
->user_attributes
;
242 struct bt_value
*bt_stream_borrow_user_attributes(struct bt_stream
*stream
)
244 return (void *) bt_stream_borrow_user_attributes_const((void *) stream
);
247 void bt_stream_set_user_attributes(struct bt_stream
*stream
,
248 const struct bt_value
*user_attributes
)
250 BT_ASSERT_PRE_NON_NULL(stream
, "Stream");
251 BT_ASSERT_PRE_NON_NULL(user_attributes
, "User attributes");
252 BT_ASSERT_PRE(user_attributes
->type
== BT_VALUE_TYPE_MAP
,
253 "User attributes object is not a map value object.");
254 BT_ASSERT_PRE_DEV_STREAM_HOT(stream
);
255 bt_object_put_ref_no_null_check(stream
->user_attributes
);
256 stream
->user_attributes
= (void *) user_attributes
;
257 bt_object_get_ref_no_null_check(stream
->user_attributes
);
260 void bt_stream_get_ref(const struct bt_stream
*stream
)
262 bt_object_get_ref(stream
);
265 void bt_stream_put_ref(const struct bt_stream
*stream
)
267 bt_object_put_ref(stream
);