lib: merge common CTF IR part with the remaining implementation
[babeltrace.git] / lib / ctf-ir / stream.c
1 /*
2 * stream.c
3 *
4 * Babeltrace CTF IR - Stream
5 *
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
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
29 #define BT_LOG_TAG "STREAM"
30 #include <babeltrace/lib-logging-internal.h>
31
32 #include <babeltrace/assert-pre-internal.h>
33 #include <babeltrace/ctf-ir/stream.h>
34 #include <babeltrace/ctf-ir/stream-internal.h>
35 #include <babeltrace/ctf-ir/stream-class.h>
36 #include <babeltrace/ctf-ir/stream-class-internal.h>
37 #include <babeltrace/ctf-ir/trace.h>
38 #include <babeltrace/ctf-ir/trace-internal.h>
39 #include <babeltrace/ctf-ir/packet-internal.h>
40 #include <babeltrace/ref.h>
41 #include <babeltrace/compiler-internal.h>
42 #include <babeltrace/align-internal.h>
43 #include <babeltrace/assert-internal.h>
44 #include <inttypes.h>
45 #include <unistd.h>
46
47 static inline
48 void bt_stream_finalize(struct bt_stream *stream)
49 {
50 BT_LOGD("Finalizing stream object: addr=%p, name=\"%s\"",
51 stream, bt_stream_get_name(stream));
52
53 if (stream->name) {
54 g_string_free(stream->name, TRUE);
55 }
56 }
57
58 static
59 void bt_stream_destroy(struct bt_object *obj)
60 {
61 struct bt_stream *stream = (void *) obj;
62
63 BT_LOGD("Destroying stream object: addr=%p, name=\"%s\"",
64 stream, bt_stream_get_name(stream));
65 bt_object_pool_finalize(&stream->packet_pool);
66 bt_stream_finalize((void *) obj);
67 g_free(stream);
68 }
69
70 static inline
71 int bt_stream_initialize(
72 struct bt_stream *stream,
73 struct bt_stream_class *stream_class, const char *name,
74 uint64_t id, bt_object_release_func release_func)
75 {
76 int ret = 0;
77 struct bt_trace *trace = NULL;
78
79 bt_object_init_shared_with_parent(&stream->base, release_func);
80
81 if (!stream_class) {
82 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
83 goto error;
84 }
85
86 BT_LOGD("Initializing stream object: stream-class-addr=%p, "
87 "stream-class-name=\"%s\", stream-name=\"%s\", "
88 "stream-id=%" PRIu64,
89 stream_class, bt_stream_class_get_name(stream_class),
90 name, id);
91 trace = bt_stream_class_borrow_trace(stream_class);
92 if (!trace) {
93 BT_LOGW("Invalid parameter: cannot create stream from a stream class which is not part of trace: "
94 "stream-class-addr=%p, stream-class-name=\"%s\", "
95 "stream-name=\"%s\"",
96 stream_class,
97 bt_stream_class_get_name(stream_class), name);
98 goto error;
99 }
100
101 if (id != -1ULL) {
102 /*
103 * Validate that the given ID is unique amongst all the
104 * existing trace's streams created from the same stream
105 * class.
106 */
107 size_t i;
108
109 for (i = 0; i < trace->streams->len; i++) {
110 struct bt_stream *trace_stream =
111 g_ptr_array_index(trace->streams, i);
112
113 if (trace_stream->stream_class != (void *) stream_class) {
114 continue;
115 }
116
117 if (trace_stream->id == id) {
118 BT_LOGW_STR("Invalid parameter: another stream in the same trace already has this ID.");
119 goto error;
120 }
121 }
122 }
123
124 /*
125 * Acquire reference to parent since stream will become publicly
126 * reachable; it needs its parent to remain valid.
127 */
128 bt_object_set_parent(&stream->base, &trace->base);
129 stream->stream_class = stream_class;
130 stream->id = (int64_t) id;
131
132 if (name) {
133 stream->name = g_string_new(name);
134 if (!stream->name) {
135 BT_LOGE_STR("Failed to allocate a GString.");
136 goto error;
137 }
138 }
139
140 BT_LOGD("Set stream's trace parent: trace-addr=%p", trace);
141
142 /* Add this stream to the trace's streams */
143 BT_LOGD("Created stream object: addr=%p", stream);
144 goto end;
145
146 error:
147 ret = -1;
148
149 end:
150 return ret;
151 }
152
153 static
154 void bt_stream_free_packet(struct bt_packet *packet, struct bt_stream *stream)
155 {
156 bt_packet_destroy(packet);
157 }
158
159 static
160 struct bt_stream *bt_stream_create_with_id_no_check(
161 struct bt_stream_class *stream_class,
162 const char *name, uint64_t id)
163 {
164 int ret;
165 struct bt_stream *stream = NULL;
166 struct bt_trace *trace = NULL;
167
168 BT_LOGD("Creating stream object: stream-class-addr=%p, "
169 "stream-class-name=\"%s\", stream-name=\"%s\", "
170 "stream-id=%" PRIu64,
171 stream_class, bt_stream_class_get_name(stream_class),
172 name, id);
173
174 trace = bt_stream_class_borrow_trace(stream_class);
175 if (!trace) {
176 BT_LOGW("Invalid parameter: cannot create stream from a stream class which is not part of trace: "
177 "stream-class-addr=%p, stream-class-name=\"%s\", "
178 "stream-name=\"%s\"",
179 stream_class, bt_stream_class_get_name(stream_class),
180 name);
181 goto error;
182 }
183
184 if (bt_trace_is_static(trace)) {
185 /*
186 * A static trace has the property that all its stream
187 * classes, clock classes, and streams are definitive:
188 * no more can be added, and each object is also frozen.
189 */
190 BT_LOGW("Invalid parameter: cannot create stream from a stream class which is part of a static trace: "
191 "stream-class-addr=%p, stream-class-name=\"%s\", "
192 "stream-name=\"%s\", trace-addr=%p",
193 stream_class, bt_stream_class_get_name(stream_class),
194 name, trace);
195 goto error;
196 }
197
198 stream = g_new0(struct bt_stream, 1);
199 if (!stream) {
200 BT_LOGE_STR("Failed to allocate one stream.");
201 goto error;
202 }
203
204 ret = bt_stream_initialize(stream, stream_class, name,
205 id, bt_stream_destroy);
206 if (ret) {
207 /* bt_stream_initialize() logs errors */
208 goto error;
209 }
210
211 ret = bt_object_pool_initialize(&stream->packet_pool,
212 (bt_object_pool_new_object_func) bt_packet_new,
213 (bt_object_pool_destroy_object_func) bt_stream_free_packet,
214 stream);
215 if (ret) {
216 BT_LOGE("Failed to initialize packet pool: ret=%d", ret);
217 goto error;
218 }
219
220 g_ptr_array_add(trace->streams, stream);
221 BT_LOGD("Created stream object: addr=%p", stream);
222 goto end;
223
224 error:
225 BT_PUT(stream);
226
227 end:
228 return stream;
229 }
230
231 struct bt_stream *bt_stream_create(struct bt_stream_class *stream_class,
232 const char *name, uint64_t id_param)
233 {
234 struct bt_stream *stream = NULL;
235 int64_t id = (int64_t) id_param;
236
237 if (!stream_class) {
238 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
239 goto end;
240 }
241
242 if (id < 0) {
243 BT_LOGW("Invalid parameter: invalid stream's ID: "
244 "name=\"%s\", id=%" PRIu64,
245 name, id_param);
246 goto end;
247 }
248
249 stream = bt_stream_create_with_id_no_check(stream_class,
250 name, id_param);
251
252 end:
253 return stream;
254 }
255
256 struct bt_stream_class *bt_stream_borrow_class(struct bt_stream *stream)
257 {
258 BT_ASSERT(stream);
259 return stream->stream_class;
260 }
261
262 const char *bt_stream_get_name(struct bt_stream *stream)
263 {
264 BT_ASSERT_PRE_NON_NULL(stream, "Stream");
265 return stream->name ? stream->name->str : NULL;
266 }
267
268 int64_t bt_stream_get_id(struct bt_stream *stream)
269 {
270 int64_t ret;
271
272 BT_ASSERT_PRE_NON_NULL(stream, "Stream");
273 ret = stream->id;
274 if (ret < 0) {
275 BT_LOGV("Stream's ID is not set: addr=%p, name=\"%s\"",
276 stream, bt_stream_get_name(stream));
277 }
278
279 return ret;
280 }
This page took 0.035197 seconds and 4 git commands to generate.