4 * Babeltrace CTF IR - Event class
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
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:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
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
29 #define BT_LOG_TAG "EVENT-CLASS"
30 #include <babeltrace/lib-logging-internal.h>
32 #include <babeltrace/ctf-ir/fields-internal.h>
33 #include <babeltrace/ctf-ir/field-types-internal.h>
34 #include <babeltrace/ctf-ir/event-class.h>
35 #include <babeltrace/ctf-ir/event-class-internal.h>
36 #include <babeltrace/ctf-ir/stream-class.h>
37 #include <babeltrace/ctf-ir/stream-class-internal.h>
38 #include <babeltrace/ctf-ir/trace-internal.h>
39 #include <babeltrace/ctf-ir/validation-internal.h>
40 #include <babeltrace/ctf-ir/utils.h>
41 #include <babeltrace/ctf-ir/utils-internal.h>
42 #include <babeltrace/ref.h>
43 #include <babeltrace/ctf-ir/attributes-internal.h>
44 #include <babeltrace/compiler-internal.h>
45 #include <babeltrace/endian-internal.h>
46 #include <babeltrace/types.h>
47 #include <babeltrace/values-internal.h>
48 #include <babeltrace/assert-internal.h>
53 void bt_event_class_destroy(struct bt_object
*obj
);
55 struct bt_event_class
*bt_event_class_create(const char *name
)
57 struct bt_value
*obj
= NULL
;
58 struct bt_event_class
*event_class
= NULL
;
60 BT_LOGD("Creating event class object: name=\"%s\"",
64 BT_LOGW_STR("Invalid parameter: name is NULL.");
68 event_class
= g_new0(struct bt_event_class
, 1);
70 BT_LOGE_STR("Failed to allocate one event class.");
74 bt_object_init(event_class
, bt_event_class_destroy
);
75 event_class
->fields
= bt_field_type_structure_create();
76 if (!event_class
->fields
) {
77 BT_LOGE_STR("Cannot create event class's initial payload field type object.");
82 event_class
->name
= g_string_new(name
);
83 if (!event_class
->name
) {
84 BT_LOGE_STR("Failed to allocate a GString.");
88 event_class
->emf_uri
= g_string_new(NULL
);
89 if (!event_class
->emf_uri
) {
90 BT_LOGE_STR("Failed to allocate a GString.");
94 event_class
->log_level
= BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED
;
96 BT_LOGD("Created event class object: addr=%p, name=\"%s\"",
97 event_class
, bt_event_class_get_name(event_class
));
106 const char *bt_event_class_get_name(struct bt_event_class
*event_class
)
108 const char *name
= NULL
;
111 BT_LOGW_STR("Invalid parameter: event class is NULL.");
115 name
= event_class
->name
->str
;
121 int64_t bt_event_class_get_id(struct bt_event_class
*event_class
)
126 BT_LOGW_STR("Invalid parameter: event class is NULL.");
131 ret
= event_class
->id
;
137 int bt_event_class_set_id(struct bt_event_class
*event_class
,
141 int64_t id
= (int64_t) id_param
;
144 BT_LOGW_STR("Invalid parameter: event class is NULL.");
149 if (event_class
->frozen
) {
150 BT_LOGW("Invalid parameter: event class is frozen: "
151 "addr=%p, name=\"%s\", id=%" PRId64
,
152 event_class
, bt_event_class_get_name(event_class
),
153 bt_event_class_get_id(event_class
));
159 BT_LOGW("Invalid parameter: invalid event class's ID: "
160 "addr=%p, name=\"%s\", id=%" PRIu64
,
161 event_class
, bt_event_class_get_name(event_class
),
167 event_class
->id
= id
;
168 BT_LOGV("Set event class's ID: "
169 "addr=%p, name=\"%s\", id=%" PRId64
,
170 event_class
, bt_event_class_get_name(event_class
), id
);
176 enum bt_event_class_log_level
bt_event_class_get_log_level(
177 struct bt_event_class
*event_class
)
179 enum bt_event_class_log_level log_level
;
182 BT_LOGW_STR("Invalid parameter: event class is NULL.");
183 log_level
= BT_EVENT_CLASS_LOG_LEVEL_UNKNOWN
;
187 log_level
= event_class
->log_level
;
193 int bt_event_class_set_log_level(struct bt_event_class
*event_class
,
194 enum bt_event_class_log_level log_level
)
199 BT_LOGW_STR("Invalid parameter: event class is NULL.");
204 if (event_class
->frozen
) {
205 BT_LOGW("Invalid parameter: event class is frozen: "
206 "addr=%p, name=\"%s\", id=%" PRId64
,
207 event_class
, bt_event_class_get_name(event_class
),
208 bt_event_class_get_id(event_class
));
214 case BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED
:
215 case BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY
:
216 case BT_EVENT_CLASS_LOG_LEVEL_ALERT
:
217 case BT_EVENT_CLASS_LOG_LEVEL_CRITICAL
:
218 case BT_EVENT_CLASS_LOG_LEVEL_ERROR
:
219 case BT_EVENT_CLASS_LOG_LEVEL_WARNING
:
220 case BT_EVENT_CLASS_LOG_LEVEL_NOTICE
:
221 case BT_EVENT_CLASS_LOG_LEVEL_INFO
:
222 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM
:
223 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM
:
224 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS
:
225 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE
:
226 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT
:
227 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION
:
228 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE
:
229 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG
:
232 BT_LOGW("Invalid parameter: unknown event class log level: "
233 "addr=%p, name=\"%s\", id=%" PRId64
", log-level=%d",
234 event_class
, bt_event_class_get_name(event_class
),
235 bt_event_class_get_id(event_class
), log_level
);
240 event_class
->log_level
= log_level
;
241 BT_LOGV("Set event class's log level: "
242 "addr=%p, name=\"%s\", id=%" PRId64
", log-level=%s",
243 event_class
, bt_event_class_get_name(event_class
),
244 bt_event_class_get_id(event_class
),
245 bt_event_class_log_level_string(log_level
));
251 const char *bt_event_class_get_emf_uri(
252 struct bt_event_class
*event_class
)
254 const char *emf_uri
= NULL
;
257 BT_LOGW_STR("Invalid parameter: event class is NULL.");
261 if (event_class
->emf_uri
->len
> 0) {
262 emf_uri
= event_class
->emf_uri
->str
;
269 int bt_event_class_set_emf_uri(struct bt_event_class
*event_class
,
275 BT_LOGW_STR("Invalid parameter: event class is NULL.");
280 if (emf_uri
&& strlen(emf_uri
) == 0) {
281 BT_LOGW_STR("Invalid parameter: EMF URI is empty.");
286 if (event_class
->frozen
) {
287 BT_LOGW("Invalid parameter: event class is frozen: "
288 "addr=%p, name=\"%s\", id=%" PRId64
,
289 event_class
, bt_event_class_get_name(event_class
),
290 bt_event_class_get_id(event_class
));
296 g_string_assign(event_class
->emf_uri
, emf_uri
);
297 BT_LOGV("Set event class's EMF URI: "
298 "addr=%p, name=\"%s\", id=%" PRId64
", emf-uri=\"%s\"",
299 event_class
, bt_event_class_get_name(event_class
),
300 bt_event_class_get_id(event_class
), emf_uri
);
302 g_string_assign(event_class
->emf_uri
, "");
303 BT_LOGV("Reset event class's EMF URI: "
304 "addr=%p, name=\"%s\", id=%" PRId64
,
305 event_class
, bt_event_class_get_name(event_class
),
306 bt_event_class_get_id(event_class
));
313 struct bt_stream_class
*bt_event_class_get_stream_class(
314 struct bt_event_class
*event_class
)
317 bt_get(bt_event_class_borrow_stream_class(event_class
)) :
321 struct bt_field_type
*bt_event_class_get_payload_type(
322 struct bt_event_class
*event_class
)
324 struct bt_field_type
*payload
= NULL
;
327 BT_LOGW_STR("Invalid parameter: event class is NULL.");
331 bt_get(event_class
->fields
);
332 payload
= event_class
->fields
;
337 int bt_event_class_set_payload_type(struct bt_event_class
*event_class
,
338 struct bt_field_type
*payload
)
343 BT_LOGW_STR("Invalid parameter: event class is NULL.");
348 if (payload
&& bt_field_type_get_type_id(payload
) !=
349 BT_FIELD_TYPE_ID_STRUCT
) {
350 BT_LOGW("Invalid parameter: event class's payload field type must be a structure: "
351 "addr=%p, name=\"%s\", id=%" PRId64
", "
352 "payload-ft-addr=%p, payload-ft-id=%s",
353 event_class
, bt_event_class_get_name(event_class
),
354 bt_event_class_get_id(event_class
), payload
,
355 bt_field_type_id_string(
356 bt_field_type_get_type_id(payload
)));
361 bt_put(event_class
->fields
);
362 event_class
->fields
= bt_get(payload
);
363 BT_LOGV("Set event class's payload field type: "
364 "event-class-addr=%p, event-class-name=\"%s\", "
365 "event-class-id=%" PRId64
", payload-ft-addr=%p",
366 event_class
, bt_event_class_get_name(event_class
),
367 bt_event_class_get_id(event_class
), payload
);
372 int bt_event_class_add_field(struct bt_event_class
*event_class
,
373 struct bt_field_type
*type
,
378 if (!event_class
|| !type
) {
379 BT_LOGW("Invalid parameter: event class or field type is NULL: "
380 "event-class-addr=%p, field-type-addr=%p",
386 if (!bt_identifier_is_valid(name
)) {
387 BT_LOGW("Invalid parameter: event class's payload field type's field name is not a valid CTF identifier: "
388 "addr=%p, name=\"%s\", id=%" PRId64
", field-name=\"%s\"",
389 event_class
, bt_event_class_get_name(event_class
),
390 bt_event_class_get_id(event_class
),
396 if (event_class
->frozen
) {
397 BT_LOGW("Invalid parameter: event class is frozen: "
398 "addr=%p, name=\"%s\", id=%" PRId64
,
399 event_class
, bt_event_class_get_name(event_class
),
400 bt_event_class_get_id(event_class
));
405 if (!event_class
->fields
) {
406 BT_LOGW("Event class has no payload field type: "
407 "addr=%p, name=\"%s\", id=%" PRId64
,
408 event_class
, bt_event_class_get_name(event_class
),
409 bt_event_class_get_id(event_class
));
414 BT_ASSERT(bt_field_type_get_type_id(event_class
->fields
) ==
415 BT_FIELD_TYPE_ID_STRUCT
);
416 ret
= bt_field_type_structure_add_field(event_class
->fields
,
418 BT_LOGV("Added field to event class's payload field type: "
419 "event-class-addr=%p, event-class-name=\"%s\", "
420 "event-class-id=%" PRId64
", field-name=\"%s\", ft-addr=%p",
421 event_class
, bt_event_class_get_name(event_class
),
422 bt_event_class_get_id(event_class
), name
, type
);
427 int64_t bt_event_class_get_payload_type_field_count(
428 struct bt_event_class
*event_class
)
433 BT_LOGW_STR("Invalid parameter: event class is NULL.");
438 if (!event_class
->fields
) {
439 BT_LOGV("Event class has no payload field type: "
440 "addr=%p, name=\"%s\", id=%" PRId64
,
441 event_class
, bt_event_class_get_name(event_class
),
442 bt_event_class_get_id(event_class
));
447 BT_ASSERT(bt_field_type_get_type_id(event_class
->fields
) ==
448 BT_FIELD_TYPE_ID_STRUCT
);
449 ret
= bt_field_type_structure_get_field_count(event_class
->fields
);
454 int bt_event_class_get_payload_type_field_by_index(
455 struct bt_event_class
*event_class
,
456 const char **field_name
, struct bt_field_type
**field_type
,
462 BT_LOGW_STR("Invalid parameter: event class is NULL.");
467 if (!event_class
->fields
) {
468 BT_LOGV("Event class has no payload field type: "
469 "addr=%p, name=\"%s\", id=%" PRId64
", index=%" PRIu64
,
470 event_class
, bt_event_class_get_name(event_class
),
471 bt_event_class_get_id(event_class
), index
);
476 BT_ASSERT(bt_field_type_get_type_id(event_class
->fields
) ==
477 BT_FIELD_TYPE_ID_STRUCT
);
478 ret
= bt_field_type_structure_get_field_by_index(event_class
->fields
,
479 field_name
, field_type
, index
);
484 struct bt_field_type
*
485 bt_event_class_get_payload_type_field_type_by_name(
486 struct bt_event_class
*event_class
, const char *name
)
489 struct bt_field_type
*field_type
= NULL
;
491 if (!event_class
|| !name
) {
492 BT_LOGW("Invalid parameter: event class or name is NULL: "
493 "event-class-addr=%p, name-addr=%p",
498 if (!event_class
->fields
) {
499 BT_LOGV("Event class has no payload field type: "
500 "addr=%p, name=\"%s\", id=%" PRId64
,
501 event_class
, bt_event_class_get_name(event_class
),
502 bt_event_class_get_id(event_class
));
506 BT_ASSERT(bt_field_type_get_type_id(event_class
->fields
) ==
507 BT_FIELD_TYPE_ID_STRUCT
);
508 name_quark
= g_quark_try_string(name
);
510 BT_LOGE("Cannot get GQuark: string=\"%s\"", name
);
515 * No need to increment field_type's reference count since getting it
516 * from the structure already does.
518 field_type
= bt_field_type_structure_get_field_type_by_name(
519 event_class
->fields
, name
);
524 struct bt_field_type
*bt_event_class_get_context_type(
525 struct bt_event_class
*event_class
)
527 struct bt_field_type
*context_type
= NULL
;
530 BT_LOGW_STR("Invalid parameter: event class is NULL.");
534 if (!event_class
->context
) {
535 BT_LOGV("Event class has no context field type: "
536 "addr=%p, name=\"%s\", id=%" PRId64
,
537 event_class
, bt_event_class_get_name(event_class
),
538 bt_event_class_get_id(event_class
));
542 bt_get(event_class
->context
);
543 context_type
= event_class
->context
;
548 int bt_event_class_set_context_type(
549 struct bt_event_class
*event_class
,
550 struct bt_field_type
*context
)
555 BT_LOGW_STR("Invalid parameter: event class is NULL.");
560 if (event_class
->frozen
) {
561 BT_LOGW("Invalid parameter: event class is frozen: "
562 "addr=%p, name=\"%s\", id=%" PRId64
,
563 event_class
, bt_event_class_get_name(event_class
),
564 bt_event_class_get_id(event_class
));
569 if (context
&& bt_field_type_get_type_id(context
) !=
570 BT_FIELD_TYPE_ID_STRUCT
) {
571 BT_LOGW("Invalid parameter: event class's context field type must be a structure: "
572 "addr=%p, name=\"%s\", id=%" PRId64
", "
574 event_class
, bt_event_class_get_name(event_class
),
575 bt_event_class_get_id(event_class
),
576 bt_field_type_id_string(
577 bt_field_type_get_type_id(context
)));
582 bt_put(event_class
->context
);
583 event_class
->context
= bt_get(context
);
584 BT_LOGV("Set event class's context field type: "
585 "event-class-addr=%p, event-class-name=\"%s\", "
586 "event-class-id=%" PRId64
", context-ft-addr=%p",
587 event_class
, bt_event_class_get_name(event_class
),
588 bt_event_class_get_id(event_class
), context
);
594 /* Pre-2.0 CTF writer backward compatibility */
595 void bt_ctf_event_class_get(struct bt_event_class
*event_class
)
600 /* Pre-2.0 CTF writer backward compatibility */
601 void bt_ctf_event_class_put(struct bt_event_class
*event_class
)
607 void bt_event_class_destroy(struct bt_object
*obj
)
609 struct bt_event_class
*event_class
;
611 event_class
= container_of(obj
, struct bt_event_class
, base
);
612 BT_LOGD("Destroying event class: addr=%p, name=\"%s\", id=%" PRId64
,
613 event_class
, bt_event_class_get_name(event_class
),
614 bt_event_class_get_id(event_class
));
615 g_string_free(event_class
->name
, TRUE
);
616 g_string_free(event_class
->emf_uri
, TRUE
);
617 BT_LOGD_STR("Putting context field type.");
618 bt_put(event_class
->context
);
619 BT_LOGD_STR("Putting payload field type.");
620 bt_put(event_class
->fields
);
625 void bt_event_class_freeze(struct bt_event_class
*event_class
)
627 BT_ASSERT(event_class
);
629 if (event_class
->frozen
) {
633 BT_LOGD("Freezing event class: addr=%p, name=\"%s\", id=%" PRId64
,
634 event_class
, bt_event_class_get_name(event_class
),
635 bt_event_class_get_id(event_class
));
636 event_class
->frozen
= 1;
637 BT_LOGD_STR("Freezing event class's context field type.");
638 bt_field_type_freeze(event_class
->context
);
639 BT_LOGD_STR("Freezing event class's payload field type.");
640 bt_field_type_freeze(event_class
->fields
);
644 int bt_event_class_serialize(struct bt_event_class
*event_class
,
645 struct metadata_context
*context
)
648 struct bt_value
*attr_value
= NULL
;
650 BT_ASSERT(event_class
);
652 BT_LOGD("Serializing event class's metadata: "
653 "event-class-addr=%p, event-class-name=\"%s\", "
654 "event-class-id=%" PRId64
", metadata-context-addr=%p",
655 event_class
, bt_event_class_get_name(event_class
),
656 bt_event_class_get_id(event_class
), context
);
657 context
->current_indentation_level
= 1;
658 g_string_assign(context
->field_name
, "");
659 g_string_append(context
->string
, "event {\n");
661 /* Serialize attributes */
662 g_string_append_printf(context
->string
, "\tname = \"%s\";\n",
663 event_class
->name
->str
);
664 BT_ASSERT(event_class
->id
>= 0);
665 g_string_append_printf(context
->string
, "\tid = %" PRId64
";\n",
667 g_string_append_printf(context
->string
, "\tstream_id = %" PRId64
";\n",
668 bt_stream_class_get_id(
669 bt_event_class_borrow_stream_class(event_class
)));
671 if (event_class
->log_level
!= BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED
) {
672 g_string_append_printf(context
->string
, "\tloglevel = %d;\n",
673 (int) event_class
->log_level
);
676 if (event_class
->emf_uri
->len
> 0) {
677 g_string_append_printf(context
->string
, "\tmodel.emf.uri = \"%s\";\n",
678 event_class
->emf_uri
->str
);
681 /* Serialize context field type */
682 if (event_class
->context
) {
683 g_string_append(context
->string
, "\tcontext := ");
684 BT_LOGD_STR("Serializing event class's context field type metadata.");
685 ret
= bt_field_type_serialize(event_class
->context
,
688 BT_LOGW("Cannot serialize event class's context field type's metadata: "
692 g_string_append(context
->string
, ";\n");
695 /* Serialize payload field type */
696 if (event_class
->fields
) {
697 g_string_append(context
->string
, "\tfields := ");
698 BT_LOGD_STR("Serializing event class's payload field type metadata.");
699 ret
= bt_field_type_serialize(event_class
->fields
, context
);
701 BT_LOGW("Cannot serialize event class's payload field type's metadata: "
705 g_string_append(context
->string
, ";\n");
708 g_string_append(context
->string
, "};\n\n");
710 context
->current_indentation_level
= 0;
716 int bt_event_class_validate_single_clock_class(
717 struct bt_event_class
*event_class
,
718 struct bt_clock_class
**expected_clock_class
)
722 BT_ASSERT(event_class
);
723 BT_ASSERT(expected_clock_class
);
724 ret
= bt_validate_single_clock_class(event_class
->context
,
725 expected_clock_class
);
727 BT_LOGW("Event class's context field type "
728 "is not recursively mapped to the "
729 "expected clock class: "
730 "event-class-addr=%p, "
731 "event-class-name=\"%s\", "
732 "event-class-id=%" PRId64
", "
735 bt_event_class_get_name(event_class
),
737 event_class
->context
);
741 ret
= bt_validate_single_clock_class(event_class
->fields
,
742 expected_clock_class
);
744 BT_LOGW("Event class's payload field type "
745 "is not recursively mapped to the "
746 "expected clock class: "
747 "event-class-addr=%p, "
748 "event-class-name=\"%s\", "
749 "event-class-id=%" PRId64
", "
752 bt_event_class_get_name(event_class
),
754 event_class
->fields
);