Visibility hidden by default
[babeltrace.git] / src / ctf-writer / stream-class.h
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright 2014 EfficiOS Inc.
5 *
6 * The Common Trace Format (CTF) Specification is available at
7 * http://www.efficios.com/ctf
8 */
9
10 #ifndef BABELTRACE_CTF_WRITER_STREAM_CLASS_INTERNAL_H
11 #define BABELTRACE_CTF_WRITER_STREAM_CLASS_INTERNAL_H
12
13 #include "common/assert.h"
14 #include "common/macros.h"
15 #include "common/common.h"
16 #include <babeltrace2-ctf-writer/field-types.h>
17 #include <babeltrace2-ctf-writer/visitor.h>
18 #include <inttypes.h>
19
20 #include "clock.h"
21 #include "field-types.h"
22 #include "object.h"
23 #include "stream-class.h"
24 #include "utils.h"
25 #include "validation.h"
26
27 struct bt_ctf_stream_class_common {
28 struct bt_ctf_object base;
29 GString *name;
30
31 /* Array of pointers to event class addresses */
32 GPtrArray *event_classes;
33
34 /* event class id (int64_t) to event class address */
35 GHashTable *event_classes_ht;
36 int id_set;
37 int64_t id;
38 int64_t next_event_id;
39 struct bt_ctf_field_type_common *packet_context_field_type;
40 struct bt_ctf_field_type_common *event_header_field_type;
41 struct bt_ctf_field_type_common *event_context_field_type;
42 int frozen;
43 int byte_order;
44
45 /*
46 * This flag indicates if the stream class is valid. A valid
47 * stream class is _always_ frozen.
48 */
49 int valid;
50
51 /*
52 * Unique clock class mapped to any field type within this
53 * stream class, including all the stream class's event class
54 * field types. This is only set if the stream class is frozen.
55 *
56 * If the stream class is frozen and this is still NULL, it is
57 * still possible that it becomes non-NULL because
58 * bt_ctf_stream_class_add_event_class() can add an event class
59 * containing a field type mapped to some clock class. In this
60 * case, this is the mapped clock class, and at this point, both
61 * the new event class and the stream class are frozen, so the
62 * next added event classes are expected to contain field types
63 * which only map to this specific clock class.
64 *
65 * If this is a CTF writer stream class, then this is the
66 * backing clock class of the `clock` member above.
67 */
68 struct bt_ctf_clock_class *clock_class;
69 };
70
71 struct bt_ctf_event_class_common;
72
73 int bt_ctf_stream_class_common_initialize(struct bt_ctf_stream_class_common *stream_class,
74 const char *name, bt_ctf_object_release_func release_func);
75
76 void bt_ctf_stream_class_common_finalize(struct bt_ctf_stream_class_common *stream_class);
77
78 void bt_ctf_stream_class_common_freeze(struct bt_ctf_stream_class_common *stream_class);
79
80 static inline
81 const char *bt_ctf_stream_class_common_get_name(
82 struct bt_ctf_stream_class_common *stream_class)
83 {
84 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
85 return stream_class->name->len > 0 ? stream_class->name->str : NULL;
86 }
87
88 static inline
89 int64_t bt_ctf_stream_class_common_get_id(
90 struct bt_ctf_stream_class_common *stream_class)
91 {
92 int64_t ret;
93
94 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
95
96 if (!stream_class->id_set) {
97 BT_LOGT("Stream class's ID is not set: addr=%p, name=\"%s\"",
98 stream_class,
99 bt_ctf_stream_class_common_get_name(stream_class));
100 ret = (int64_t) -1;
101 goto end;
102 }
103
104 ret = stream_class->id;
105
106 end:
107 return ret;
108 }
109
110 void bt_ctf_stream_class_common_set_byte_order(
111 struct bt_ctf_stream_class_common *stream_class, int byte_order);
112
113 int bt_ctf_stream_class_common_validate_single_clock_class(
114 struct bt_ctf_stream_class_common *stream_class,
115 struct bt_ctf_clock_class **expected_clock_class);
116
117 int bt_ctf_stream_class_common_add_event_class(
118 struct bt_ctf_stream_class_common *stream_class,
119 struct bt_ctf_event_class_common *event_class,
120 bt_ctf_validation_flag_copy_field_type_func copy_field_type_func);
121
122 int bt_ctf_stream_class_common_visit(struct bt_ctf_stream_class_common *stream_class,
123 bt_ctf_visitor visitor, void *data);
124
125 int bt_ctf_stream_class_visit(struct bt_ctf_stream_class *stream_class,
126 bt_ctf_visitor visitor, void *data);
127
128 static inline
129 struct bt_ctf_trace_common *bt_ctf_stream_class_common_borrow_trace(
130 struct bt_ctf_stream_class_common *stream_class)
131 {
132 BT_ASSERT_DBG(stream_class);
133 return (void *) bt_ctf_object_borrow_parent(&stream_class->base);
134 }
135
136 static inline
137 int bt_ctf_stream_class_common_set_name(struct bt_ctf_stream_class_common *stream_class,
138 const char *name)
139 {
140 int ret = 0;
141
142 if (!stream_class) {
143 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
144 ret = -1;
145 goto end;
146 }
147
148 if (stream_class->frozen) {
149 BT_LOGW("Invalid parameter: stream class is frozen: "
150 "addr=%p, name=\"%s\", id=%" PRId64,
151 stream_class,
152 bt_ctf_stream_class_common_get_name(stream_class),
153 bt_ctf_stream_class_common_get_id(stream_class));
154 ret = -1;
155 goto end;
156 }
157
158 if (!name) {
159 g_string_assign(stream_class->name, "");
160 } else {
161 if (strlen(name) == 0) {
162 BT_LOGW("Invalid parameter: name is empty.");
163 ret = -1;
164 goto end;
165 }
166
167 g_string_assign(stream_class->name, name);
168 }
169
170 BT_LOGT("Set stream class's name: "
171 "addr=%p, name=\"%s\", id=%" PRId64,
172 stream_class, bt_ctf_stream_class_common_get_name(stream_class),
173 bt_ctf_stream_class_common_get_id(stream_class));
174 end:
175 return ret;
176 }
177
178 static inline
179 void _bt_ctf_stream_class_common_set_id(
180 struct bt_ctf_stream_class_common *stream_class, int64_t id)
181 {
182 BT_ASSERT_DBG(stream_class);
183 stream_class->id = id;
184 stream_class->id_set = 1;
185 BT_LOGT("Set stream class's ID (internal): "
186 "addr=%p, name=\"%s\", id=%" PRId64,
187 stream_class, bt_ctf_stream_class_common_get_name(stream_class),
188 bt_ctf_stream_class_common_get_id(stream_class));
189 }
190
191 static inline
192 int bt_ctf_stream_class_common_set_id_no_check(
193 struct bt_ctf_stream_class_common *stream_class, int64_t id)
194 {
195 _bt_ctf_stream_class_common_set_id(stream_class, id);
196 return 0;
197 }
198
199 static inline
200 int bt_ctf_stream_class_common_set_id(struct bt_ctf_stream_class_common *stream_class,
201 uint64_t id_param)
202 {
203 int ret = 0;
204 int64_t id = (int64_t) id_param;
205
206 if (!stream_class) {
207 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
208 ret = -1;
209 goto end;
210 }
211
212 if (stream_class->frozen) {
213 BT_LOGW("Invalid parameter: stream class is frozen: "
214 "addr=%p, name=\"%s\", id=%" PRId64,
215 stream_class,
216 bt_ctf_stream_class_common_get_name(stream_class),
217 bt_ctf_stream_class_common_get_id(stream_class));
218 ret = -1;
219 goto end;
220 }
221
222 if (id < 0) {
223 BT_LOGW("Invalid parameter: invalid stream class's ID: "
224 "stream-class-addr=%p, stream-class-name=\"%s\", "
225 "stream-class-id=%" PRId64 ", id=%" PRIu64,
226 stream_class,
227 bt_ctf_stream_class_common_get_name(stream_class),
228 bt_ctf_stream_class_common_get_id(stream_class),
229 id_param);
230 ret = -1;
231 goto end;
232 }
233
234 ret = bt_ctf_stream_class_common_set_id_no_check(stream_class, id);
235 if (ret == 0) {
236 BT_LOGT("Set stream class's ID: "
237 "addr=%p, name=\"%s\", id=%" PRId64,
238 stream_class,
239 bt_ctf_stream_class_common_get_name(stream_class),
240 bt_ctf_stream_class_common_get_id(stream_class));
241 }
242 end:
243 return ret;
244 }
245
246 static inline
247 int64_t bt_ctf_stream_class_common_get_event_class_count(
248 struct bt_ctf_stream_class_common *stream_class)
249 {
250 int64_t ret;
251
252 if (!stream_class) {
253 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
254 ret = (int64_t) -1;
255 goto end;
256 }
257
258 ret = (int64_t) stream_class->event_classes->len;
259 end:
260 return ret;
261 }
262
263 static inline
264 struct bt_ctf_event_class_common *bt_ctf_stream_class_common_borrow_event_class_by_index(
265 struct bt_ctf_stream_class_common *stream_class, uint64_t index)
266 {
267 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
268 BT_CTF_ASSERT_PRE(index < stream_class->event_classes->len,
269 "Index is out of bounds: index=%" PRIu64 ", "
270 "count=%u",
271 index, stream_class->event_classes->len);
272 return g_ptr_array_index(stream_class->event_classes, index);
273 }
274
275 static inline
276 struct bt_ctf_event_class_common *bt_ctf_stream_class_common_borrow_event_class_by_id(
277 struct bt_ctf_stream_class_common *stream_class, uint64_t id)
278 {
279 int64_t id_key = (int64_t) id;
280
281 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
282 BT_CTF_ASSERT_PRE(id_key >= 0,
283 "Invalid event class ID: %" PRIu64, id);
284 return g_hash_table_lookup(stream_class->event_classes_ht,
285 &id_key);
286 }
287
288 static inline
289 struct bt_ctf_field_type_common *
290 bt_ctf_stream_class_common_borrow_packet_context_field_type(
291 struct bt_ctf_stream_class_common *stream_class)
292 {
293 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
294 return stream_class->packet_context_field_type;
295 }
296
297 static inline
298 int bt_ctf_stream_class_common_set_packet_context_field_type(
299 struct bt_ctf_stream_class_common *stream_class,
300 struct bt_ctf_field_type_common *packet_context_type)
301 {
302 int ret = 0;
303
304 if (!stream_class) {
305 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
306 ret = -1;
307 goto end;
308 }
309
310 if (stream_class->frozen) {
311 BT_LOGW("Invalid parameter: stream class is frozen: "
312 "addr=%p, name=\"%s\", id=%" PRId64,
313 stream_class, bt_ctf_stream_class_common_get_name(stream_class),
314 bt_ctf_stream_class_common_get_id(stream_class));
315 ret = -1;
316 goto end;
317 }
318
319 if (packet_context_type &&
320 bt_ctf_field_type_common_get_type_id(packet_context_type) !=
321 BT_CTF_FIELD_TYPE_ID_STRUCT) {
322 /* A packet context must be a structure. */
323 BT_LOGW("Invalid parameter: stream class's packet context field type must be a structure: "
324 "addr=%p, name=\"%s\", id=%" PRId64 ", "
325 "packet-context-ft-addr=%p, packet-context-ft-id=%s",
326 stream_class, bt_ctf_stream_class_common_get_name(stream_class),
327 bt_ctf_stream_class_common_get_id(stream_class),
328 packet_context_type,
329 bt_ctf_field_type_id_string(
330 bt_ctf_field_type_common_get_type_id(packet_context_type)));
331 ret = -1;
332 goto end;
333 }
334
335 bt_ctf_object_put_ref(stream_class->packet_context_field_type);
336 stream_class->packet_context_field_type = packet_context_type;
337 bt_ctf_object_get_ref(stream_class->packet_context_field_type);
338 BT_LOGT("Set stream class's packet context field type: "
339 "addr=%p, name=\"%s\", id=%" PRId64 ", "
340 "packet-context-ft-addr=%p",
341 stream_class, bt_ctf_stream_class_common_get_name(stream_class),
342 bt_ctf_stream_class_common_get_id(stream_class),
343 packet_context_type);
344
345 end:
346 return ret;
347 }
348
349 static inline
350 struct bt_ctf_field_type_common *
351 bt_ctf_stream_class_common_borrow_event_header_field_type(
352 struct bt_ctf_stream_class_common *stream_class)
353 {
354 struct bt_ctf_field_type_common *ret = NULL;
355
356 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
357
358 if (!stream_class->event_header_field_type) {
359 BT_LOGT("Stream class has no event header field type: "
360 "addr=%p, name=\"%s\", id=%" PRId64,
361 stream_class,
362 bt_ctf_stream_class_common_get_name(stream_class),
363 bt_ctf_stream_class_common_get_id(stream_class));
364 goto end;
365 }
366
367 ret = stream_class->event_header_field_type;
368
369 end:
370 return ret;
371 }
372
373 static inline
374 int bt_ctf_stream_class_common_set_event_header_field_type(
375 struct bt_ctf_stream_class_common *stream_class,
376 struct bt_ctf_field_type_common *event_header_type)
377 {
378 int ret = 0;
379
380 if (!stream_class) {
381 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
382 ret = -1;
383 goto end;
384 }
385
386 if (stream_class->frozen) {
387 BT_LOGW("Invalid parameter: stream class is frozen: "
388 "addr=%p, name=\"%s\", id=%" PRId64,
389 stream_class,
390 bt_ctf_stream_class_common_get_name(stream_class),
391 bt_ctf_stream_class_common_get_id(stream_class));
392 ret = -1;
393 goto end;
394 }
395
396 if (event_header_type &&
397 bt_ctf_field_type_common_get_type_id(event_header_type) !=
398 BT_CTF_FIELD_TYPE_ID_STRUCT) {
399 /* An event header must be a structure. */
400 BT_LOGW("Invalid parameter: stream class's event header field type must be a structure: "
401 "addr=%p, name=\"%s\", id=%" PRId64 ", "
402 "event-header-ft-addr=%p, event-header-ft-id=%s",
403 stream_class, bt_ctf_stream_class_common_get_name(stream_class),
404 bt_ctf_stream_class_common_get_id(stream_class),
405 event_header_type,
406 bt_ctf_field_type_id_string(
407 bt_ctf_field_type_common_get_type_id(event_header_type)));
408 ret = -1;
409 goto end;
410 }
411
412 bt_ctf_object_put_ref(stream_class->event_header_field_type);
413 stream_class->event_header_field_type = event_header_type;
414 bt_ctf_object_get_ref(stream_class->event_header_field_type);
415 BT_LOGT("Set stream class's event header field type: "
416 "addr=%p, name=\"%s\", id=%" PRId64 ", "
417 "event-header-ft-addr=%p",
418 stream_class, bt_ctf_stream_class_common_get_name(stream_class),
419 bt_ctf_stream_class_common_get_id(stream_class),
420 event_header_type);
421 end:
422 return ret;
423 }
424
425 static inline
426 struct bt_ctf_field_type_common *
427 bt_ctf_stream_class_common_borrow_event_context_field_type(
428 struct bt_ctf_stream_class_common *stream_class)
429 {
430 struct bt_ctf_field_type_common *ret = NULL;
431
432 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
433
434 if (!stream_class->event_context_field_type) {
435 goto end;
436 }
437
438 ret = stream_class->event_context_field_type;
439
440 end:
441 return ret;
442 }
443
444 static inline
445 int bt_ctf_stream_class_common_set_event_context_field_type(
446 struct bt_ctf_stream_class_common *stream_class,
447 struct bt_ctf_field_type_common *event_context_type)
448 {
449 int ret = 0;
450
451 if (!stream_class) {
452 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
453 ret = -1;
454 goto end;
455 }
456
457 if (stream_class->frozen) {
458 BT_LOGW("Invalid parameter: stream class is frozen: "
459 "addr=%p, name=\"%s\", id=%" PRId64,
460 stream_class, bt_ctf_stream_class_common_get_name(stream_class),
461 bt_ctf_stream_class_common_get_id(stream_class));
462 ret = -1;
463 goto end;
464 }
465
466 if (event_context_type &&
467 bt_ctf_field_type_common_get_type_id(event_context_type) !=
468 BT_CTF_FIELD_TYPE_ID_STRUCT) {
469 /* A packet context must be a structure. */
470 BT_LOGW("Invalid parameter: stream class's event context field type must be a structure: "
471 "addr=%p, name=\"%s\", id=%" PRId64 ", "
472 "event-context-ft-addr=%p, event-context-ft-id=%s",
473 stream_class, bt_ctf_stream_class_common_get_name(stream_class),
474 bt_ctf_stream_class_common_get_id(stream_class),
475 event_context_type,
476 bt_ctf_field_type_id_string(
477 bt_ctf_field_type_common_get_type_id(event_context_type)));
478 ret = -1;
479 goto end;
480 }
481
482 bt_ctf_object_put_ref(stream_class->event_context_field_type);
483 stream_class->event_context_field_type = event_context_type;
484 bt_ctf_object_get_ref(stream_class->event_context_field_type);
485 BT_LOGT("Set stream class's event context field type: "
486 "addr=%p, name=\"%s\", id=%" PRId64 ", "
487 "event-context-ft-addr=%p",
488 stream_class, bt_ctf_stream_class_common_get_name(stream_class),
489 bt_ctf_stream_class_common_get_id(stream_class),
490 event_context_type);
491 end:
492 return ret;
493 }
494
495 struct bt_ctf_stream_class {
496 struct bt_ctf_stream_class_common common;
497 struct bt_ctf_clock *clock;
498 int64_t next_stream_id;
499 };
500
501 struct metadata_context;
502
503 int bt_ctf_stream_class_serialize(struct bt_ctf_stream_class *stream_class,
504 struct metadata_context *context);
505
506 int bt_ctf_stream_class_map_clock_class(
507 struct bt_ctf_stream_class *stream_class,
508 struct bt_ctf_field_type *packet_context_type,
509 struct bt_ctf_field_type *event_header_type);
510
511 #endif /* BABELTRACE_CTF_WRITER_STREAM_CLASS_INTERNAL_H */
This page took 0.039773 seconds and 4 git commands to generate.