lib: add internal object pool API and use it; adapt plugins/tests
[babeltrace.git] / include / babeltrace / ctf-ir / stream-class-internal.h
1 #ifndef BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H
2 #define BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H
3
4 /*
5 * BabelTrace - CTF IR: Stream class internal
6 *
7 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
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
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>
39 #include <glib.h>
40 #include <inttypes.h>
41
42 struct bt_stream_class_common {
43 struct bt_object base;
44 GString *name;
45
46 /* Array of pointers to event class addresses */
47 GPtrArray *event_classes;
48
49 /* event class id (int64_t) to event class address */
50 GHashTable *event_classes_ht;
51 int id_set;
52 int64_t id;
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;
57 int frozen;
58 int byte_order;
59
60 /*
61 * This flag indicates if the stream class is valid. A valid
62 * stream class is _always_ frozen.
63 */
64 int valid;
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;
84 };
85
86 struct bt_stream_class {
87 struct bt_stream_class_common common;
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;
94 };
95
96 struct bt_event_class_common;
97
98 BT_HIDDEN
99 int bt_stream_class_common_initialize(struct bt_stream_class_common *stream_class,
100 const char *name, bt_object_release_func release_func);
101
102 BT_HIDDEN
103 void bt_stream_class_common_finalize(struct bt_stream_class_common *stream_class);
104
105 BT_HIDDEN
106 void bt_stream_class_common_freeze(struct bt_stream_class_common *stream_class);
107
108 BT_HIDDEN
109 void bt_stream_class_freeze(struct bt_stream_class *stream_class);
110
111 static inline
112 const 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
119 static inline
120 int64_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
137 end:
138 return ret;
139 }
140
141 BT_HIDDEN
142 void bt_stream_class_common_set_byte_order(
143 struct bt_stream_class_common *stream_class, int byte_order);
144
145 BT_HIDDEN
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);
149
150 BT_HIDDEN
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);
155
156 BT_HIDDEN
157 int bt_stream_class_common_visit(struct bt_stream_class_common *stream_class,
158 bt_visitor visitor, void *data);
159
160 static inline
161 struct 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
168 static inline
169 int 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));
206 end:
207 return ret;
208 }
209
210 static inline
211 void _bt_stream_class_common_set_id(
212 struct bt_stream_class_common *stream_class, int64_t id)
213 {
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));
221 }
222
223 static inline
224 int 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
231 static inline
232 int 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 }
274 end:
275 return ret;
276 }
277
278 static inline
279 int64_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;
291 end:
292 return ret;
293 }
294
295 static inline
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)
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);
304 return g_ptr_array_index(stream_class->event_classes, index);
305 }
306
307 static inline
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)
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);
316 return g_hash_table_lookup(stream_class->event_classes_ht,
317 &id_key);
318 }
319
320 static inline
321 struct bt_field_type_common *
322 bt_stream_class_common_borrow_packet_context_field_type(
323 struct bt_stream_class_common *stream_class)
324 {
325 BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
326 return stream_class->packet_context_field_type;
327 }
328
329 static inline
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)
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
377 end:
378 return ret;
379 }
380
381 static inline
382 struct bt_field_type_common *
383 bt_stream_class_common_borrow_event_header_field_type(
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
399 ret = stream_class->event_header_field_type;
400
401 end:
402 return ret;
403 }
404
405 static inline
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)
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);
452 end:
453 return ret;
454 }
455
456 static inline
457 struct bt_field_type_common *
458 bt_stream_class_common_borrow_event_context_field_type(
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
469 ret = stream_class->event_context_field_type;
470
471 end:
472 return ret;
473 }
474
475 static inline
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)
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);
521 end:
522 return ret;
523 }
524
525 #endif /* BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H */
This page took 0.038881 seconds and 4 git commands to generate.