6 * Copyright 2011-2012 EfficiOS Inc. and Linux Foundation
8 * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
9 * Julien Desfossez <julien.desfossez@efficios.com>
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:
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
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
30 #include <babeltrace/babeltrace.h>
31 #include <babeltrace/format.h>
32 #include <babeltrace/ctf/events.h>
33 #include <babeltrace/ctf-ir/metadata.h>
34 #include <babeltrace/prio_heap.h>
35 #include <babeltrace/iterator-internal.h>
36 #include <babeltrace/ctf/events-internal.h>
37 #include <babeltrace/ctf/metadata.h>
40 #include "events-private.h"
43 * thread local storage to store the last error that occured
44 * while reading a field, this variable must be accessed by
45 * bt_ctf_field_get_error only
47 __thread
int bt_ctf_last_field_error
= 0;
49 const struct bt_definition
*bt_ctf_get_top_level_scope(const struct bt_ctf_event
*ctf_event
,
52 const struct bt_definition
*tmp
= NULL
;
53 const struct ctf_event_definition
*event
;
58 event
= ctf_event
->parent
;
60 case BT_TRACE_PACKET_HEADER
:
63 if (event
->stream
->trace_packet_header
)
64 tmp
= &event
->stream
->trace_packet_header
->p
;
66 case BT_STREAM_PACKET_CONTEXT
:
69 if (event
->stream
->stream_packet_context
)
70 tmp
= &event
->stream
->stream_packet_context
->p
;
72 case BT_STREAM_EVENT_HEADER
:
75 if (event
->stream
->stream_event_header
)
76 tmp
= &event
->stream
->stream_event_header
->p
;
78 case BT_STREAM_EVENT_CONTEXT
:
81 if (event
->stream
->stream_event_context
)
82 tmp
= &event
->stream
->stream_event_context
->p
;
84 case BT_EVENT_CONTEXT
:
85 if (event
->event_context
)
86 tmp
= &event
->event_context
->p
;
89 if (event
->event_fields
)
90 tmp
= &event
->event_fields
->p
;
99 const struct bt_definition
*bt_ctf_get_field(const struct bt_ctf_event
*ctf_event
,
100 const struct bt_definition
*scope
,
103 const struct bt_definition
*def
;
104 char *field_underscore
;
106 if (!ctf_event
|| !scope
|| !field
)
109 def
= bt_lookup_definition(scope
, field
);
111 * optionally a field can have an underscore prefix, try
112 * to lookup the field with this prefix if it failed
115 field_underscore
= g_new(char, strlen(field
) + 2);
116 field_underscore
[0] = '_';
117 strcpy(&field_underscore
[1], field
);
118 def
= bt_lookup_definition(scope
, field_underscore
);
119 g_free(field_underscore
);
121 if (bt_ctf_field_type(bt_ctf_get_decl_from_def(def
)) == CTF_TYPE_VARIANT
) {
122 const struct definition_variant
*variant_definition
;
123 variant_definition
= container_of(def
,
124 const struct definition_variant
, p
);
125 return variant_definition
->current_field
;
130 const struct bt_definition
*bt_ctf_get_index(const struct bt_ctf_event
*ctf_event
,
131 const struct bt_definition
*field
,
134 struct bt_definition
*ret
= NULL
;
136 if (!ctf_event
|| !field
)
139 if (bt_ctf_field_type(bt_ctf_get_decl_from_def(field
)) == CTF_TYPE_ARRAY
) {
140 struct definition_array
*array_definition
;
141 array_definition
= container_of(field
,
142 struct definition_array
, p
);
143 ret
= bt_array_index(array_definition
, index
);
144 } else if (bt_ctf_field_type(bt_ctf_get_decl_from_def(field
)) == CTF_TYPE_SEQUENCE
) {
145 struct definition_sequence
*sequence_definition
;
146 sequence_definition
= container_of(field
,
147 struct definition_sequence
, p
);
148 ret
= bt_sequence_index(sequence_definition
, index
);
153 const char *bt_ctf_event_name(const struct bt_ctf_event
*ctf_event
)
155 const struct ctf_event_declaration
*event_class
;
156 const struct ctf_stream_declaration
*stream_class
;
157 const struct ctf_event_definition
*event
;
162 event
= ctf_event
->parent
;
163 stream_class
= event
->stream
->stream_class
;
164 event_class
= g_ptr_array_index(stream_class
->events_by_id
,
165 event
->stream
->event_id
);
166 return g_quark_to_string(event_class
->name
);
169 const char *bt_ctf_field_name(const struct bt_definition
*def
)
171 if (!def
|| !def
->name
)
174 return rem_(g_quark_to_string(def
->name
));
177 enum ctf_type_id
bt_ctf_field_type(const struct bt_declaration
*decl
)
180 return CTF_TYPE_UNKNOWN
;
185 int bt_ctf_get_field_list(const struct bt_ctf_event
*ctf_event
,
186 const struct bt_definition
*scope
,
187 struct bt_definition
const * const **list
,
190 if (!ctf_event
|| !scope
|| !list
|| !count
)
193 switch (bt_ctf_field_type(bt_ctf_get_decl_from_def(scope
))) {
194 case CTF_TYPE_INTEGER
:
196 case CTF_TYPE_STRING
:
199 case CTF_TYPE_STRUCT
:
201 const struct definition_struct
*def_struct
;
203 def_struct
= container_of(scope
, const struct definition_struct
, p
);
206 if (def_struct
->fields
->pdata
) {
207 *list
= (struct bt_definition
const* const*) def_struct
->fields
->pdata
;
208 *count
= def_struct
->fields
->len
;
215 case CTF_TYPE_UNTAGGED_VARIANT
:
217 case CTF_TYPE_VARIANT
:
219 const struct definition_variant
*def_variant
;
221 def_variant
= container_of(scope
, const struct definition_variant
, p
);
224 if (def_variant
->fields
->pdata
) {
225 *list
= (struct bt_definition
const* const*) def_variant
->fields
->pdata
;
226 *count
= def_variant
->fields
->len
;
235 const struct definition_array
*def_array
;
237 def_array
= container_of(scope
, const struct definition_array
, p
);
240 if (def_array
->elems
->pdata
) {
241 *list
= (struct bt_definition
const* const*) def_array
->elems
->pdata
;
242 *count
= def_array
->elems
->len
;
249 case CTF_TYPE_SEQUENCE
:
251 const struct definition_sequence
*def_sequence
;
253 def_sequence
= container_of(scope
, const struct definition_sequence
, p
);
256 if (def_sequence
->elems
->pdata
) {
257 *list
= (struct bt_definition
const* const*) def_sequence
->elems
->pdata
;
258 *count
= (unsigned int) def_sequence
->length
->value
._unsigned
;
278 struct bt_context
*bt_ctf_event_get_context(const struct bt_ctf_event
*ctf_event
)
280 struct bt_context
*ret
= NULL
;
281 const struct ctf_file_stream
*cfs
;
282 const struct ctf_trace
*trace
;
283 const struct ctf_event_definition
*event
;
288 event
= ctf_event
->parent
;
289 cfs
= container_of(event
->stream
, const struct ctf_file_stream
,
291 trace
= cfs
->parent
.stream_class
->trace
;
292 if (trace
->parent
.ctx
)
293 ret
= trace
->parent
.ctx
;
298 int bt_ctf_event_get_handle_id(const struct bt_ctf_event
*ctf_event
)
301 const struct ctf_file_stream
*cfs
;
302 const struct ctf_trace
*trace
;
303 const struct ctf_event_definition
*event
;
308 event
= ctf_event
->parent
;
309 cfs
= container_of(event
->stream
, const struct ctf_file_stream
,
311 trace
= cfs
->parent
.stream_class
->trace
;
312 if (trace
->parent
.handle
)
313 ret
= trace
->parent
.handle
->id
;
318 int bt_ctf_get_timestamp(const struct bt_ctf_event
*ctf_event
, int64_t *timestamp
)
320 const struct ctf_event_definition
*event
;
322 if (!ctf_event
|| !timestamp
)
325 event
= ctf_event
->parent
;
326 if (event
&& event
->stream
->has_timestamp
)
327 *timestamp
= event
->stream
->real_timestamp
;
333 uint64_t bt_ctf_get_cycles(const struct bt_ctf_event
*ctf_event
)
335 const struct ctf_event_definition
*event
;
340 event
= ctf_event
->parent
;
341 if (event
&& event
->stream
->has_timestamp
)
342 return event
->stream
->cycles_timestamp
;
347 static void bt_ctf_field_set_error(int error
)
349 bt_ctf_last_field_error
= error
;
352 int bt_ctf_field_get_error(void)
355 ret
= bt_ctf_last_field_error
;
356 bt_ctf_last_field_error
= 0;
361 static const struct declaration_integer
*
362 get_declaration_integer(const struct bt_declaration
*decl
)
364 if (!decl
|| bt_ctf_field_type(decl
) != CTF_TYPE_INTEGER
)
366 return container_of(decl
, const struct declaration_integer
, p
);
369 static const struct declaration_string
*
370 get_declaration_string(const struct bt_declaration
*decl
)
372 if (!decl
|| bt_ctf_field_type(decl
) != CTF_TYPE_STRING
)
374 return container_of(decl
, const struct declaration_string
, p
);
377 static const struct declaration_array
*
378 get_declaration_array(const struct bt_declaration
*decl
)
380 if (!decl
|| bt_ctf_field_type(decl
) != CTF_TYPE_ARRAY
)
382 return container_of(decl
, const struct declaration_array
, p
);
385 static const struct declaration_sequence
*
386 get_declaration_sequence(const struct bt_declaration
*decl
)
388 if (!decl
|| bt_ctf_field_type(decl
) != CTF_TYPE_SEQUENCE
)
390 return container_of(decl
, const struct declaration_sequence
, p
);
393 int bt_ctf_get_int_signedness(const struct bt_declaration
*decl
)
395 const struct declaration_integer
*integer
;
397 integer
= get_declaration_integer(decl
);
399 bt_ctf_field_set_error(-EINVAL
);
402 return integer
->signedness
;
405 int bt_ctf_get_int_base(const struct bt_declaration
*decl
)
407 const struct declaration_integer
*integer
;
409 integer
= get_declaration_integer(decl
);
411 bt_ctf_field_set_error(-EINVAL
);
414 return integer
->base
;
417 int bt_ctf_get_int_byte_order(const struct bt_declaration
*decl
)
419 const struct declaration_integer
*integer
;
421 integer
= get_declaration_integer(decl
);
423 bt_ctf_field_set_error(-EINVAL
);
426 return integer
->byte_order
;
429 ssize_t
bt_ctf_get_int_len(const struct bt_declaration
*decl
)
431 const struct declaration_integer
*integer
;
433 integer
= get_declaration_integer(decl
);
435 bt_ctf_field_set_error(-EINVAL
);
438 return (ssize_t
) integer
->len
;
441 const struct bt_definition
*bt_ctf_get_enum_int(const struct bt_definition
*field
)
443 const struct definition_enum
*def_enum
;
445 if (!field
|| bt_ctf_field_type(bt_ctf_get_decl_from_def(field
)) != CTF_TYPE_ENUM
) {
446 bt_ctf_field_set_error(-EINVAL
);
449 def_enum
= container_of(field
, const struct definition_enum
, p
);
450 return &def_enum
->integer
->p
;
453 const char *bt_ctf_get_enum_str(const struct bt_definition
*field
)
455 const struct definition_enum
*def_enum
;
456 const struct declaration_enum
*decl_enum
;
460 if (!field
|| bt_ctf_field_type(bt_ctf_get_decl_from_def(field
)) != CTF_TYPE_ENUM
) {
461 bt_ctf_field_set_error(-EINVAL
);
464 def_enum
= container_of(field
, const struct definition_enum
, p
);
465 decl_enum
= def_enum
->declaration
;
466 if (bt_get_int_signedness(&def_enum
->integer
->p
)) {
467 array
= bt_enum_int_to_quark_set(decl_enum
,
468 bt_get_signed_int(&def_enum
->integer
->p
));
470 array
= bt_enum_uint_to_quark_set(decl_enum
,
471 bt_get_unsigned_int(&def_enum
->integer
->p
));
474 bt_ctf_field_set_error(-ENOENT
);
478 if (array
->len
== 0) {
479 g_array_unref(array
);
480 bt_ctf_field_set_error(-ENOENT
);
483 /* Return first string. Arbitrary choice. */
484 ret
= g_quark_to_string(g_array_index(array
, GQuark
, 0));
485 g_array_unref(array
);
489 enum ctf_string_encoding
bt_ctf_get_encoding(const struct bt_declaration
*decl
)
491 enum ctf_string_encoding ret
= 0;
492 enum ctf_type_id type
;
493 const struct declaration_integer
*integer
;
494 const struct declaration_string
*string
;
495 const struct declaration_array
*array
;
496 const struct declaration_sequence
*sequence
;
501 type
= bt_ctf_field_type(decl
);
505 array
= get_declaration_array(decl
);
508 integer
= get_declaration_integer(array
->elem
);
511 ret
= integer
->encoding
;
513 case CTF_TYPE_SEQUENCE
:
514 sequence
= get_declaration_sequence(decl
);
517 integer
= get_declaration_integer(sequence
->elem
);
520 ret
= integer
->encoding
;
522 case CTF_TYPE_STRING
:
523 string
= get_declaration_string(decl
);
526 ret
= string
->encoding
;
528 case CTF_TYPE_INTEGER
:
529 integer
= get_declaration_integer(decl
);
532 ret
= integer
->encoding
;
540 bt_ctf_field_set_error(-EINVAL
);
544 int bt_ctf_get_array_len(const struct bt_declaration
*decl
)
546 const struct declaration_array
*array
;
548 array
= get_declaration_array(decl
);
554 bt_ctf_field_set_error(-EINVAL
);
558 uint64_t bt_ctf_get_uint64(const struct bt_definition
*field
)
562 if (field
&& bt_ctf_field_type(bt_ctf_get_decl_from_def(field
)) == CTF_TYPE_INTEGER
)
563 ret
= bt_get_unsigned_int(field
);
565 bt_ctf_field_set_error(-EINVAL
);
570 int64_t bt_ctf_get_int64(const struct bt_definition
*field
)
574 if (field
&& bt_ctf_field_type(bt_ctf_get_decl_from_def(field
)) == CTF_TYPE_INTEGER
)
575 ret
= bt_get_signed_int(field
);
577 bt_ctf_field_set_error(-EINVAL
);
582 char *bt_ctf_get_char_array(const struct bt_definition
*field
)
587 if (field
&& bt_ctf_field_type(bt_ctf_get_decl_from_def(field
)) == CTF_TYPE_ARRAY
) {
588 char_array
= bt_get_char_array(field
);
590 ret
= char_array
->str
;
594 bt_ctf_field_set_error(-EINVAL
);
600 char *bt_ctf_get_string(const struct bt_definition
*field
)
604 if (field
&& bt_ctf_field_type(bt_ctf_get_decl_from_def(field
)) == CTF_TYPE_STRING
)
605 ret
= bt_get_string(field
);
607 bt_ctf_field_set_error(-EINVAL
);
612 double bt_ctf_get_float(const struct bt_definition
*field
)
616 if (field
&& bt_ctf_field_type(bt_ctf_get_decl_from_def(field
)) == CTF_TYPE_FLOAT
) {
617 ret
= bt_get_float(field
);
619 bt_ctf_field_set_error(-EINVAL
);
625 const struct bt_definition
*bt_ctf_get_variant(const struct bt_definition
*field
)
627 const struct bt_definition
*ret
= NULL
;
629 if (field
&& bt_ctf_field_type(
630 bt_ctf_get_decl_from_def(field
)) == CTF_TYPE_VARIANT
) {
631 struct definition_variant
*variant
= container_of(field
,
632 struct definition_variant
, p
);
634 ret
= bt_variant_get_current_field(variant
);
636 bt_ctf_field_set_error(-EINVAL
);
642 uint64_t bt_ctf_get_struct_field_count(const struct bt_definition
*field
)
645 const struct bt_declaration
*declaration
=
646 bt_ctf_get_decl_from_def(field
);
648 if (field
&& bt_ctf_field_type(declaration
) == CTF_TYPE_STRUCT
) {
649 const struct declaration_struct
*struct_declaration
=
650 container_of(declaration
, struct declaration_struct
, p
);
652 ret
= bt_struct_declaration_len(struct_declaration
);
654 bt_ctf_field_set_error(-EINVAL
);
660 const struct bt_definition
*bt_ctf_get_struct_field_index(
661 const struct bt_definition
*field
, uint64_t i
)
663 const struct bt_definition
*ret
= NULL
;
665 if (field
&& bt_ctf_field_type(
666 bt_ctf_get_decl_from_def(field
)) == CTF_TYPE_STRUCT
&&
667 i
< bt_ctf_get_struct_field_count(field
)) {
668 const struct definition_struct
*structure
= container_of(
669 field
, struct definition_struct
, p
);
671 ret
= bt_struct_definition_get_field_from_index(structure
, i
);
675 bt_ctf_field_set_error(-EINVAL
);
681 int bt_ctf_get_event_decl_list(int handle_id
, struct bt_context
*ctx
,
682 struct bt_ctf_event_decl
* const **list
,
685 struct bt_trace_handle
*handle
;
686 struct bt_trace_descriptor
*td
;
687 struct ctf_trace
*tin
;
689 if (!ctx
|| !list
|| !count
)
692 handle
= g_hash_table_lookup(ctx
->trace_handles
,
693 (gpointer
) (unsigned long) handle_id
);
698 tin
= container_of(td
, struct ctf_trace
, parent
);
700 *list
= (struct bt_ctf_event_decl
* const*) tin
->event_declarations
->pdata
;
701 *count
= tin
->event_declarations
->len
;
708 const char *bt_ctf_get_decl_event_name(const struct bt_ctf_event_decl
*event
)
713 return g_quark_to_string(event
->parent
.name
);
716 uint64_t bt_ctf_get_decl_event_id(const struct bt_ctf_event_decl
*event
)
719 return (uint64_t)(-1);
721 return event
->parent
.id
;
724 int bt_ctf_get_decl_fields(struct bt_ctf_event_decl
*event_decl
,
725 enum ctf_scope scope
,
726 struct bt_ctf_field_decl
const * const **list
,
730 GArray
*fields
= NULL
;
731 gpointer
*ret_list
= NULL
;
732 GPtrArray
*fields_array
= NULL
;
735 if (!event_decl
|| !list
|| !count
)
740 case BT_EVENT_CONTEXT
:
741 if (event_decl
->context_decl
) {
742 ret_list
= event_decl
->context_decl
->pdata
;
743 *count
= event_decl
->context_decl
->len
;
746 event_decl
->context_decl
= g_ptr_array_new();
747 if (!event_decl
->parent
.context_decl
) {
751 fields
= event_decl
->parent
.context_decl
->fields
;
752 fields_array
= event_decl
->context_decl
;
754 case BT_EVENT_FIELDS
:
755 if (event_decl
->fields_decl
) {
756 ret_list
= event_decl
->fields_decl
->pdata
;
757 *count
= event_decl
->fields_decl
->len
;
760 event_decl
->fields_decl
= g_ptr_array_new();
761 if (!event_decl
->parent
.fields_decl
) {
765 fields
= event_decl
->parent
.fields_decl
->fields
;
766 fields_array
= event_decl
->fields_decl
;
768 case BT_STREAM_PACKET_CONTEXT
:
769 if (event_decl
->packet_context_decl
) {
770 ret_list
= event_decl
->packet_context_decl
->pdata
;
771 *count
= event_decl
->packet_context_decl
->len
;
774 event_decl
->packet_context_decl
= g_ptr_array_new();
775 if (!event_decl
->parent
.stream
->packet_context_decl
) {
779 fields
= event_decl
->parent
.stream
->packet_context_decl
->fields
;
780 fields_array
= event_decl
->packet_context_decl
;
782 case BT_STREAM_EVENT_CONTEXT
:
783 if (event_decl
->event_context_decl
) {
784 ret_list
= event_decl
->event_context_decl
->pdata
;
785 *count
= event_decl
->event_context_decl
->len
;
788 event_decl
->event_context_decl
= g_ptr_array_new();
789 if (!event_decl
->parent
.stream
->event_context_decl
) {
793 fields
= event_decl
->parent
.stream
->event_context_decl
->fields
;
794 fields_array
= event_decl
->event_context_decl
;
796 case BT_STREAM_EVENT_HEADER
:
797 if (event_decl
->event_header_decl
) {
798 ret_list
= event_decl
->event_header_decl
->pdata
;
799 *count
= event_decl
->event_header_decl
->len
;
802 event_decl
->event_header_decl
= g_ptr_array_new();
803 if (!event_decl
->parent
.stream
->event_header_decl
) {
807 fields
= event_decl
->parent
.stream
->event_header_decl
->fields
;
808 fields_array
= event_decl
->event_header_decl
;
810 case BT_TRACE_PACKET_HEADER
:
811 if (event_decl
->packet_header_decl
) {
812 ret_list
= event_decl
->packet_header_decl
->pdata
;
813 *count
= event_decl
->packet_header_decl
->len
;
816 event_decl
->packet_header_decl
= g_ptr_array_new();
817 if (!event_decl
->parent
.stream
->trace
->packet_header_decl
) {
821 fields
= event_decl
->parent
.stream
->trace
->packet_header_decl
->fields
;
822 fields_array
= event_decl
->packet_header_decl
;
826 for (i
= 0; i
< fields
->len
; i
++) {
827 g_ptr_array_add(fields_array
,
828 &g_array_index(fields
,
829 struct declaration_field
, i
));
831 ret_list
= fields_array
->pdata
;
832 *count
= fields
->len
;
835 *list
= (struct bt_ctf_field_decl
const* const*) ret_list
;
840 const char *bt_ctf_get_decl_field_name(const struct bt_ctf_field_decl
*field
)
845 return rem_(g_quark_to_string(((struct declaration_field
*) field
)->name
));
848 const struct bt_declaration
*bt_ctf_get_decl_from_def(const struct bt_definition
*def
)
851 return def
->declaration
;
856 const struct bt_declaration
*bt_ctf_get_decl_from_field_decl(
857 const struct bt_ctf_field_decl
*field
)
860 return ((struct declaration_field
*) field
)->declaration
;