lib: merge common CTF IR part with the remaining implementation
[babeltrace.git] / lib / ctf-ir / stream.c
CommitLineData
273b65be
JG
1/*
2 * stream.c
3 *
d2dc44b6 4 * Babeltrace CTF IR - Stream
273b65be 5 *
de9dd397 6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
273b65be
JG
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
19abc2c6
PP
29#define BT_LOG_TAG "STREAM"
30#include <babeltrace/lib-logging-internal.h>
31
d975f66c 32#include <babeltrace/assert-pre-internal.h>
3dca2276
PP
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>
312c056a 39#include <babeltrace/ctf-ir/packet-internal.h>
3dca2276
PP
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>
12c8a1a3 46
cb6f1f7d
PP
47static inline
48void bt_stream_finalize(struct bt_stream *stream)
263a7df5 49{
cb6f1f7d
PP
50 BT_LOGD("Finalizing stream object: addr=%p, name=\"%s\"",
51 stream, bt_stream_get_name(stream));
263a7df5 52
3dca2276
PP
53 if (stream->name) {
54 g_string_free(stream->name, TRUE);
b3376dd9 55 }
263a7df5
JG
56}
57
c9af50d1 58static
3dca2276 59void bt_stream_destroy(struct bt_object *obj)
c9af50d1 60{
3dca2276 61 struct bt_stream *stream = (void *) obj;
c9af50d1 62
3dca2276
PP
63 BT_LOGD("Destroying stream object: addr=%p, name=\"%s\"",
64 stream, bt_stream_get_name(stream));
312c056a 65 bt_object_pool_finalize(&stream->packet_pool);
cb6f1f7d 66 bt_stream_finalize((void *) obj);
3dca2276 67 g_free(stream);
c9af50d1
JG
68}
69
cb6f1f7d
PP
70static inline
71int bt_stream_initialize(
72 struct bt_stream *stream,
73 struct bt_stream_class *stream_class, const char *name,
3dca2276 74 uint64_t id, bt_object_release_func release_func)
273b65be
JG
75{
76 int ret = 0;
cb6f1f7d 77 struct bt_trace *trace = NULL;
98edd02c 78
3fea54f6 79 bt_object_init_shared_with_parent(&stream->base, release_func);
273b65be 80
3dca2276
PP
81 if (!stream_class) {
82 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
83 goto error;
b3376dd9 84 }
12c8a1a3 85
cb6f1f7d 86 BT_LOGD("Initializing stream object: stream-class-addr=%p, "
3dca2276
PP
87 "stream-class-name=\"%s\", stream-name=\"%s\", "
88 "stream-id=%" PRIu64,
cb6f1f7d 89 stream_class, bt_stream_class_get_name(stream_class),
3dca2276 90 name, id);
cb6f1f7d 91 trace = bt_stream_class_borrow_trace(stream_class);
3dca2276
PP
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,
cb6f1f7d 97 bt_stream_class_get_name(stream_class), name);
3dca2276 98 goto error;
12c8a1a3
JG
99 }
100
3dca2276
PP
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;
19abc2c6 108
3dca2276 109 for (i = 0; i < trace->streams->len; i++) {
cb6f1f7d 110 struct bt_stream *trace_stream =
3dca2276 111 g_ptr_array_index(trace->streams, i);
273b65be 112
3dca2276
PP
113 if (trace_stream->stream_class != (void *) stream_class) {
114 continue;
06b019a7 115 }
273b65be 116
3dca2276
PP
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;
8bfa3f9c
JG
120 }
121 }
1c1d572f
JD
122 }
123
1c1d572f 124 /*
3dca2276
PP
125 * Acquire reference to parent since stream will become publicly
126 * reachable; it needs its parent to remain valid.
1c1d572f 127 */
3fea54f6 128 bt_object_set_parent(&stream->base, &trace->base);
3dca2276
PP
129 stream->stream_class = stream_class;
130 stream->id = (int64_t) id;
273b65be 131
3dca2276
PP
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;
98edd02c 137 }
273b65be
JG
138 }
139
cb6f1f7d 140 BT_LOGD("Set stream's trace parent: trace-addr=%p", trace);
1c1d572f 141
3dca2276 142 /* Add this stream to the trace's streams */
cb6f1f7d 143 BT_LOGD("Created stream object: addr=%p", stream);
3dca2276 144 goto end;
cd7d8fb7 145
3dca2276
PP
146error:
147 ret = -1;
f0ea9318 148
3dca2276 149end:
273b65be
JG
150 return ret;
151}
152
312c056a
PP
153static
154void bt_stream_free_packet(struct bt_packet *packet, struct bt_stream *stream)
155{
156 bt_packet_destroy(packet);
157}
158
273b65be 159static
3dca2276
PP
160struct bt_stream *bt_stream_create_with_id_no_check(
161 struct bt_stream_class *stream_class,
162 const char *name, uint64_t id)
273b65be 163{
3dca2276
PP
164 int ret;
165 struct bt_stream *stream = NULL;
166 struct bt_trace *trace = NULL;
3230ee6b 167
3dca2276
PP
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);
3230ee6b 173
cb6f1f7d 174 trace = bt_stream_class_borrow_trace(stream_class);
3dca2276
PP
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;
3230ee6b
PP
182 }
183
3dca2276 184 if (bt_trace_is_static(trace)) {
0686ef94 185 /*
3dca2276
PP
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.
0686ef94 189 */
3dca2276
PP
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;
9f56e450 196 }
12c8a1a3 197
3dca2276
PP
198 stream = g_new0(struct bt_stream, 1);
199 if (!stream) {
200 BT_LOGE_STR("Failed to allocate one stream.");
201 goto error;
12c8a1a3 202 }
b71d7298 203
cb6f1f7d
PP
204 ret = bt_stream_initialize(stream, stream_class, name,
205 id, bt_stream_destroy);
3dca2276 206 if (ret) {
cb6f1f7d 207 /* bt_stream_initialize() logs errors */
3dca2276 208 goto error;
b71d7298 209 }
41ac640a 210
312c056a
PP
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
cb6f1f7d 220 g_ptr_array_add(trace->streams, stream);
3dca2276
PP
221 BT_LOGD("Created stream object: addr=%p", stream);
222 goto end;
3230ee6b 223
3dca2276
PP
224error:
225 BT_PUT(stream);
226
227end:
228 return stream;
273b65be
JG
229}
230
3dca2276
PP
231struct bt_stream *bt_stream_create(struct bt_stream_class *stream_class,
232 const char *name, uint64_t id_param)
273b65be 233{
3dca2276
PP
234 struct bt_stream *stream = NULL;
235 int64_t id = (int64_t) id_param;
273b65be 236
3dca2276
PP
237 if (!stream_class) {
238 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
12c8a1a3
JG
239 goto end;
240 }
241
3dca2276
PP
242 if (id < 0) {
243 BT_LOGW("Invalid parameter: invalid stream's ID: "
244 "name=\"%s\", id=%" PRIu64,
245 name, id_param);
12c8a1a3
JG
246 goto end;
247 }
248
3dca2276
PP
249 stream = bt_stream_create_with_id_no_check(stream_class,
250 name, id_param);
d7b1ea66 251
273b65be 252end:
3dca2276 253 return stream;
273b65be 254}
b71d7298 255
094ff7c0 256struct bt_stream_class *bt_stream_borrow_class(struct bt_stream *stream)
af9296f3 257{
cb6f1f7d
PP
258 BT_ASSERT(stream);
259 return stream->stream_class;
af9296f3
JG
260}
261
50842bdc 262const char *bt_stream_get_name(struct bt_stream *stream)
b71d7298 263{
cb6f1f7d
PP
264 BT_ASSERT_PRE_NON_NULL(stream, "Stream");
265 return stream->name ? stream->name->str : NULL;
b71d7298 266}
98a4cbef 267
3dca2276 268int64_t bt_stream_get_id(struct bt_stream *stream)
98a4cbef 269{
cb6f1f7d
PP
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;
98a4cbef 280}
This page took 0.069826 seconds and 4 git commands to generate.