lib: add internal object pool API and use it; adapt plugins/tests
[babeltrace.git] / include / babeltrace / ctf-ir / stream-class-internal.h
CommitLineData
adc315b8
JG
1#ifndef BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H
2#define BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H
273b65be
JG
3
4/*
adc315b8 5 * BabelTrace - CTF IR: Stream class internal
273b65be 6 *
de9dd397 7 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
273b65be
JG
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
3dca2276
PP
30#include <babeltrace/assert-internal.h>
31#include <babeltrace/common-internal.h>
32#include <babeltrace/ctf-ir/validation-internal.h>
33#include <babeltrace/ctf-ir/field-types-internal.h>
34#include <babeltrace/ctf-ir/utils-internal.h>
35#include <babeltrace/ctf-ir/visitor.h>
83509119 36#include <babeltrace/object-internal.h>
312c056a 37#include <babeltrace/object-pool-internal.h>
273b65be
JG
38#include <babeltrace/babeltrace-internal.h>
39#include <glib.h>
3dca2276 40#include <inttypes.h>
273b65be 41
3dca2276 42struct bt_stream_class_common {
83509119 43 struct bt_object base;
273b65be 44 GString *name;
3dca2276
PP
45
46 /* Array of pointers to event class addresses */
47 GPtrArray *event_classes;
48
49 /* event class id (int64_t) to event class address */
0b9ce69f 50 GHashTable *event_classes_ht;
adc315b8 51 int id_set;
9ac68eb1
PP
52 int64_t id;
53 int64_t next_event_id;
3dca2276
PP
54 struct bt_field_type_common *packet_context_field_type;
55 struct bt_field_type_common *event_header_field_type;
56 struct bt_field_type_common *event_context_field_type;
273b65be 57 int frozen;
c35a1669 58 int byte_order;
09840de5
PP
59
60 /*
61 * This flag indicates if the stream class is valid. A valid
62 * stream class is _always_ frozen.
63 */
64 int valid;
2a3ced3c
PP
65
66 /*
67 * Unique clock class mapped to any field type within this
68 * stream class, including all the stream class's event class
69 * field types. This is only set if the stream class is frozen.
70 *
71 * If the stream class is frozen and this is still NULL, it is
72 * still possible that it becomes non-NULL because
73 * bt_stream_class_add_event_class() can add an event class
74 * containing a field type mapped to some clock class. In this
75 * case, this is the mapped clock class, and at this point, both
76 * the new event class and the stream class are frozen, so the
77 * next added event classes are expected to contain field types
78 * which only map to this specific clock class.
79 *
80 * If this is a CTF writer stream class, then this is the
81 * backing clock class of the `clock` member above.
82 */
83 struct bt_clock_class *clock_class;
273b65be
JG
84};
85
3dca2276
PP
86struct bt_stream_class {
87 struct bt_stream_class_common common;
312c056a
PP
88
89 /* Pool of `struct bt_field_wrapper *` */
90 struct bt_object_pool event_header_field_pool;
91
92 /* Pool of `struct bt_field_wrapper *` */
93 struct bt_object_pool packet_context_field_pool;
3dca2276
PP
94};
95
96struct bt_event_class_common;
273b65be 97
adc315b8 98BT_HIDDEN
3dca2276
PP
99int bt_stream_class_common_initialize(struct bt_stream_class_common *stream_class,
100 const char *name, bt_object_release_func release_func);
273b65be
JG
101
102BT_HIDDEN
3dca2276 103void bt_stream_class_common_finalize(struct bt_stream_class_common *stream_class);
273b65be 104
5ca83563 105BT_HIDDEN
3dca2276 106void bt_stream_class_common_freeze(struct bt_stream_class_common *stream_class);
5ca83563 107
29664b2a 108BT_HIDDEN
3dca2276
PP
109void bt_stream_class_freeze(struct bt_stream_class *stream_class);
110
111static inline
112const char *bt_stream_class_common_get_name(
113 struct bt_stream_class_common *stream_class)
114{
115 BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
116 return stream_class->name->len > 0 ? stream_class->name->str : NULL;
117}
118
119static inline
120int64_t bt_stream_class_common_get_id(
121 struct bt_stream_class_common *stream_class)
122{
123 int64_t ret;
124
125 BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
126
127 if (!stream_class->id_set) {
128 BT_LOGV("Stream class's ID is not set: addr=%p, name=\"%s\"",
129 stream_class,
130 bt_stream_class_common_get_name(stream_class));
131 ret = (int64_t) -1;
132 goto end;
133 }
134
135 ret = stream_class->id;
136
137end:
138 return ret;
139}
29664b2a 140
e011d2c1 141BT_HIDDEN
3dca2276
PP
142void bt_stream_class_common_set_byte_order(
143 struct bt_stream_class_common *stream_class, int byte_order);
e011d2c1 144
2a3ced3c 145BT_HIDDEN
3dca2276
PP
146int bt_stream_class_common_validate_single_clock_class(
147 struct bt_stream_class_common *stream_class,
2a3ced3c
PP
148 struct bt_clock_class **expected_clock_class);
149
3dca2276
PP
150BT_HIDDEN
151int bt_stream_class_common_add_event_class(
152 struct bt_stream_class_common *stream_class,
153 struct bt_event_class_common *event_class,
154 bt_validation_flag_copy_field_type_func copy_field_type_func);
155
156BT_HIDDEN
157int bt_stream_class_common_visit(struct bt_stream_class_common *stream_class,
158 bt_visitor visitor, void *data);
159
160static inline
161struct bt_trace_common *bt_stream_class_common_borrow_trace(
162 struct bt_stream_class_common *stream_class)
163{
164 BT_ASSERT(stream_class);
165 return (void *) bt_object_borrow_parent(stream_class);
166}
167
3dca2276
PP
168static inline
169int bt_stream_class_common_set_name(struct bt_stream_class_common *stream_class,
170 const char *name)
171{
172 int ret = 0;
173
174 if (!stream_class) {
175 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
176 ret = -1;
177 goto end;
178 }
179
180 if (stream_class->frozen) {
181 BT_LOGW("Invalid parameter: stream class is frozen: "
182 "addr=%p, name=\"%s\", id=%" PRId64,
183 stream_class,
184 bt_stream_class_common_get_name(stream_class),
185 bt_stream_class_common_get_id(stream_class));
186 ret = -1;
187 goto end;
188 }
189
190 if (!name) {
191 g_string_assign(stream_class->name, "");
192 } else {
193 if (strlen(name) == 0) {
194 BT_LOGW("Invalid parameter: name is empty.");
195 ret = -1;
196 goto end;
197 }
198
199 g_string_assign(stream_class->name, name);
200 }
201
202 BT_LOGV("Set stream class's name: "
203 "addr=%p, name=\"%s\", id=%" PRId64,
204 stream_class, bt_stream_class_common_get_name(stream_class),
205 bt_stream_class_common_get_id(stream_class));
206end:
207 return ret;
208}
209
210static inline
211void _bt_stream_class_common_set_id(
212 struct bt_stream_class_common *stream_class, int64_t id)
dc3fffef 213{
f6ccaed9 214 BT_ASSERT(stream_class);
3dca2276
PP
215 stream_class->id = id;
216 stream_class->id_set = 1;
217 BT_LOGV("Set stream class's ID (internal): "
218 "addr=%p, name=\"%s\", id=%" PRId64,
219 stream_class, bt_stream_class_common_get_name(stream_class),
220 bt_stream_class_common_get_id(stream_class));
221}
222
223static inline
224int bt_stream_class_common_set_id_no_check(
225 struct bt_stream_class_common *stream_class, int64_t id)
226{
227 _bt_stream_class_common_set_id(stream_class, id);
228 return 0;
229}
230
231static inline
232int bt_stream_class_common_set_id(struct bt_stream_class_common *stream_class,
233 uint64_t id_param)
234{
235 int ret = 0;
236 int64_t id = (int64_t) id_param;
237
238 if (!stream_class) {
239 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
240 ret = -1;
241 goto end;
242 }
243
244 if (stream_class->frozen) {
245 BT_LOGW("Invalid parameter: stream class is frozen: "
246 "addr=%p, name=\"%s\", id=%" PRId64,
247 stream_class,
248 bt_stream_class_common_get_name(stream_class),
249 bt_stream_class_common_get_id(stream_class));
250 ret = -1;
251 goto end;
252 }
253
254 if (id < 0) {
255 BT_LOGW("Invalid parameter: invalid stream class's ID: "
256 "stream-class-addr=%p, stream-class-name=\"%s\", "
257 "stream-class-id=%" PRId64 ", id=%" PRIu64,
258 stream_class,
259 bt_stream_class_common_get_name(stream_class),
260 bt_stream_class_common_get_id(stream_class),
261 id_param);
262 ret = -1;
263 goto end;
264 }
265
266 ret = bt_stream_class_common_set_id_no_check(stream_class, id);
267 if (ret == 0) {
268 BT_LOGV("Set stream class's ID: "
269 "addr=%p, name=\"%s\", id=%" PRId64,
270 stream_class,
271 bt_stream_class_common_get_name(stream_class),
272 bt_stream_class_common_get_id(stream_class));
273 }
274end:
275 return ret;
276}
277
278static inline
279int64_t bt_stream_class_common_get_event_class_count(
280 struct bt_stream_class_common *stream_class)
281{
282 int64_t ret;
283
284 if (!stream_class) {
285 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
286 ret = (int64_t) -1;
287 goto end;
288 }
289
290 ret = (int64_t) stream_class->event_classes->len;
291end:
292 return ret;
293}
294
295static inline
094ff7c0 296struct bt_event_class_common *bt_stream_class_common_borrow_event_class_by_index(
3dca2276
PP
297 struct bt_stream_class_common *stream_class, uint64_t index)
298{
299 BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
300 BT_ASSERT_PRE(index < stream_class->event_classes->len,
301 "Index is out of bounds: index=%" PRIu64 ", "
302 "count=%u",
303 index, stream_class->event_classes->len);
094ff7c0 304 return g_ptr_array_index(stream_class->event_classes, index);
3dca2276
PP
305}
306
307static inline
094ff7c0 308struct bt_event_class_common *bt_stream_class_common_borrow_event_class_by_id(
3dca2276
PP
309 struct bt_stream_class_common *stream_class, uint64_t id)
310{
311 int64_t id_key = (int64_t) id;
312
313 BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
314 BT_ASSERT_PRE(id_key >= 0,
315 "Invalid event class ID: %" PRIu64, id);
094ff7c0
PP
316 return g_hash_table_lookup(stream_class->event_classes_ht,
317 &id_key);
3dca2276
PP
318}
319
320static inline
094ff7c0
PP
321struct bt_field_type_common *
322bt_stream_class_common_borrow_packet_context_field_type(
3dca2276
PP
323 struct bt_stream_class_common *stream_class)
324{
325 BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
094ff7c0 326 return stream_class->packet_context_field_type;
3dca2276
PP
327}
328
329static inline
330int bt_stream_class_common_set_packet_context_field_type(
331 struct bt_stream_class_common *stream_class,
332 struct bt_field_type_common *packet_context_type)
333{
334 int ret = 0;
335
336 if (!stream_class) {
337 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
338 ret = -1;
339 goto end;
340 }
341
342 if (stream_class->frozen) {
343 BT_LOGW("Invalid parameter: stream class is frozen: "
344 "addr=%p, name=\"%s\", id=%" PRId64,
345 stream_class, bt_stream_class_common_get_name(stream_class),
346 bt_stream_class_common_get_id(stream_class));
347 ret = -1;
348 goto end;
349 }
350
351 if (packet_context_type &&
352 bt_field_type_common_get_type_id(packet_context_type) !=
353 BT_FIELD_TYPE_ID_STRUCT) {
354 /* A packet context must be a structure. */
355 BT_LOGW("Invalid parameter: stream class's packet context field type must be a structure: "
356 "addr=%p, name=\"%s\", id=%" PRId64 ", "
357 "packet-context-ft-addr=%p, packet-context-ft-id=%s",
358 stream_class, bt_stream_class_common_get_name(stream_class),
359 bt_stream_class_common_get_id(stream_class),
360 packet_context_type,
361 bt_common_field_type_id_string(
362 bt_field_type_common_get_type_id(packet_context_type)));
363 ret = -1;
364 goto end;
365 }
366
367 bt_put(stream_class->packet_context_field_type);
368 bt_get(packet_context_type);
369 stream_class->packet_context_field_type = packet_context_type;
370 BT_LOGV("Set stream class's packet context field type: "
371 "addr=%p, name=\"%s\", id=%" PRId64 ", "
372 "packet-context-ft-addr=%p",
373 stream_class, bt_stream_class_common_get_name(stream_class),
374 bt_stream_class_common_get_id(stream_class),
375 packet_context_type);
376
377end:
378 return ret;
379}
380
381static inline
094ff7c0
PP
382struct bt_field_type_common *
383bt_stream_class_common_borrow_event_header_field_type(
3dca2276
PP
384 struct bt_stream_class_common *stream_class)
385{
386 struct bt_field_type_common *ret = NULL;
387
388 BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
389
390 if (!stream_class->event_header_field_type) {
391 BT_LOGV("Stream class has no event header field type: "
392 "addr=%p, name=\"%s\", id=%" PRId64,
393 stream_class,
394 bt_stream_class_common_get_name(stream_class),
395 bt_stream_class_common_get_id(stream_class));
396 goto end;
397 }
398
094ff7c0 399 ret = stream_class->event_header_field_type;
3dca2276
PP
400
401end:
402 return ret;
403}
404
405static inline
406int bt_stream_class_common_set_event_header_field_type(
407 struct bt_stream_class_common *stream_class,
408 struct bt_field_type_common *event_header_type)
409{
410 int ret = 0;
411
412 if (!stream_class) {
413 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
414 ret = -1;
415 goto end;
416 }
417
418 if (stream_class->frozen) {
419 BT_LOGW("Invalid parameter: stream class is frozen: "
420 "addr=%p, name=\"%s\", id=%" PRId64,
421 stream_class,
422 bt_stream_class_common_get_name(stream_class),
423 bt_stream_class_common_get_id(stream_class));
424 ret = -1;
425 goto end;
426 }
427
428 if (event_header_type &&
429 bt_field_type_common_get_type_id(event_header_type) !=
430 BT_FIELD_TYPE_ID_STRUCT) {
431 /* An event header must be a structure. */
432 BT_LOGW("Invalid parameter: stream class's event header field type must be a structure: "
433 "addr=%p, name=\"%s\", id=%" PRId64 ", "
434 "event-header-ft-addr=%p, event-header-ft-id=%s",
435 stream_class, bt_stream_class_common_get_name(stream_class),
436 bt_stream_class_common_get_id(stream_class),
437 event_header_type,
438 bt_common_field_type_id_string(
439 bt_field_type_common_get_type_id(event_header_type)));
440 ret = -1;
441 goto end;
442 }
443
444 bt_put(stream_class->event_header_field_type);
445 stream_class->event_header_field_type = bt_get(event_header_type);
446 BT_LOGV("Set stream class's event header field type: "
447 "addr=%p, name=\"%s\", id=%" PRId64 ", "
448 "event-header-ft-addr=%p",
449 stream_class, bt_stream_class_common_get_name(stream_class),
450 bt_stream_class_common_get_id(stream_class),
451 event_header_type);
452end:
453 return ret;
454}
455
456static inline
094ff7c0
PP
457struct bt_field_type_common *
458bt_stream_class_common_borrow_event_context_field_type(
3dca2276
PP
459 struct bt_stream_class_common *stream_class)
460{
461 struct bt_field_type_common *ret = NULL;
462
463 BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
464
465 if (!stream_class->event_context_field_type) {
466 goto end;
467 }
468
094ff7c0 469 ret = stream_class->event_context_field_type;
3dca2276
PP
470
471end:
472 return ret;
473}
474
475static inline
476int bt_stream_class_common_set_event_context_field_type(
477 struct bt_stream_class_common *stream_class,
478 struct bt_field_type_common *event_context_type)
479{
480 int ret = 0;
481
482 if (!stream_class) {
483 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
484 ret = -1;
485 goto end;
486 }
487
488 if (stream_class->frozen) {
489 BT_LOGW("Invalid parameter: stream class is frozen: "
490 "addr=%p, name=\"%s\", id=%" PRId64,
491 stream_class, bt_stream_class_common_get_name(stream_class),
492 bt_stream_class_common_get_id(stream_class));
493 ret = -1;
494 goto end;
495 }
496
497 if (event_context_type &&
498 bt_field_type_common_get_type_id(event_context_type) !=
499 BT_FIELD_TYPE_ID_STRUCT) {
500 /* A packet context must be a structure. */
501 BT_LOGW("Invalid parameter: stream class's event context field type must be a structure: "
502 "addr=%p, name=\"%s\", id=%" PRId64 ", "
503 "event-context-ft-addr=%p, event-context-ft-id=%s",
504 stream_class, bt_stream_class_common_get_name(stream_class),
505 bt_stream_class_common_get_id(stream_class),
506 event_context_type,
507 bt_common_field_type_id_string(
508 bt_field_type_common_get_type_id(event_context_type)));
509 ret = -1;
510 goto end;
511 }
512
513 bt_put(stream_class->event_context_field_type);
514 stream_class->event_context_field_type = bt_get(event_context_type);
515 BT_LOGV("Set stream class's event context field type: "
516 "addr=%p, name=\"%s\", id=%" PRId64 ", "
517 "event-context-ft-addr=%p",
518 stream_class, bt_stream_class_common_get_name(stream_class),
519 bt_stream_class_common_get_id(stream_class),
520 event_context_type);
521end:
522 return ret;
dc3fffef
PP
523}
524
adc315b8 525#endif /* BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H */
This page took 0.065182 seconds and 4 git commands to generate.