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>
49 #include <babeltrace/assert-pre-internal.h>
54 void bt_event_class_destroy(struct bt_object
*obj
);
56 struct bt_event_class
*bt_event_class_create(const char *name
)
58 struct bt_value
*obj
= NULL
;
59 struct bt_event_class
*event_class
= NULL
;
61 BT_LOGD("Creating event class object: name=\"%s\"",
65 BT_LOGW_STR("Invalid parameter: name is NULL.");
69 event_class
= g_new0(struct bt_event_class
, 1);
71 BT_LOGE_STR("Failed to allocate one event class.");
75 bt_object_init(event_class
, bt_event_class_destroy
);
76 event_class
->fields
= bt_field_type_structure_create();
77 if (!event_class
->fields
) {
78 BT_LOGE_STR("Cannot create event class's initial payload field type object.");
83 event_class
->name
= g_string_new(name
);
84 if (!event_class
->name
) {
85 BT_LOGE_STR("Failed to allocate a GString.");
89 event_class
->emf_uri
= g_string_new(NULL
);
90 if (!event_class
->emf_uri
) {
91 BT_LOGE_STR("Failed to allocate a GString.");
95 event_class
->log_level
= BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED
;
97 BT_LOGD("Created event class object: addr=%p, name=\"%s\"",
98 event_class
, bt_event_class_get_name(event_class
));
107 const char *bt_event_class_get_name(struct bt_event_class
*event_class
)
109 BT_ASSERT_PRE_NON_NULL(event_class
, "Event class");
110 BT_ASSERT(event_class
->name
);
111 return event_class
->name
->str
;
114 int64_t bt_event_class_get_id(struct bt_event_class
*event_class
)
116 BT_ASSERT_PRE_NON_NULL(event_class
, "Event class");
117 return event_class
->id
;
120 int bt_event_class_set_id(struct bt_event_class
*event_class
,
124 int64_t id
= (int64_t) id_param
;
127 BT_LOGW_STR("Invalid parameter: event class is NULL.");
132 if (event_class
->frozen
) {
133 BT_LOGW("Invalid parameter: event class is frozen: "
134 "addr=%p, name=\"%s\", id=%" PRId64
,
135 event_class
, bt_event_class_get_name(event_class
),
136 bt_event_class_get_id(event_class
));
142 BT_LOGW("Invalid parameter: invalid event class's ID: "
143 "addr=%p, name=\"%s\", id=%" PRIu64
,
144 event_class
, bt_event_class_get_name(event_class
),
150 event_class
->id
= id
;
151 BT_LOGV("Set event class's ID: "
152 "addr=%p, name=\"%s\", id=%" PRId64
,
153 event_class
, bt_event_class_get_name(event_class
), id
);
159 enum bt_event_class_log_level
bt_event_class_get_log_level(
160 struct bt_event_class
*event_class
)
162 BT_ASSERT_PRE_NON_NULL(event_class
, "Event class");
163 return event_class
->log_level
;
166 int bt_event_class_set_log_level(struct bt_event_class
*event_class
,
167 enum bt_event_class_log_level log_level
)
172 BT_LOGW_STR("Invalid parameter: event class is NULL.");
177 if (event_class
->frozen
) {
178 BT_LOGW("Invalid parameter: event class is frozen: "
179 "addr=%p, name=\"%s\", id=%" PRId64
,
180 event_class
, bt_event_class_get_name(event_class
),
181 bt_event_class_get_id(event_class
));
187 case BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED
:
188 case BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY
:
189 case BT_EVENT_CLASS_LOG_LEVEL_ALERT
:
190 case BT_EVENT_CLASS_LOG_LEVEL_CRITICAL
:
191 case BT_EVENT_CLASS_LOG_LEVEL_ERROR
:
192 case BT_EVENT_CLASS_LOG_LEVEL_WARNING
:
193 case BT_EVENT_CLASS_LOG_LEVEL_NOTICE
:
194 case BT_EVENT_CLASS_LOG_LEVEL_INFO
:
195 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM
:
196 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM
:
197 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS
:
198 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE
:
199 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT
:
200 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION
:
201 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE
:
202 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG
:
205 BT_LOGW("Invalid parameter: unknown event class log level: "
206 "addr=%p, name=\"%s\", id=%" PRId64
", log-level=%d",
207 event_class
, bt_event_class_get_name(event_class
),
208 bt_event_class_get_id(event_class
), log_level
);
213 event_class
->log_level
= log_level
;
214 BT_LOGV("Set event class's log level: "
215 "addr=%p, name=\"%s\", id=%" PRId64
", log-level=%s",
216 event_class
, bt_event_class_get_name(event_class
),
217 bt_event_class_get_id(event_class
),
218 bt_event_class_log_level_string(log_level
));
224 const char *bt_event_class_get_emf_uri(
225 struct bt_event_class
*event_class
)
227 const char *emf_uri
= NULL
;
229 BT_ASSERT_PRE_NON_NULL(event_class
, "Event class");
231 if (event_class
->emf_uri
->len
> 0) {
232 emf_uri
= event_class
->emf_uri
->str
;
238 int bt_event_class_set_emf_uri(struct bt_event_class
*event_class
,
244 BT_LOGW_STR("Invalid parameter: event class is NULL.");
249 if (emf_uri
&& strlen(emf_uri
) == 0) {
250 BT_LOGW_STR("Invalid parameter: EMF URI is empty.");
255 if (event_class
->frozen
) {
256 BT_LOGW("Invalid parameter: event class is frozen: "
257 "addr=%p, name=\"%s\", id=%" PRId64
,
258 event_class
, bt_event_class_get_name(event_class
),
259 bt_event_class_get_id(event_class
));
265 g_string_assign(event_class
->emf_uri
, emf_uri
);
266 BT_LOGV("Set event class's EMF URI: "
267 "addr=%p, name=\"%s\", id=%" PRId64
", emf-uri=\"%s\"",
268 event_class
, bt_event_class_get_name(event_class
),
269 bt_event_class_get_id(event_class
), emf_uri
);
271 g_string_assign(event_class
->emf_uri
, "");
272 BT_LOGV("Reset event class's EMF URI: "
273 "addr=%p, name=\"%s\", id=%" PRId64
,
274 event_class
, bt_event_class_get_name(event_class
),
275 bt_event_class_get_id(event_class
));
282 struct bt_stream_class
*bt_event_class_get_stream_class(
283 struct bt_event_class
*event_class
)
285 BT_ASSERT_PRE_NON_NULL(event_class
, "Event class");
286 return bt_get(bt_event_class_borrow_stream_class(event_class
));
289 struct bt_field_type
*bt_event_class_get_payload_type(
290 struct bt_event_class
*event_class
)
292 BT_ASSERT_PRE_NON_NULL(event_class
, "Event class");
293 return bt_get(event_class
->fields
);
296 int bt_event_class_set_payload_type(struct bt_event_class
*event_class
,
297 struct bt_field_type
*payload
)
302 BT_LOGW_STR("Invalid parameter: event class is NULL.");
307 if (payload
&& bt_field_type_get_type_id(payload
) !=
308 BT_FIELD_TYPE_ID_STRUCT
) {
309 BT_LOGW("Invalid parameter: event class's payload field type must be a structure: "
310 "addr=%p, name=\"%s\", id=%" PRId64
", "
311 "payload-ft-addr=%p, payload-ft-id=%s",
312 event_class
, bt_event_class_get_name(event_class
),
313 bt_event_class_get_id(event_class
), payload
,
314 bt_field_type_id_string(
315 bt_field_type_get_type_id(payload
)));
320 bt_put(event_class
->fields
);
321 event_class
->fields
= bt_get(payload
);
322 BT_LOGV("Set event class's payload field type: "
323 "event-class-addr=%p, event-class-name=\"%s\", "
324 "event-class-id=%" PRId64
", payload-ft-addr=%p",
325 event_class
, bt_event_class_get_name(event_class
),
326 bt_event_class_get_id(event_class
), payload
);
331 int bt_event_class_add_field(struct bt_event_class
*event_class
,
332 struct bt_field_type
*type
,
337 if (!event_class
|| !type
) {
338 BT_LOGW("Invalid parameter: event class or field type is NULL: "
339 "event-class-addr=%p, field-type-addr=%p",
345 if (!bt_identifier_is_valid(name
)) {
346 BT_LOGW("Invalid parameter: event class's payload field type's field name is not a valid CTF identifier: "
347 "addr=%p, name=\"%s\", id=%" PRId64
", field-name=\"%s\"",
348 event_class
, bt_event_class_get_name(event_class
),
349 bt_event_class_get_id(event_class
),
355 if (event_class
->frozen
) {
356 BT_LOGW("Invalid parameter: event class is frozen: "
357 "addr=%p, name=\"%s\", id=%" PRId64
,
358 event_class
, bt_event_class_get_name(event_class
),
359 bt_event_class_get_id(event_class
));
364 if (!event_class
->fields
) {
365 BT_LOGW("Event class has no payload field type: "
366 "addr=%p, name=\"%s\", id=%" PRId64
,
367 event_class
, bt_event_class_get_name(event_class
),
368 bt_event_class_get_id(event_class
));
373 BT_ASSERT(bt_field_type_get_type_id(event_class
->fields
) ==
374 BT_FIELD_TYPE_ID_STRUCT
);
375 ret
= bt_field_type_structure_add_field(event_class
->fields
,
377 BT_LOGV("Added field to event class's payload field type: "
378 "event-class-addr=%p, event-class-name=\"%s\", "
379 "event-class-id=%" PRId64
", field-name=\"%s\", ft-addr=%p",
380 event_class
, bt_event_class_get_name(event_class
),
381 bt_event_class_get_id(event_class
), name
, type
);
386 int64_t bt_event_class_get_payload_type_field_count(
387 struct bt_event_class
*event_class
)
392 BT_LOGW_STR("Invalid parameter: event class is NULL.");
397 if (!event_class
->fields
) {
398 BT_LOGV("Event class has no payload field type: "
399 "addr=%p, name=\"%s\", id=%" PRId64
,
400 event_class
, bt_event_class_get_name(event_class
),
401 bt_event_class_get_id(event_class
));
406 BT_ASSERT(bt_field_type_get_type_id(event_class
->fields
) ==
407 BT_FIELD_TYPE_ID_STRUCT
);
408 ret
= bt_field_type_structure_get_field_count(event_class
->fields
);
413 int bt_event_class_get_payload_type_field_by_index(
414 struct bt_event_class
*event_class
,
415 const char **field_name
, struct bt_field_type
**field_type
,
421 BT_LOGW_STR("Invalid parameter: event class is NULL.");
426 if (!event_class
->fields
) {
427 BT_LOGV("Event class has no payload field type: "
428 "addr=%p, name=\"%s\", id=%" PRId64
", index=%" PRIu64
,
429 event_class
, bt_event_class_get_name(event_class
),
430 bt_event_class_get_id(event_class
), index
);
435 BT_ASSERT(bt_field_type_get_type_id(event_class
->fields
) ==
436 BT_FIELD_TYPE_ID_STRUCT
);
437 ret
= bt_field_type_structure_get_field_by_index(event_class
->fields
,
438 field_name
, field_type
, index
);
443 struct bt_field_type
*
444 bt_event_class_get_payload_type_field_type_by_name(
445 struct bt_event_class
*event_class
, const char *name
)
448 struct bt_field_type
*field_type
= NULL
;
450 if (!event_class
|| !name
) {
451 BT_LOGW("Invalid parameter: event class or name is NULL: "
452 "event-class-addr=%p, name-addr=%p",
457 if (!event_class
->fields
) {
458 BT_LOGV("Event class has no payload field type: "
459 "addr=%p, name=\"%s\", id=%" PRId64
,
460 event_class
, bt_event_class_get_name(event_class
),
461 bt_event_class_get_id(event_class
));
465 BT_ASSERT(bt_field_type_get_type_id(event_class
->fields
) ==
466 BT_FIELD_TYPE_ID_STRUCT
);
467 name_quark
= g_quark_try_string(name
);
469 BT_LOGE("Cannot get GQuark: string=\"%s\"", name
);
474 * No need to increment field_type's reference count since getting it
475 * from the structure already does.
477 field_type
= bt_field_type_structure_get_field_type_by_name(
478 event_class
->fields
, name
);
483 struct bt_field_type
*bt_event_class_get_context_type(
484 struct bt_event_class
*event_class
)
486 struct bt_field_type
*context_type
= NULL
;
488 BT_ASSERT_PRE_NON_NULL(event_class
, "Event class");
490 if (!event_class
->context
) {
491 BT_LOGV("Event class has no context field type: "
492 "addr=%p, name=\"%s\", id=%" PRId64
,
493 event_class
, bt_event_class_get_name(event_class
),
494 bt_event_class_get_id(event_class
));
498 context_type
= bt_get(event_class
->context
);
504 int bt_event_class_set_context_type(
505 struct bt_event_class
*event_class
,
506 struct bt_field_type
*context
)
511 BT_LOGW_STR("Invalid parameter: event class is NULL.");
516 if (event_class
->frozen
) {
517 BT_LOGW("Invalid parameter: event class is frozen: "
518 "addr=%p, name=\"%s\", id=%" PRId64
,
519 event_class
, bt_event_class_get_name(event_class
),
520 bt_event_class_get_id(event_class
));
525 if (context
&& bt_field_type_get_type_id(context
) !=
526 BT_FIELD_TYPE_ID_STRUCT
) {
527 BT_LOGW("Invalid parameter: event class's context field type must be a structure: "
528 "addr=%p, name=\"%s\", id=%" PRId64
", "
530 event_class
, bt_event_class_get_name(event_class
),
531 bt_event_class_get_id(event_class
),
532 bt_field_type_id_string(
533 bt_field_type_get_type_id(context
)));
538 bt_put(event_class
->context
);
539 event_class
->context
= bt_get(context
);
540 BT_LOGV("Set event class's context field type: "
541 "event-class-addr=%p, event-class-name=\"%s\", "
542 "event-class-id=%" PRId64
", context-ft-addr=%p",
543 event_class
, bt_event_class_get_name(event_class
),
544 bt_event_class_get_id(event_class
), context
);
550 /* Pre-2.0 CTF writer backward compatibility */
551 void bt_ctf_event_class_get(struct bt_event_class
*event_class
)
556 /* Pre-2.0 CTF writer backward compatibility */
557 void bt_ctf_event_class_put(struct bt_event_class
*event_class
)
563 void bt_event_class_destroy(struct bt_object
*obj
)
565 struct bt_event_class
*event_class
;
567 event_class
= container_of(obj
, struct bt_event_class
, base
);
568 BT_LOGD("Destroying event class: addr=%p, name=\"%s\", id=%" PRId64
,
569 event_class
, bt_event_class_get_name(event_class
),
570 bt_event_class_get_id(event_class
));
571 g_string_free(event_class
->name
, TRUE
);
572 g_string_free(event_class
->emf_uri
, TRUE
);
573 BT_LOGD_STR("Putting context field type.");
574 bt_put(event_class
->context
);
575 BT_LOGD_STR("Putting payload field type.");
576 bt_put(event_class
->fields
);
581 void bt_event_class_freeze(struct bt_event_class
*event_class
)
583 BT_ASSERT(event_class
);
585 if (event_class
->frozen
) {
589 BT_LOGD("Freezing event class: addr=%p, name=\"%s\", id=%" PRId64
,
590 event_class
, bt_event_class_get_name(event_class
),
591 bt_event_class_get_id(event_class
));
592 event_class
->frozen
= 1;
593 BT_LOGD_STR("Freezing event class's context field type.");
594 bt_field_type_freeze(event_class
->context
);
595 BT_LOGD_STR("Freezing event class's payload field type.");
596 bt_field_type_freeze(event_class
->fields
);
600 int bt_event_class_serialize(struct bt_event_class
*event_class
,
601 struct metadata_context
*context
)
604 struct bt_value
*attr_value
= NULL
;
606 BT_ASSERT(event_class
);
608 BT_LOGD("Serializing event class's metadata: "
609 "event-class-addr=%p, event-class-name=\"%s\", "
610 "event-class-id=%" PRId64
", metadata-context-addr=%p",
611 event_class
, bt_event_class_get_name(event_class
),
612 bt_event_class_get_id(event_class
), context
);
613 context
->current_indentation_level
= 1;
614 g_string_assign(context
->field_name
, "");
615 g_string_append(context
->string
, "event {\n");
617 /* Serialize attributes */
618 g_string_append_printf(context
->string
, "\tname = \"%s\";\n",
619 event_class
->name
->str
);
620 BT_ASSERT(event_class
->id
>= 0);
621 g_string_append_printf(context
->string
, "\tid = %" PRId64
";\n",
623 g_string_append_printf(context
->string
, "\tstream_id = %" PRId64
";\n",
624 bt_stream_class_get_id(
625 bt_event_class_borrow_stream_class(event_class
)));
627 if (event_class
->log_level
!= BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED
) {
628 g_string_append_printf(context
->string
, "\tloglevel = %d;\n",
629 (int) event_class
->log_level
);
632 if (event_class
->emf_uri
->len
> 0) {
633 g_string_append_printf(context
->string
, "\tmodel.emf.uri = \"%s\";\n",
634 event_class
->emf_uri
->str
);
637 /* Serialize context field type */
638 if (event_class
->context
) {
639 g_string_append(context
->string
, "\tcontext := ");
640 BT_LOGD_STR("Serializing event class's context field type metadata.");
641 ret
= bt_field_type_serialize(event_class
->context
,
644 BT_LOGW("Cannot serialize event class's context field type's metadata: "
648 g_string_append(context
->string
, ";\n");
651 /* Serialize payload field type */
652 if (event_class
->fields
) {
653 g_string_append(context
->string
, "\tfields := ");
654 BT_LOGD_STR("Serializing event class's payload field type metadata.");
655 ret
= bt_field_type_serialize(event_class
->fields
, context
);
657 BT_LOGW("Cannot serialize event class's payload field type's metadata: "
661 g_string_append(context
->string
, ";\n");
664 g_string_append(context
->string
, "};\n\n");
666 context
->current_indentation_level
= 0;
672 int bt_event_class_validate_single_clock_class(
673 struct bt_event_class
*event_class
,
674 struct bt_clock_class
**expected_clock_class
)
678 BT_ASSERT(event_class
);
679 BT_ASSERT(expected_clock_class
);
680 ret
= bt_validate_single_clock_class(event_class
->context
,
681 expected_clock_class
);
683 BT_LOGW("Event class's context field type "
684 "is not recursively mapped to the "
685 "expected clock class: "
686 "event-class-addr=%p, "
687 "event-class-name=\"%s\", "
688 "event-class-id=%" PRId64
", "
691 bt_event_class_get_name(event_class
),
693 event_class
->context
);
697 ret
= bt_validate_single_clock_class(event_class
->fields
,
698 expected_clock_class
);
700 BT_LOGW("Event class's payload field type "
701 "is not recursively mapped to the "
702 "expected clock class: "
703 "event-class-addr=%p, "
704 "event-class-name=\"%s\", "
705 "event-class-id=%" PRId64
", "
708 bt_event_class_get_name(event_class
),
710 event_class
->fields
);