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.
22 #include <babeltrace/babeltrace.h>
23 #include <babeltrace/format.h>
24 #include <babeltrace/ctf/events.h>
25 #include <babeltrace/ctf-ir/metadata.h>
26 #include <babeltrace/prio_heap.h>
27 #include <babeltrace/iterator-internal.h>
28 #include <babeltrace/ctf/events-internal.h>
29 #include <babeltrace/ctf/metadata.h>
32 #include "events-private.h"
35 * thread local storage to store the last error that occured
36 * while reading a field, this variable must be accessed by
37 * bt_ctf_field_get_error only
39 __thread
int bt_ctf_last_field_error
= 0;
41 const struct definition
*bt_ctf_get_top_level_scope(const struct bt_ctf_event
*ctf_event
,
42 enum bt_ctf_scope scope
)
44 const struct definition
*tmp
= NULL
;
45 const struct ctf_event_definition
*event
;
50 event
= ctf_event
->parent
;
52 case BT_TRACE_PACKET_HEADER
:
55 if (event
->stream
->trace_packet_header
)
56 tmp
= &event
->stream
->trace_packet_header
->p
;
58 case BT_STREAM_PACKET_CONTEXT
:
61 if (event
->stream
->stream_packet_context
)
62 tmp
= &event
->stream
->stream_packet_context
->p
;
64 case BT_STREAM_EVENT_HEADER
:
67 if (event
->stream
->stream_event_header
)
68 tmp
= &event
->stream
->stream_event_header
->p
;
70 case BT_STREAM_EVENT_CONTEXT
:
73 if (event
->stream
->stream_event_context
)
74 tmp
= &event
->stream
->stream_event_context
->p
;
76 case BT_EVENT_CONTEXT
:
77 if (event
->event_context
)
78 tmp
= &event
->event_context
->p
;
81 if (event
->event_fields
)
82 tmp
= &event
->event_fields
->p
;
91 const struct definition
*bt_ctf_get_field(const struct bt_ctf_event
*ctf_event
,
92 const struct definition
*scope
,
95 const struct definition
*def
;
96 char *field_underscore
;
98 if (!ctf_event
|| !scope
|| !field
)
101 def
= lookup_definition(scope
, field
);
103 * optionally a field can have an underscore prefix, try
104 * to lookup the field with this prefix if it failed
107 field_underscore
= g_new(char, strlen(field
) + 2);
108 field_underscore
[0] = '_';
109 strcpy(&field_underscore
[1], field
);
110 def
= lookup_definition(scope
, field_underscore
);
111 g_free(field_underscore
);
113 if (bt_ctf_field_type(bt_ctf_get_decl_from_def(def
)) == CTF_TYPE_VARIANT
) {
114 const struct definition_variant
*variant_definition
;
115 variant_definition
= container_of(def
,
116 const struct definition_variant
, p
);
117 return variant_definition
->current_field
;
122 const struct definition
*bt_ctf_get_index(const struct bt_ctf_event
*ctf_event
,
123 const struct definition
*field
,
126 struct definition
*ret
= NULL
;
128 if (!ctf_event
|| !field
)
131 if (bt_ctf_field_type(bt_ctf_get_decl_from_def(field
)) == CTF_TYPE_ARRAY
) {
132 struct definition_array
*array_definition
;
133 array_definition
= container_of(field
,
134 struct definition_array
, p
);
135 ret
= array_index(array_definition
, index
);
136 } else if (bt_ctf_field_type(bt_ctf_get_decl_from_def(field
)) == CTF_TYPE_SEQUENCE
) {
137 struct definition_sequence
*sequence_definition
;
138 sequence_definition
= container_of(field
,
139 struct definition_sequence
, p
);
140 ret
= sequence_index(sequence_definition
, index
);
145 const char *bt_ctf_event_name(const struct bt_ctf_event
*ctf_event
)
147 const struct ctf_event_declaration
*event_class
;
148 const struct ctf_stream_declaration
*stream_class
;
149 const struct ctf_event_definition
*event
;
154 event
= ctf_event
->parent
;
155 stream_class
= event
->stream
->stream_class
;
156 event_class
= g_ptr_array_index(stream_class
->events_by_id
,
157 event
->stream
->event_id
);
158 return g_quark_to_string(event_class
->name
);
161 const char *bt_ctf_field_name(const struct definition
*def
)
166 return rem_(g_quark_to_string(def
->name
));
169 enum ctf_type_id
bt_ctf_field_type(const struct declaration
*decl
)
172 return CTF_TYPE_UNKNOWN
;
177 int bt_ctf_get_field_list(const struct bt_ctf_event
*ctf_event
,
178 const struct definition
*scope
,
179 struct definition
const * const **list
,
182 if (!ctf_event
|| !scope
|| !list
|| !count
)
185 switch (bt_ctf_field_type(bt_ctf_get_decl_from_def(scope
))) {
186 case CTF_TYPE_INTEGER
:
188 case CTF_TYPE_STRING
:
191 case CTF_TYPE_STRUCT
:
193 const struct definition_struct
*def_struct
;
195 def_struct
= container_of(scope
, const struct definition_struct
, p
);
198 if (def_struct
->fields
->pdata
) {
199 *list
= (struct definition
const* const*) def_struct
->fields
->pdata
;
200 *count
= def_struct
->fields
->len
;
207 case CTF_TYPE_UNTAGGED_VARIANT
:
209 case CTF_TYPE_VARIANT
:
211 const struct definition_variant
*def_variant
;
213 def_variant
= container_of(scope
, const struct definition_variant
, p
);
216 if (def_variant
->fields
->pdata
) {
217 *list
= (struct definition
const* const*) def_variant
->fields
->pdata
;
218 *count
= def_variant
->fields
->len
;
227 const struct definition_array
*def_array
;
229 def_array
= container_of(scope
, const struct definition_array
, p
);
232 if (def_array
->elems
->pdata
) {
233 *list
= (struct definition
const* const*) def_array
->elems
->pdata
;
234 *count
= def_array
->elems
->len
;
241 case CTF_TYPE_SEQUENCE
:
243 const struct definition_sequence
*def_sequence
;
245 def_sequence
= container_of(scope
, const struct definition_sequence
, p
);
248 if (def_sequence
->elems
->pdata
) {
249 *list
= (struct definition
const* const*) def_sequence
->elems
->pdata
;
250 *count
= def_sequence
->elems
->len
;
270 struct bt_context
*bt_ctf_event_get_context(const struct bt_ctf_event
*ctf_event
)
272 struct bt_context
*ret
= NULL
;
273 const struct ctf_file_stream
*cfs
;
274 const struct ctf_trace
*trace
;
275 const struct ctf_event_definition
*event
;
280 event
= ctf_event
->parent
;
281 cfs
= container_of(event
->stream
, const struct ctf_file_stream
,
283 trace
= cfs
->parent
.stream_class
->trace
;
290 int bt_ctf_event_get_handle_id(const struct bt_ctf_event
*ctf_event
)
293 const struct ctf_file_stream
*cfs
;
294 const struct ctf_trace
*trace
;
295 const struct ctf_event_definition
*event
;
300 event
= ctf_event
->parent
;
301 cfs
= container_of(event
->stream
, const struct ctf_file_stream
,
303 trace
= cfs
->parent
.stream_class
->trace
;
305 ret
= trace
->handle
->id
;
310 uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event
*ctf_event
)
312 const struct ctf_event_definition
*event
;
317 event
= ctf_event
->parent
;
318 if (event
&& event
->stream
->has_timestamp
)
319 return event
->stream
->real_timestamp
;
324 uint64_t bt_ctf_get_cycles(const struct bt_ctf_event
*ctf_event
)
326 const struct ctf_event_definition
*event
;
331 event
= ctf_event
->parent
;
332 if (event
&& event
->stream
->has_timestamp
)
333 return event
->stream
->cycles_timestamp
;
338 static void bt_ctf_field_set_error(int error
)
340 bt_ctf_last_field_error
= error
;
343 int bt_ctf_field_get_error(void)
346 ret
= bt_ctf_last_field_error
;
347 bt_ctf_last_field_error
= 0;
352 static const struct declaration_integer
*
353 get_declaration_integer(const struct declaration
*decl
)
355 if (!decl
|| bt_ctf_field_type(decl
) != CTF_TYPE_INTEGER
)
357 return container_of(decl
, const struct declaration_integer
, p
);
360 static const struct declaration_string
*
361 get_declaration_string(const struct declaration
*decl
)
363 if (!decl
|| bt_ctf_field_type(decl
) != CTF_TYPE_STRING
)
365 return container_of(decl
, const struct declaration_string
, p
);
368 static const struct declaration_array
*
369 get_declaration_array(const struct declaration
*decl
)
371 if (!decl
|| bt_ctf_field_type(decl
) != CTF_TYPE_ARRAY
)
373 return container_of(decl
, const struct declaration_array
, p
);
376 static const struct declaration_sequence
*
377 get_declaration_sequence(const struct declaration
*decl
)
379 if (!decl
|| bt_ctf_field_type(decl
) != CTF_TYPE_SEQUENCE
)
381 return container_of(decl
, const struct declaration_sequence
, p
);
384 int bt_ctf_get_int_signedness(const struct declaration
*decl
)
386 const struct declaration_integer
*integer
;
388 integer
= get_declaration_integer(decl
);
390 bt_ctf_field_set_error(-EINVAL
);
393 return integer
->signedness
;
396 int bt_ctf_get_int_base(const struct declaration
*decl
)
398 const struct declaration_integer
*integer
;
400 integer
= get_declaration_integer(decl
);
402 bt_ctf_field_set_error(-EINVAL
);
405 return integer
->base
;
408 int bt_ctf_get_int_byte_order(const struct declaration
*decl
)
410 const struct declaration_integer
*integer
;
412 integer
= get_declaration_integer(decl
);
414 bt_ctf_field_set_error(-EINVAL
);
417 return integer
->byte_order
;
420 ssize_t
bt_ctf_get_int_len(const struct declaration
*decl
)
422 const struct declaration_integer
*integer
;
424 integer
= get_declaration_integer(decl
);
426 bt_ctf_field_set_error(-EINVAL
);
429 return (ssize_t
) integer
->len
;
432 const struct definition
*bt_ctf_get_enum_int(const struct definition
*field
)
434 const struct definition_enum
*def_enum
;
436 if (!field
|| bt_ctf_field_type(bt_ctf_get_decl_from_def(field
)) != CTF_TYPE_ENUM
) {
437 bt_ctf_field_set_error(-EINVAL
);
440 def_enum
= container_of(field
, const struct definition_enum
, p
);
441 return &def_enum
->integer
->p
;
444 const char *bt_ctf_get_enum_str(const struct definition
*field
)
446 const struct definition_enum
*def_enum
;
447 const struct declaration_enum
*decl_enum
;
451 if (!field
|| bt_ctf_field_type(bt_ctf_get_decl_from_def(field
)) != CTF_TYPE_ENUM
) {
452 bt_ctf_field_set_error(-EINVAL
);
455 def_enum
= container_of(field
, const struct definition_enum
, p
);
456 decl_enum
= def_enum
->declaration
;
457 if (get_int_signedness(&def_enum
->integer
->p
)) {
458 array
= enum_int_to_quark_set(decl_enum
,
459 get_signed_int(&def_enum
->integer
->p
));
461 array
= enum_uint_to_quark_set(decl_enum
,
462 get_unsigned_int(&def_enum
->integer
->p
));
465 bt_ctf_field_set_error(-ENOENT
);
469 if (array
->len
== 0) {
470 g_array_unref(array
);
471 bt_ctf_field_set_error(-ENOENT
);
474 /* Return first string. Arbitrary choice. */
475 ret
= g_quark_to_string(g_array_index(array
, GQuark
, 0));
476 g_array_unref(array
);
480 enum ctf_string_encoding
bt_ctf_get_encoding(const struct declaration
*decl
)
482 enum ctf_string_encoding ret
= 0;
483 enum ctf_type_id type
;
484 const struct declaration_integer
*integer
;
485 const struct declaration_string
*string
;
486 const struct declaration_array
*array
;
487 const struct declaration_sequence
*sequence
;
492 type
= bt_ctf_field_type(decl
);
496 array
= get_declaration_array(decl
);
499 integer
= get_declaration_integer(array
->elem
);
502 ret
= integer
->encoding
;
504 case CTF_TYPE_SEQUENCE
:
505 sequence
= get_declaration_sequence(decl
);
508 integer
= get_declaration_integer(sequence
->elem
);
511 ret
= integer
->encoding
;
513 case CTF_TYPE_STRING
:
514 string
= get_declaration_string(decl
);
517 ret
= string
->encoding
;
519 case CTF_TYPE_INTEGER
:
520 integer
= get_declaration_integer(decl
);
523 ret
= integer
->encoding
;
531 bt_ctf_field_set_error(-EINVAL
);
535 int bt_ctf_get_array_len(const struct declaration
*decl
)
537 const struct declaration_array
*array
;
539 array
= get_declaration_array(decl
);
545 bt_ctf_field_set_error(-EINVAL
);
549 uint64_t bt_ctf_get_uint64(const struct definition
*field
)
553 if (field
&& bt_ctf_field_type(bt_ctf_get_decl_from_def(field
)) == CTF_TYPE_INTEGER
)
554 ret
= get_unsigned_int(field
);
556 bt_ctf_field_set_error(-EINVAL
);
561 int64_t bt_ctf_get_int64(const struct definition
*field
)
565 if (field
&& bt_ctf_field_type(bt_ctf_get_decl_from_def(field
)) == CTF_TYPE_INTEGER
)
566 ret
= get_signed_int(field
);
568 bt_ctf_field_set_error(-EINVAL
);
573 char *bt_ctf_get_char_array(const struct definition
*field
)
578 if (field
&& bt_ctf_field_type(bt_ctf_get_decl_from_def(field
)) == CTF_TYPE_ARRAY
) {
579 char_array
= get_char_array(field
);
581 ret
= char_array
->str
;
585 bt_ctf_field_set_error(-EINVAL
);
591 char *bt_ctf_get_string(const struct definition
*field
)
595 if (field
&& bt_ctf_field_type(bt_ctf_get_decl_from_def(field
)) == CTF_TYPE_STRING
)
596 ret
= get_string(field
);
598 bt_ctf_field_set_error(-EINVAL
);
603 int bt_ctf_get_event_decl_list(int handle_id
, struct bt_context
*ctx
,
604 struct bt_ctf_event_decl
* const **list
,
607 struct bt_trace_handle
*handle
;
608 struct trace_descriptor
*td
;
609 struct ctf_trace
*tin
;
611 if (!ctx
|| !list
|| !count
)
614 handle
= g_hash_table_lookup(ctx
->trace_handles
,
615 (gpointer
) (unsigned long) handle_id
);
620 tin
= container_of(td
, struct ctf_trace
, parent
);
622 *list
= (struct bt_ctf_event_decl
* const*) tin
->event_declarations
->pdata
;
623 *count
= tin
->event_declarations
->len
;
630 const char *bt_ctf_get_decl_event_name(const struct bt_ctf_event_decl
*event
)
635 return g_quark_to_string(event
->parent
.name
);
638 int bt_ctf_get_decl_fields(struct bt_ctf_event_decl
*event_decl
,
639 enum bt_ctf_scope scope
,
640 struct bt_ctf_field_decl
const * const **list
,
644 GArray
*fields
= NULL
;
645 gpointer
*ret_list
= NULL
;
646 GPtrArray
*fields_array
= NULL
;
650 if (!event_decl
|| !list
|| !count
)
654 case BT_EVENT_CONTEXT
:
655 if (event_decl
->context_decl
) {
656 ret_list
= event_decl
->context_decl
->pdata
;
657 *count
= event_decl
->context_decl
->len
;
660 event_decl
->context_decl
= g_ptr_array_new();
661 if (!event_decl
->parent
.context_decl
) {
665 fields
= event_decl
->parent
.context_decl
->fields
;
666 fields_array
= event_decl
->context_decl
;
668 case BT_EVENT_FIELDS
:
669 if (event_decl
->fields_decl
) {
670 ret_list
= event_decl
->fields_decl
->pdata
;
671 *count
= event_decl
->fields_decl
->len
;
674 event_decl
->fields_decl
= g_ptr_array_new();
675 if (!event_decl
->parent
.fields_decl
) {
679 fields
= event_decl
->parent
.fields_decl
->fields
;
680 fields_array
= event_decl
->fields_decl
;
682 case BT_STREAM_PACKET_CONTEXT
:
683 if (event_decl
->packet_context_decl
) {
684 ret_list
= event_decl
->packet_context_decl
->pdata
;
685 *count
= event_decl
->packet_context_decl
->len
;
688 event_decl
->packet_context_decl
= g_ptr_array_new();
689 if (!event_decl
->parent
.stream
->packet_context_decl
) {
693 fields
= event_decl
->parent
.stream
->packet_context_decl
->fields
;
694 fields_array
= event_decl
->packet_context_decl
;
696 case BT_STREAM_EVENT_CONTEXT
:
697 if (event_decl
->event_context_decl
) {
698 ret_list
= event_decl
->event_context_decl
->pdata
;
699 *count
= event_decl
->event_context_decl
->len
;
702 event_decl
->event_context_decl
= g_ptr_array_new();
703 if (!event_decl
->parent
.stream
->event_context_decl
) {
707 fields
= event_decl
->parent
.stream
->event_context_decl
->fields
;
708 fields_array
= event_decl
->event_context_decl
;
710 case BT_STREAM_EVENT_HEADER
:
711 if (event_decl
->event_header_decl
) {
712 ret_list
= event_decl
->event_header_decl
->pdata
;
713 *count
= event_decl
->event_header_decl
->len
;
716 event_decl
->event_header_decl
= g_ptr_array_new();
717 if (!event_decl
->parent
.stream
->event_header_decl
) {
721 fields
= event_decl
->parent
.stream
->event_header_decl
->fields
;
722 fields_array
= event_decl
->event_header_decl
;
724 case BT_TRACE_PACKET_HEADER
:
725 if (event_decl
->packet_header_decl
) {
726 ret_list
= event_decl
->packet_header_decl
->pdata
;
727 *count
= event_decl
->packet_header_decl
->len
;
730 event_decl
->packet_header_decl
= g_ptr_array_new();
731 if (!event_decl
->parent
.stream
->trace
->packet_header_decl
) {
735 fields
= event_decl
->parent
.stream
->trace
->packet_header_decl
->fields
;
736 fields_array
= event_decl
->packet_header_decl
;
740 for (i
= 0; i
< fields
->len
; i
++) {
741 g_ptr_array_add(fields_array
,
742 &g_array_index(fields
,
743 struct declaration_field
, i
));
745 ret_list
= fields_array
->pdata
;
746 *count
= fields
->len
;
749 *list
= (struct bt_ctf_field_decl
const* const*) ret_list
;
754 const char *bt_ctf_get_decl_field_name(const struct bt_ctf_field_decl
*field
)
759 return rem_(g_quark_to_string(((struct declaration_field
*) field
)->name
));
762 const struct declaration
*bt_ctf_get_decl_from_def(const struct definition
*def
)
765 return def
->declaration
;
770 const struct declaration
*bt_ctf_get_decl_from_field_decl(
771 const struct bt_ctf_field_decl
*field
)
774 return ((struct declaration_field
*) field
)->declaration
;