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>
52 void bt_event_class_destroy(struct bt_object
*obj
);
54 struct bt_event_class
*bt_event_class_create(const char *name
)
56 struct bt_value
*obj
= NULL
;
57 struct bt_event_class
*event_class
= NULL
;
59 BT_LOGD("Creating event class object: name=\"%s\"",
63 BT_LOGW_STR("Invalid parameter: name is NULL.");
67 event_class
= g_new0(struct bt_event_class
, 1);
69 BT_LOGE_STR("Failed to allocate one event class.");
73 bt_object_init(event_class
, bt_event_class_destroy
);
74 event_class
->fields
= bt_field_type_structure_create();
75 if (!event_class
->fields
) {
76 BT_LOGE_STR("Cannot create event class's initial payload field type object.");
81 event_class
->name
= g_string_new(name
);
82 if (!event_class
->name
) {
83 BT_LOGE_STR("Failed to allocate a GString.");
87 event_class
->emf_uri
= g_string_new(NULL
);
88 if (!event_class
->emf_uri
) {
89 BT_LOGE_STR("Failed to allocate a GString.");
93 event_class
->log_level
= BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED
;
95 BT_LOGD("Created event class object: addr=%p, name=\"%s\"",
96 event_class
, bt_event_class_get_name(event_class
));
105 const char *bt_event_class_get_name(struct bt_event_class
*event_class
)
107 const char *name
= NULL
;
110 BT_LOGW_STR("Invalid parameter: event class is NULL.");
114 name
= event_class
->name
->str
;
120 int64_t bt_event_class_get_id(struct bt_event_class
*event_class
)
125 BT_LOGW_STR("Invalid parameter: event class is NULL.");
130 ret
= event_class
->id
;
136 int bt_event_class_set_id(struct bt_event_class
*event_class
,
140 int64_t id
= (int64_t) id_param
;
143 BT_LOGW_STR("Invalid parameter: event class is NULL.");
148 if (event_class
->frozen
) {
149 BT_LOGW("Invalid parameter: event class is frozen: "
150 "addr=%p, name=\"%s\", id=%" PRId64
,
151 event_class
, bt_event_class_get_name(event_class
),
152 bt_event_class_get_id(event_class
));
158 BT_LOGW("Invalid parameter: invalid event class's ID: "
159 "addr=%p, name=\"%s\", id=%" PRIu64
,
160 event_class
, bt_event_class_get_name(event_class
),
166 event_class
->id
= id
;
167 BT_LOGV("Set event class's ID: "
168 "addr=%p, name=\"%s\", id=%" PRId64
,
169 event_class
, bt_event_class_get_name(event_class
), id
);
175 enum bt_event_class_log_level
bt_event_class_get_log_level(
176 struct bt_event_class
*event_class
)
178 enum bt_event_class_log_level log_level
;
181 BT_LOGW_STR("Invalid parameter: event class is NULL.");
182 log_level
= BT_EVENT_CLASS_LOG_LEVEL_UNKNOWN
;
186 log_level
= event_class
->log_level
;
192 int bt_event_class_set_log_level(struct bt_event_class
*event_class
,
193 enum bt_event_class_log_level log_level
)
198 BT_LOGW_STR("Invalid parameter: event class is NULL.");
203 if (event_class
->frozen
) {
204 BT_LOGW("Invalid parameter: event class is frozen: "
205 "addr=%p, name=\"%s\", id=%" PRId64
,
206 event_class
, bt_event_class_get_name(event_class
),
207 bt_event_class_get_id(event_class
));
213 case BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED
:
214 case BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY
:
215 case BT_EVENT_CLASS_LOG_LEVEL_ALERT
:
216 case BT_EVENT_CLASS_LOG_LEVEL_CRITICAL
:
217 case BT_EVENT_CLASS_LOG_LEVEL_ERROR
:
218 case BT_EVENT_CLASS_LOG_LEVEL_WARNING
:
219 case BT_EVENT_CLASS_LOG_LEVEL_NOTICE
:
220 case BT_EVENT_CLASS_LOG_LEVEL_INFO
:
221 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM
:
222 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM
:
223 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS
:
224 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE
:
225 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT
:
226 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION
:
227 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE
:
228 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG
:
231 BT_LOGW("Invalid parameter: unknown event class log level: "
232 "addr=%p, name=\"%s\", id=%" PRId64
", log-level=%d",
233 event_class
, bt_event_class_get_name(event_class
),
234 bt_event_class_get_id(event_class
), log_level
);
239 event_class
->log_level
= log_level
;
240 BT_LOGV("Set event class's log level: "
241 "addr=%p, name=\"%s\", id=%" PRId64
", log-level=%s",
242 event_class
, bt_event_class_get_name(event_class
),
243 bt_event_class_get_id(event_class
),
244 bt_event_class_log_level_string(log_level
));
250 const char *bt_event_class_get_emf_uri(
251 struct bt_event_class
*event_class
)
253 const char *emf_uri
= NULL
;
256 BT_LOGW_STR("Invalid parameter: event class is NULL.");
260 if (event_class
->emf_uri
->len
> 0) {
261 emf_uri
= event_class
->emf_uri
->str
;
268 int bt_event_class_set_emf_uri(struct bt_event_class
*event_class
,
274 BT_LOGW_STR("Invalid parameter: event class is NULL.");
279 if (emf_uri
&& strlen(emf_uri
) == 0) {
280 BT_LOGW_STR("Invalid parameter: EMF URI is empty.");
285 if (event_class
->frozen
) {
286 BT_LOGW("Invalid parameter: event class is frozen: "
287 "addr=%p, name=\"%s\", id=%" PRId64
,
288 event_class
, bt_event_class_get_name(event_class
),
289 bt_event_class_get_id(event_class
));
295 g_string_assign(event_class
->emf_uri
, emf_uri
);
296 BT_LOGV("Set event class's EMF URI: "
297 "addr=%p, name=\"%s\", id=%" PRId64
", emf-uri=\"%s\"",
298 event_class
, bt_event_class_get_name(event_class
),
299 bt_event_class_get_id(event_class
), emf_uri
);
301 g_string_assign(event_class
->emf_uri
, "");
302 BT_LOGV("Reset event class's EMF URI: "
303 "addr=%p, name=\"%s\", id=%" PRId64
,
304 event_class
, bt_event_class_get_name(event_class
),
305 bt_event_class_get_id(event_class
));
312 struct bt_stream_class
*bt_event_class_get_stream_class(
313 struct bt_event_class
*event_class
)
316 bt_get(bt_event_class_borrow_stream_class(event_class
)) :
320 struct bt_field_type
*bt_event_class_get_payload_type(
321 struct bt_event_class
*event_class
)
323 struct bt_field_type
*payload
= NULL
;
326 BT_LOGW_STR("Invalid parameter: event class is NULL.");
330 bt_get(event_class
->fields
);
331 payload
= event_class
->fields
;
336 int bt_event_class_set_payload_type(struct bt_event_class
*event_class
,
337 struct bt_field_type
*payload
)
342 BT_LOGW_STR("Invalid parameter: event class is NULL.");
347 if (payload
&& bt_field_type_get_type_id(payload
) !=
348 BT_FIELD_TYPE_ID_STRUCT
) {
349 BT_LOGW("Invalid parameter: event class's payload field type must be a structure: "
350 "addr=%p, name=\"%s\", id=%" PRId64
", "
351 "payload-ft-addr=%p, payload-ft-id=%s",
352 event_class
, bt_event_class_get_name(event_class
),
353 bt_event_class_get_id(event_class
), payload
,
354 bt_field_type_id_string(
355 bt_field_type_get_type_id(payload
)));
360 bt_put(event_class
->fields
);
361 event_class
->fields
= bt_get(payload
);
362 BT_LOGV("Set event class's payload field type: "
363 "event-class-addr=%p, event-class-name=\"%s\", "
364 "event-class-id=%" PRId64
", payload-ft-addr=%p",
365 event_class
, bt_event_class_get_name(event_class
),
366 bt_event_class_get_id(event_class
), payload
);
371 int bt_event_class_add_field(struct bt_event_class
*event_class
,
372 struct bt_field_type
*type
,
377 if (!event_class
|| !type
) {
378 BT_LOGW("Invalid parameter: event class or field type is NULL: "
379 "event-class-addr=%p, field-type-addr=%p",
385 if (!bt_identifier_is_valid(name
)) {
386 BT_LOGW("Invalid parameter: event class's payload field type's field name is not a valid CTF identifier: "
387 "addr=%p, name=\"%s\", id=%" PRId64
", field-name=\"%s\"",
388 event_class
, bt_event_class_get_name(event_class
),
389 bt_event_class_get_id(event_class
),
395 if (event_class
->frozen
) {
396 BT_LOGW("Invalid parameter: event class is frozen: "
397 "addr=%p, name=\"%s\", id=%" PRId64
,
398 event_class
, bt_event_class_get_name(event_class
),
399 bt_event_class_get_id(event_class
));
404 if (!event_class
->fields
) {
405 BT_LOGW("Event class has no payload field type: "
406 "addr=%p, name=\"%s\", id=%" PRId64
,
407 event_class
, bt_event_class_get_name(event_class
),
408 bt_event_class_get_id(event_class
));
413 assert(bt_field_type_get_type_id(event_class
->fields
) ==
414 BT_FIELD_TYPE_ID_STRUCT
);
415 ret
= bt_field_type_structure_add_field(event_class
->fields
,
417 BT_LOGV("Added field to event class's payload field type: "
418 "event-class-addr=%p, event-class-name=\"%s\", "
419 "event-class-id=%" PRId64
", field-name=\"%s\", ft-addr=%p",
420 event_class
, bt_event_class_get_name(event_class
),
421 bt_event_class_get_id(event_class
), name
, type
);
426 int64_t bt_event_class_get_payload_type_field_count(
427 struct bt_event_class
*event_class
)
432 BT_LOGW_STR("Invalid parameter: event class is NULL.");
437 if (!event_class
->fields
) {
438 BT_LOGV("Event class has no payload field type: "
439 "addr=%p, name=\"%s\", id=%" PRId64
,
440 event_class
, bt_event_class_get_name(event_class
),
441 bt_event_class_get_id(event_class
));
446 assert(bt_field_type_get_type_id(event_class
->fields
) ==
447 BT_FIELD_TYPE_ID_STRUCT
);
448 ret
= bt_field_type_structure_get_field_count(event_class
->fields
);
453 int bt_event_class_get_payload_type_field_by_index(
454 struct bt_event_class
*event_class
,
455 const char **field_name
, struct bt_field_type
**field_type
,
461 BT_LOGW_STR("Invalid parameter: event class is NULL.");
466 if (!event_class
->fields
) {
467 BT_LOGV("Event class has no payload field type: "
468 "addr=%p, name=\"%s\", id=%" PRId64
", index=%" PRIu64
,
469 event_class
, bt_event_class_get_name(event_class
),
470 bt_event_class_get_id(event_class
), index
);
475 assert(bt_field_type_get_type_id(event_class
->fields
) ==
476 BT_FIELD_TYPE_ID_STRUCT
);
477 ret
= bt_field_type_structure_get_field_by_index(event_class
->fields
,
478 field_name
, field_type
, index
);
483 struct bt_field_type
*
484 bt_event_class_get_payload_type_field_type_by_name(
485 struct bt_event_class
*event_class
, const char *name
)
488 struct bt_field_type
*field_type
= NULL
;
490 if (!event_class
|| !name
) {
491 BT_LOGW("Invalid parameter: event class or name is NULL: "
492 "event-class-addr=%p, name-addr=%p",
497 if (!event_class
->fields
) {
498 BT_LOGV("Event class has no payload field type: "
499 "addr=%p, name=\"%s\", id=%" PRId64
,
500 event_class
, bt_event_class_get_name(event_class
),
501 bt_event_class_get_id(event_class
));
505 assert(bt_field_type_get_type_id(event_class
->fields
) ==
506 BT_FIELD_TYPE_ID_STRUCT
);
507 name_quark
= g_quark_try_string(name
);
509 BT_LOGE("Cannot get GQuark: string=\"%s\"", name
);
514 * No need to increment field_type's reference count since getting it
515 * from the structure already does.
517 field_type
= bt_field_type_structure_get_field_type_by_name(
518 event_class
->fields
, name
);
523 struct bt_field_type
*bt_event_class_get_context_type(
524 struct bt_event_class
*event_class
)
526 struct bt_field_type
*context_type
= NULL
;
529 BT_LOGW_STR("Invalid parameter: event class is NULL.");
533 if (!event_class
->context
) {
534 BT_LOGV("Event class has no context field type: "
535 "addr=%p, name=\"%s\", id=%" PRId64
,
536 event_class
, bt_event_class_get_name(event_class
),
537 bt_event_class_get_id(event_class
));
541 bt_get(event_class
->context
);
542 context_type
= event_class
->context
;
547 int bt_event_class_set_context_type(
548 struct bt_event_class
*event_class
,
549 struct bt_field_type
*context
)
554 BT_LOGW_STR("Invalid parameter: event class is NULL.");
559 if (event_class
->frozen
) {
560 BT_LOGW("Invalid parameter: event class is frozen: "
561 "addr=%p, name=\"%s\", id=%" PRId64
,
562 event_class
, bt_event_class_get_name(event_class
),
563 bt_event_class_get_id(event_class
));
568 if (context
&& bt_field_type_get_type_id(context
) !=
569 BT_FIELD_TYPE_ID_STRUCT
) {
570 BT_LOGW("Invalid parameter: event class's context field type must be a structure: "
571 "addr=%p, name=\"%s\", id=%" PRId64
", "
573 event_class
, bt_event_class_get_name(event_class
),
574 bt_event_class_get_id(event_class
),
575 bt_field_type_id_string(
576 bt_field_type_get_type_id(context
)));
581 bt_put(event_class
->context
);
582 event_class
->context
= bt_get(context
);
583 BT_LOGV("Set event class's context field type: "
584 "event-class-addr=%p, event-class-name=\"%s\", "
585 "event-class-id=%" PRId64
", context-ft-addr=%p",
586 event_class
, bt_event_class_get_name(event_class
),
587 bt_event_class_get_id(event_class
), context
);
593 /* Pre-2.0 CTF writer backward compatibility */
594 void bt_ctf_event_class_get(struct bt_event_class
*event_class
)
599 /* Pre-2.0 CTF writer backward compatibility */
600 void bt_ctf_event_class_put(struct bt_event_class
*event_class
)
606 void bt_event_class_destroy(struct bt_object
*obj
)
608 struct bt_event_class
*event_class
;
610 event_class
= container_of(obj
, struct bt_event_class
, base
);
611 BT_LOGD("Destroying event class: addr=%p, name=\"%s\", id=%" PRId64
,
612 event_class
, bt_event_class_get_name(event_class
),
613 bt_event_class_get_id(event_class
));
614 g_string_free(event_class
->name
, TRUE
);
615 g_string_free(event_class
->emf_uri
, TRUE
);
616 BT_LOGD_STR("Putting context field type.");
617 bt_put(event_class
->context
);
618 BT_LOGD_STR("Putting payload field type.");
619 bt_put(event_class
->fields
);
624 void bt_event_class_freeze(struct bt_event_class
*event_class
)
628 if (event_class
->frozen
) {
632 BT_LOGD("Freezing event class: addr=%p, name=\"%s\", id=%" PRId64
,
633 event_class
, bt_event_class_get_name(event_class
),
634 bt_event_class_get_id(event_class
));
635 event_class
->frozen
= 1;
636 BT_LOGD_STR("Freezing event class's context field type.");
637 bt_field_type_freeze(event_class
->context
);
638 BT_LOGD_STR("Freezing event class's payload field type.");
639 bt_field_type_freeze(event_class
->fields
);
643 int bt_event_class_serialize(struct bt_event_class
*event_class
,
644 struct metadata_context
*context
)
647 struct bt_value
*attr_value
= NULL
;
651 BT_LOGD("Serializing event class's metadata: "
652 "event-class-addr=%p, event-class-name=\"%s\", "
653 "event-class-id=%" PRId64
", metadata-context-addr=%p",
654 event_class
, bt_event_class_get_name(event_class
),
655 bt_event_class_get_id(event_class
), context
);
656 context
->current_indentation_level
= 1;
657 g_string_assign(context
->field_name
, "");
658 g_string_append(context
->string
, "event {\n");
660 /* Serialize attributes */
661 g_string_append_printf(context
->string
, "\tname = \"%s\";\n",
662 event_class
->name
->str
);
663 assert(event_class
->id
>= 0);
664 g_string_append_printf(context
->string
, "\tid = %" PRId64
";\n",
666 g_string_append_printf(context
->string
, "\tstream_id = %" PRId64
";\n",
667 bt_stream_class_get_id(
668 bt_event_class_borrow_stream_class(event_class
)));
670 if (event_class
->log_level
!= BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED
) {
671 g_string_append_printf(context
->string
, "\tloglevel = %d;\n",
672 (int) event_class
->log_level
);
675 if (event_class
->emf_uri
->len
> 0) {
676 g_string_append_printf(context
->string
, "\tmodel.emf.uri = \"%s\";\n",
677 event_class
->emf_uri
->str
);
680 /* Serialize context field type */
681 if (event_class
->context
) {
682 g_string_append(context
->string
, "\tcontext := ");
683 BT_LOGD_STR("Serializing event class's context field type metadata.");
684 ret
= bt_field_type_serialize(event_class
->context
,
687 BT_LOGW("Cannot serialize event class's context field type's metadata: "
691 g_string_append(context
->string
, ";\n");
694 /* Serialize payload field type */
695 if (event_class
->fields
) {
696 g_string_append(context
->string
, "\tfields := ");
697 BT_LOGD_STR("Serializing event class's payload field type metadata.");
698 ret
= bt_field_type_serialize(event_class
->fields
, context
);
700 BT_LOGW("Cannot serialize event class's payload field type's metadata: "
704 g_string_append(context
->string
, ";\n");
707 g_string_append(context
->string
, "};\n\n");
709 context
->current_indentation_level
= 0;
715 int bt_event_class_validate_single_clock_class(
716 struct bt_event_class
*event_class
,
717 struct bt_clock_class
**expected_clock_class
)
722 assert(expected_clock_class
);
723 ret
= bt_validate_single_clock_class(event_class
->context
,
724 expected_clock_class
);
726 BT_LOGW("Event class's context field type "
727 "is not recursively mapped to the "
728 "expected clock class: "
729 "event-class-addr=%p, "
730 "event-class-name=\"%s\", "
731 "event-class-id=%" PRId64
", "
734 bt_event_class_get_name(event_class
),
736 event_class
->context
);
740 ret
= bt_validate_single_clock_class(event_class
->fields
,
741 expected_clock_class
);
743 BT_LOGW("Event class's payload field type "
744 "is not recursively mapped to the "
745 "expected clock class: "
746 "event-class-addr=%p, "
747 "event-class-name=\"%s\", "
748 "event-class-id=%" PRId64
", "
751 bt_event_class_get_name(event_class
),
753 event_class
->fields
);