1 #ifndef BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H
2 #define BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H
5 * BabelTrace - CTF IR: Stream class internal
7 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
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:
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
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
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>
36 #include <babeltrace/object-internal.h>
37 #include <babeltrace/object-pool-internal.h>
38 #include <babeltrace/babeltrace-internal.h>
42 struct bt_stream_class_common
{
43 struct bt_object base
;
46 /* Array of pointers to event class addresses */
47 GPtrArray
*event_classes
;
49 /* event class id (int64_t) to event class address */
50 GHashTable
*event_classes_ht
;
53 int64_t next_event_id
;
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
;
61 * This flag indicates if the stream class is valid. A valid
62 * stream class is _always_ frozen.
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.
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.
80 * If this is a CTF writer stream class, then this is the
81 * backing clock class of the `clock` member above.
83 struct bt_clock_class
*clock_class
;
86 struct bt_stream_class
{
87 struct bt_stream_class_common common
;
89 /* Pool of `struct bt_field_wrapper *` */
90 struct bt_object_pool event_header_field_pool
;
92 /* Pool of `struct bt_field_wrapper *` */
93 struct bt_object_pool packet_context_field_pool
;
96 struct bt_event_class_common
;
99 int bt_stream_class_common_initialize(struct bt_stream_class_common
*stream_class
,
100 const char *name
, bt_object_release_func release_func
);
103 void bt_stream_class_common_finalize(struct bt_stream_class_common
*stream_class
);
106 void bt_stream_class_common_freeze(struct bt_stream_class_common
*stream_class
);
109 void bt_stream_class_freeze(struct bt_stream_class
*stream_class
);
112 const char *bt_stream_class_common_get_name(
113 struct bt_stream_class_common
*stream_class
)
115 BT_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
116 return stream_class
->name
->len
> 0 ? stream_class
->name
->str
: NULL
;
120 int64_t bt_stream_class_common_get_id(
121 struct bt_stream_class_common
*stream_class
)
125 BT_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
127 if (!stream_class
->id_set
) {
128 BT_LOGV("Stream class's ID is not set: addr=%p, name=\"%s\"",
130 bt_stream_class_common_get_name(stream_class
));
135 ret
= stream_class
->id
;
142 void bt_stream_class_common_set_byte_order(
143 struct bt_stream_class_common
*stream_class
, int byte_order
);
146 int bt_stream_class_common_validate_single_clock_class(
147 struct bt_stream_class_common
*stream_class
,
148 struct bt_clock_class
**expected_clock_class
);
151 int 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
);
157 int bt_stream_class_common_visit(struct bt_stream_class_common
*stream_class
,
158 bt_visitor visitor
, void *data
);
161 struct bt_trace_common
*bt_stream_class_common_borrow_trace(
162 struct bt_stream_class_common
*stream_class
)
164 BT_ASSERT(stream_class
);
165 return (void *) bt_object_borrow_parent(stream_class
);
169 int bt_stream_class_common_set_name(struct bt_stream_class_common
*stream_class
,
175 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
180 if (stream_class
->frozen
) {
181 BT_LOGW("Invalid parameter: stream class is frozen: "
182 "addr=%p, name=\"%s\", id=%" PRId64
,
184 bt_stream_class_common_get_name(stream_class
),
185 bt_stream_class_common_get_id(stream_class
));
191 g_string_assign(stream_class
->name
, "");
193 if (strlen(name
) == 0) {
194 BT_LOGW("Invalid parameter: name is empty.");
199 g_string_assign(stream_class
->name
, name
);
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
));
211 void _bt_stream_class_common_set_id(
212 struct bt_stream_class_common
*stream_class
, int64_t id
)
214 BT_ASSERT(stream_class
);
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
));
224 int bt_stream_class_common_set_id_no_check(
225 struct bt_stream_class_common
*stream_class
, int64_t id
)
227 _bt_stream_class_common_set_id(stream_class
, id
);
232 int bt_stream_class_common_set_id(struct bt_stream_class_common
*stream_class
,
236 int64_t id
= (int64_t) id_param
;
239 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
244 if (stream_class
->frozen
) {
245 BT_LOGW("Invalid parameter: stream class is frozen: "
246 "addr=%p, name=\"%s\", id=%" PRId64
,
248 bt_stream_class_common_get_name(stream_class
),
249 bt_stream_class_common_get_id(stream_class
));
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
,
259 bt_stream_class_common_get_name(stream_class
),
260 bt_stream_class_common_get_id(stream_class
),
266 ret
= bt_stream_class_common_set_id_no_check(stream_class
, id
);
268 BT_LOGV("Set stream class's ID: "
269 "addr=%p, name=\"%s\", id=%" PRId64
,
271 bt_stream_class_common_get_name(stream_class
),
272 bt_stream_class_common_get_id(stream_class
));
279 int64_t bt_stream_class_common_get_event_class_count(
280 struct bt_stream_class_common
*stream_class
)
285 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
290 ret
= (int64_t) stream_class
->event_classes
->len
;
296 struct bt_event_class_common
*bt_stream_class_common_borrow_event_class_by_index(
297 struct bt_stream_class_common
*stream_class
, uint64_t index
)
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
", "
303 index
, stream_class
->event_classes
->len
);
304 return g_ptr_array_index(stream_class
->event_classes
, index
);
308 struct bt_event_class_common
*bt_stream_class_common_borrow_event_class_by_id(
309 struct bt_stream_class_common
*stream_class
, uint64_t id
)
311 int64_t id_key
= (int64_t) id
;
313 BT_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
314 BT_ASSERT_PRE(id_key
>= 0,
315 "Invalid event class ID: %" PRIu64
, id
);
316 return g_hash_table_lookup(stream_class
->event_classes_ht
,
321 struct bt_field_type_common
*
322 bt_stream_class_common_borrow_packet_context_field_type(
323 struct bt_stream_class_common
*stream_class
)
325 BT_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
326 return stream_class
->packet_context_field_type
;
330 int 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
)
337 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
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
));
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
),
361 bt_common_field_type_id_string(
362 bt_field_type_common_get_type_id(packet_context_type
)));
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
);
382 struct bt_field_type_common
*
383 bt_stream_class_common_borrow_event_header_field_type(
384 struct bt_stream_class_common
*stream_class
)
386 struct bt_field_type_common
*ret
= NULL
;
388 BT_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
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
,
394 bt_stream_class_common_get_name(stream_class
),
395 bt_stream_class_common_get_id(stream_class
));
399 ret
= stream_class
->event_header_field_type
;
406 int 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
)
413 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
418 if (stream_class
->frozen
) {
419 BT_LOGW("Invalid parameter: stream class is frozen: "
420 "addr=%p, name=\"%s\", id=%" PRId64
,
422 bt_stream_class_common_get_name(stream_class
),
423 bt_stream_class_common_get_id(stream_class
));
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
),
438 bt_common_field_type_id_string(
439 bt_field_type_common_get_type_id(event_header_type
)));
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
),
457 struct bt_field_type_common
*
458 bt_stream_class_common_borrow_event_context_field_type(
459 struct bt_stream_class_common
*stream_class
)
461 struct bt_field_type_common
*ret
= NULL
;
463 BT_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
465 if (!stream_class
->event_context_field_type
) {
469 ret
= stream_class
->event_context_field_type
;
476 int 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
)
483 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
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
));
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
),
507 bt_common_field_type_id_string(
508 bt_field_type_common_get_type_id(event_context_type
)));
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
),
525 #endif /* BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H */