/tests/lib/test_bt_notification_heap
/tests/lib/test_bt_objects
/tests/lib/test_bt_values
-/tests/lib/test_ctf_ir_ref
+/tests/lib/test_trace_ir_ref
/tests/lib/test_ctf_writer
/tests/lib/test_ctf_writer_complete
/tests/lib/test_dwarf
/tests/lib/test_bt_notification_iterator
/tests/lib/test_cc_prio_map
/tests/lib/test_graph_topo
-/tests/lib/ctf-ir/test_ctf_ir
+/tests/lib/trace-ir/test_trace_ir
/tests/lib/ctf-writer/test_ctf_writer
/tests/plugins/test-utils-muxer
/tests/plugins/test-utils-muxer-complete
The scheme employed in Babeltrace to break this cycle consists in the
"children" holding *reverse component references* to their parents. That
-is, in the context of CTF IR, that event classes hold a reference to
-their parent stream class and stream classes hold a reference to their
-parent trace.
+is, in the context of the trace IR, that event classes hold a reference
+to their parent stream class and stream classes hold a reference to
+their parent trace.
On the other hand, parents hold *claiming aggregation references* to
their children. A claiming aggregation reference means that the object
lib/plugin/Makefile
lib/graph/Makefile
lib/graph/notification/Makefile
- lib/ctf-ir/Makefile
+ lib/trace-ir/Makefile
lib/ctf-writer/Makefile
include/Makefile
logging/Makefile
tests/cli/intersection/Makefile
tests/lib/Makefile
tests/lib/test-plugin-plugins/Makefile
- tests/lib/ctf-ir/Makefile
+ tests/lib/trace-ir/Makefile
tests/lib/ctf-writer/Makefile
tests/utils/common.sh
tests/utils/Makefile
AC_CONFIG_FILES([tests/cli/test_trimmer], [chmod +x tests/cli/test_trimmer])
AC_CONFIG_FILES([tests/lib/test_ctf_writer_complete], [chmod +x tests/lib/test_ctf_writer_complete])
AC_CONFIG_FILES([tests/lib/test_plugin_complete], [chmod +x tests/lib/test_plugin_complete])
-AC_CONFIG_FILES([tests/lib/ctf-ir/test_ctf_ir], [chmod +x tests/lib/ctf-ir/test_ctf_ir])
+AC_CONFIG_FILES([tests/lib/trace-ir/test_trace_ir], [chmod +x tests/lib/trace-ir/test_trace_ir])
AC_CONFIG_FILES([tests/lib/ctf-writer/test_ctf_writer], [chmod +x tests/lib/ctf-writer/test_ctf_writer])
AC_CONFIG_FILES([tests/plugins/test-utils-muxer-complete], [chmod +x tests/plugins/test-utils-muxer-complete])
AC_CONFIG_FILES([tests/plugins/test_lttng_utils_debug_info], [chmod +x tests/plugins/test_lttng_utils_debug_info])
babeltrace/ctf-writer/visitor.h \
babeltrace/ctf-writer/writer.h
-# CTF IR API
+# Legacy API (for CTF writer)
babeltracectfirincludedir = "$(includedir)/babeltrace/ctf-ir"
babeltracectfirinclude_HEADERS = \
- babeltrace/ctf-ir/clock-class.h \
- babeltrace/ctf-ir/clock-value.h \
babeltrace/ctf-ir/clock.h \
babeltrace/ctf-ir/event-class.h \
+ babeltrace/ctf-ir/event-fields.h \
+ babeltrace/ctf-ir/event-types.h \
babeltrace/ctf-ir/event.h \
- babeltrace/ctf-ir/event-header-field.h \
- babeltrace/ctf-ir/field-path.h \
babeltrace/ctf-ir/field-types.h \
babeltrace/ctf-ir/fields.h \
- babeltrace/ctf-ir/packet.h \
- babeltrace/ctf-ir/packet-context-field.h \
- babeltrace/ctf-ir/packet-header-field.h \
babeltrace/ctf-ir/stream-class.h \
babeltrace/ctf-ir/stream.h \
- babeltrace/ctf-ir/trace.h
+ babeltrace/ctf-ir/trace.h \
+ babeltrace/ctf-ir/utils.h
+
+
+# Trace IR API
+babeltracetraceirincludedir = "$(includedir)/babeltrace/trace-ir"
+babeltracetraceirinclude_HEADERS = \
+ babeltrace/trace-ir/clock-class.h \
+ babeltrace/trace-ir/clock-value.h \
+ babeltrace/trace-ir/event-class.h \
+ babeltrace/trace-ir/event.h \
+ babeltrace/trace-ir/event-header-field.h \
+ babeltrace/trace-ir/field-path.h \
+ babeltrace/trace-ir/field-types.h \
+ babeltrace/trace-ir/fields.h \
+ babeltrace/trace-ir/packet.h \
+ babeltrace/trace-ir/packet-context-field.h \
+ babeltrace/trace-ir/packet-header-field.h \
+ babeltrace/trace-ir/stream-class.h \
+ babeltrace/trace-ir/stream.h \
+ babeltrace/trace-ir/trace.h
# Plugin and plugin development API
babeltracepluginincludedir = "$(includedir)/babeltrace/plugin"
babeltrace/align-internal.h \
babeltrace/logging-internal.h \
babeltrace/endian-internal.h \
- babeltrace/ctf-ir/packet-internal.h \
- babeltrace/ctf-ir/event-class-internal.h \
- babeltrace/ctf-ir/utils-internal.h \
- babeltrace/ctf-ir/fields-internal.h \
- babeltrace/ctf-ir/stream-class-internal.h \
- babeltrace/ctf-ir/event-internal.h \
- babeltrace/ctf-ir/field-path-internal.h \
- babeltrace/ctf-ir/field-wrapper-internal.h \
- babeltrace/ctf-ir/trace-internal.h \
- babeltrace/ctf-ir/clock-class-internal.h \
- babeltrace/ctf-ir/field-types-internal.h \
- babeltrace/ctf-ir/clock-value-internal.h \
- babeltrace/ctf-ir/attributes-internal.h \
- babeltrace/ctf-ir/stream-internal.h \
- babeltrace/ctf-ir/resolve-field-path-internal.h \
+ babeltrace/trace-ir/packet-internal.h \
+ babeltrace/trace-ir/event-class-internal.h \
+ babeltrace/trace-ir/utils-internal.h \
+ babeltrace/trace-ir/fields-internal.h \
+ babeltrace/trace-ir/stream-class-internal.h \
+ babeltrace/trace-ir/event-internal.h \
+ babeltrace/trace-ir/field-path-internal.h \
+ babeltrace/trace-ir/field-wrapper-internal.h \
+ babeltrace/trace-ir/trace-internal.h \
+ babeltrace/trace-ir/clock-class-internal.h \
+ babeltrace/trace-ir/field-types-internal.h \
+ babeltrace/trace-ir/clock-value-internal.h \
+ babeltrace/trace-ir/attributes-internal.h \
+ babeltrace/trace-ir/stream-internal.h \
+ babeltrace/trace-ir/resolve-field-path-internal.h \
babeltrace/prio-heap-internal.h \
babeltrace/lib-logging-internal.h \
babeltrace/compiler-internal.h \
#include <babeltrace/ctf-writer/visitor.h>
#include <babeltrace/ctf-writer/writer.h>
-/* CTF IR API */
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/clock-value.h>
-#include <babeltrace/ctf-ir/clock.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/event-header-field.h>
-#include <babeltrace/ctf-ir/event.h>
-#include <babeltrace/ctf-ir/field-path.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/packet-context-field.h>
-#include <babeltrace/ctf-ir/packet-header-field.h>
-#include <babeltrace/ctf-ir/packet.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/trace.h>
+/* Trace IR API */
+#include <babeltrace/trace-ir/clock-class.h>
+#include <babeltrace/trace-ir/clock-value.h>
+#include <babeltrace/trace-ir/clock.h>
+#include <babeltrace/trace-ir/event-class.h>
+#include <babeltrace/trace-ir/event-header-field.h>
+#include <babeltrace/trace-ir/event.h>
+#include <babeltrace/trace-ir/field-path.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/trace-ir/packet-context-field.h>
+#include <babeltrace/trace-ir/packet-header-field.h>
+#include <babeltrace/trace-ir/packet.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/trace.h>
/* Plugin and plugin development API */
#include <babeltrace/plugin/plugin-dev.h>
#include <stdbool.h>
#include <babeltrace/assert-internal.h>
#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/field-path.h>
-#include <babeltrace/ctf-ir/event-class.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/field-path.h>
+#include <babeltrace/trace-ir/event-class.h>
#include <stdarg.h>
#include <inttypes.h>
#include <stdint.h>
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_ATTRIBUTES_H
-#define BABELTRACE_CTF_IR_ATTRIBUTES_H
-
-/*
- * attributes.c
- *
- * Babeltrace - CTF IR: Attributes internal
- *
- * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
- * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/values.h>
-
-BT_HIDDEN
-struct bt_value *bt_attributes_create(void);
-
-BT_HIDDEN
-void bt_attributes_destroy(struct bt_value *attr_obj);
-
-BT_HIDDEN
-int64_t bt_attributes_get_count(struct bt_value *attr_obj);
-
-BT_HIDDEN
-const char *bt_attributes_get_field_name(struct bt_value *attr_obj,
- uint64_t index);
-
-BT_HIDDEN
-struct bt_value *bt_attributes_borrow_field_value(struct bt_value *attr_obj,
- uint64_t index);
-
-BT_HIDDEN
-int bt_attributes_set_field_value(struct bt_value *attr_obj,
- const char *name, struct bt_value *value_obj);
-
-BT_HIDDEN
-struct bt_value *bt_attributes_borrow_field_value_by_name(
- struct bt_value *attr_obj, const char *name);
-
-BT_HIDDEN
-int bt_attributes_freeze(struct bt_value *attr_obj);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_ATTRIBUTES_H */
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_CLOCK_CLASS_INTERNAL_H
-#define BABELTRACE_CTF_IR_CLOCK_CLASS_INTERNAL_H
-
-/*
- * BabelTrace - CTF IR: Clock internal
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/object-pool-internal.h>
-#include <babeltrace/compat/uuid-internal.h>
-#include <babeltrace/types.h>
-#include <babeltrace/property-internal.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <glib.h>
-
-struct bt_clock_class {
- struct bt_object base;
-
- struct {
- GString *str;
-
- /* NULL or `str->str` above */
- const char *value;
- } name;
-
- struct {
- GString *str;
-
- /* NULL or `str->str` above */
- const char *value;
- } description;
-
- uint64_t frequency;
- uint64_t precision;
- int64_t offset_seconds;
- uint64_t offset_cycles;
-
- struct {
- uint8_t uuid[BABELTRACE_UUID_LEN];
-
- /* NULL or `uuid` above */
- bt_uuid value;
- } uuid;
-
- bool is_absolute;
-
- /*
- * This is computed every time you call
- * bt_clock_class_set_frequency() or
- * bt_clock_class_set_offset(), as well as initially. It is the
- * base offset in nanoseconds including both `offset_seconds`
- * and `offset_cycles` above in the result. It is used to
- * accelerate future calls to
- * bt_clock_value_get_ns_from_origin() and
- * bt_clock_class_cycles_to_ns_from_origin().
- *
- * `overflows` is true if the base offset cannot be computed
- * because of an overflow.
- */
- struct {
- int64_t value_ns;
- bool overflows;
- } base_offset;
-
- /* Pool of `struct bt_clock_value *` */
- struct bt_object_pool cv_pool;
-
- bool frozen;
-};
-
-BT_HIDDEN
-void _bt_clock_class_freeze(struct bt_clock_class *clock_class);
-
-#ifdef BT_DEV_MODE
-# define bt_clock_class_freeze _bt_clock_class_freeze
-#else
-# define bt_clock_class_freeze(_cc)
-#endif
-
-BT_HIDDEN
-bt_bool bt_clock_class_is_valid(struct bt_clock_class *clock_class);
-
-#endif /* BABELTRACE_CTF_IR_CLOCK_CLASS_INTERNAL_H */
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_CLOCK_CLASS_H
-#define BABELTRACE_CTF_IR_CLOCK_CLASS_H
-
-/*
- * BabelTrace - CTF IR: Clock class
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <stdint.h>
-
-/* For bt_bool, bt_uuid */
-#include <babeltrace/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_clock_class;
-struct bt_clock_value;
-
-extern struct bt_clock_class *bt_clock_class_create(void);
-
-extern const char *bt_clock_class_get_name(struct bt_clock_class *clock_class);
-
-extern int bt_clock_class_set_name(struct bt_clock_class *clock_class,
- const char *name);
-
-extern const char *bt_clock_class_get_description(
- struct bt_clock_class *clock_class);
-
-extern int bt_clock_class_set_description(struct bt_clock_class *clock_class,
- const char *description);
-
-extern uint64_t bt_clock_class_get_frequency(
- struct bt_clock_class *clock_class);
-
-extern int bt_clock_class_set_frequency(struct bt_clock_class *clock_class,
- uint64_t freq);
-
-extern uint64_t bt_clock_class_get_precision(
- struct bt_clock_class *clock_class);
-
-extern int bt_clock_class_set_precision(struct bt_clock_class *clock_class,
- uint64_t precision);
-
-extern void bt_clock_class_get_offset(struct bt_clock_class *clock_class,
- int64_t *seconds, uint64_t *cycles);
-
-extern int bt_clock_class_set_offset(struct bt_clock_class *clock_class,
- int64_t seconds, uint64_t cycles);
-
-extern bt_bool bt_clock_class_is_absolute(struct bt_clock_class *clock_class);
-
-extern int bt_clock_class_set_is_absolute(struct bt_clock_class *clock_class,
- bt_bool is_absolute);
-
-extern bt_uuid bt_clock_class_get_uuid(struct bt_clock_class *clock_class);
-
-extern int bt_clock_class_set_uuid(struct bt_clock_class *clock_class,
- bt_uuid uuid);
-
-extern int bt_clock_class_cycles_to_ns_from_origin(
- struct bt_clock_class *clock_class,
- uint64_t cycles, int64_t *ns_from_origin);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_CLOCK_CLASS_H */
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_CLOCK_VALUE_INTERNAL_H
-#define BABELTRACE_CTF_IR_CLOCK_VALUE_INTERNAL_H
-
-/*
- * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-struct bt_clock_class;
-
-struct bt_clock_value {
- struct bt_object base;
- struct bt_clock_class *clock_class;
- uint64_t value_cycles;
- bool ns_from_origin_overflows;
- int64_t ns_from_origin;
- bool is_set;
-};
-
-static inline
-void bt_clock_value_set(struct bt_clock_value *clock_value)
-{
- BT_ASSERT(clock_value);
- clock_value->is_set = true;
-}
-
-static inline
-void bt_clock_value_reset(struct bt_clock_value *clock_value)
-{
- BT_ASSERT(clock_value);
- clock_value->is_set = false;
-}
-
-static inline
-void set_ns_from_origin(struct bt_clock_value *clock_value)
-{
- if (bt_util_ns_from_origin(clock_value->clock_class, clock_value->value_cycles,
- &clock_value->ns_from_origin)) {
- clock_value->ns_from_origin_overflows = true;
- }
-
-}
-
-static inline
-void bt_clock_value_set_raw_value(struct bt_clock_value *clock_value,
- uint64_t cycles)
-{
- BT_ASSERT(clock_value);
- clock_value->value_cycles = cycles;
- set_ns_from_origin(clock_value);
- bt_clock_value_set(clock_value);
-}
-
-static inline
-void bt_clock_value_set_value_inline(struct bt_clock_value *clock_value,
- uint64_t raw_value)
-{
- bt_clock_value_set_raw_value(clock_value, raw_value);
-}
-
-BT_HIDDEN
-void bt_clock_value_destroy(struct bt_clock_value *clock_value);
-
-BT_HIDDEN
-struct bt_clock_value *bt_clock_value_new(struct bt_clock_class *clock_class);
-
-BT_HIDDEN
-struct bt_clock_value *bt_clock_value_create(
- struct bt_clock_class *clock_class);
-
-BT_HIDDEN
-void bt_clock_value_recycle(struct bt_clock_value *clock_value);
-
-BT_HIDDEN
-void bt_clock_value_set_raw_value(struct bt_clock_value *clock_value,
- uint64_t cycles);
-
-#endif /* BABELTRACE_CTF_IR_CLOCK_VALUE_INTERNAL_H */
+++ /dev/null
-#ifndef BABELTRACE_GRAPH_CLOCK_VALUE_SET_H
-#define BABELTRACE_GRAPH_CLOCK_VALUE_SET_H
-
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <stdint.h>
-#include <glib.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/assert-internal.h>
-
-struct bt_clock_value_set {
- /* Unique objects owned by this */
- GPtrArray *clock_values;
-
- /* Weak; points to one of the clock values above */
- struct bt_clock_value *default_cv;
-};
-
-static inline
-int bt_clock_value_set_initialize(struct bt_clock_value_set *cv_set)
-{
- int ret = 0;
-
- cv_set->clock_values = g_ptr_array_sized_new(1);
- if (!cv_set->clock_values) {
-#ifdef BT_LOGE_STR
- BT_LOGE_STR("Failed to allocate one GPtrArray.");
-#endif
-
- ret = -1;
- goto end;
- }
-
- cv_set->default_cv = NULL;
-
-end:
- return ret;
-}
-
-static inline
-void bt_clock_value_set_reset(struct bt_clock_value_set *cv_set)
-{
- uint64_t i;
-
- BT_ASSERT(cv_set);
- BT_ASSERT(cv_set->clock_values);
-
- for (i = 0; i < cv_set->clock_values->len; i++) {
- struct bt_clock_value *cv = cv_set->clock_values->pdata[i];
-
- BT_ASSERT(cv);
- bt_clock_value_reset(cv);
- }
-
- cv_set->default_cv = NULL;
-}
-
-static inline
-void bt_clock_value_set_finalize(struct bt_clock_value_set *cv_set)
-{
- uint64_t i;
-
- BT_ASSERT(cv_set);
-
- if (cv_set->clock_values) {
- for (i = 0; i < cv_set->clock_values->len; i++) {
- struct bt_clock_value *cv =
- cv_set->clock_values->pdata[i];
-
- BT_ASSERT(cv);
- bt_clock_value_recycle(cv);
- }
-
- g_ptr_array_free(cv_set->clock_values, TRUE);
- }
-
- cv_set->default_cv = NULL;
-}
-
-static inline
-int bt_clock_value_set_set_clock_value(struct bt_clock_value_set *cv_set,
- struct bt_clock_class *cc, uint64_t raw_value)
-{
- int ret = 0;
- struct bt_clock_value *clock_value = NULL;
- uint64_t i;
-
- BT_ASSERT(cv_set);
- BT_ASSERT(cc);
-
- /*
- * Check if we already have a value for this clock class.
- *
- * TODO: When we have many clock classes, make this more
- * efficient.
- */
- for (i = 0; i < cv_set->clock_values->len; i++) {
- struct bt_clock_value *cv = cv_set->clock_values->pdata[i];
-
- BT_ASSERT(cv);
-
- if (cv->clock_class == cc) {
- clock_value = cv;
- break;
- }
- }
-
- if (!clock_value) {
- clock_value = bt_clock_value_create(cc);
- if (!clock_value) {
-#ifdef BT_LIB_LOGE
- BT_LIB_LOGE("Cannot create a clock value from a clock class: "
- "%![cc-]+K", cc);
-#endif
-
- ret = -1;
- goto end;
- }
-
- g_ptr_array_add(cv_set->clock_values, clock_value);
- }
-
- bt_clock_value_set_value_inline(clock_value, raw_value);
-
-end:
- return ret;
-}
-
-static inline
-void bt_clock_value_set_set_default_clock_value(
- struct bt_clock_value_set *cv_set, uint64_t raw_value)
-{
- BT_ASSERT(cv_set);
- BT_ASSERT(cv_set->default_cv);
- bt_clock_value_set_value_inline(cv_set->default_cv, raw_value);
-}
-
-#endif /* BABELTRACE_GRAPH_CLOCK_VALUE_SET_H */
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_CLOCK_VALUE_H
-#define BABELTRACE_CTF_IR_CLOCK_VALUE_H
-
-/*
- * BabelTrace - CTF IR: Clock class
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_clock_class;
-struct bt_clock_value;
-
-enum bt_clock_value_status {
- BT_CLOCK_VALUE_STATUS_KNOWN,
- BT_CLOCK_VALUE_STATUS_UNKNOWN,
-};
-
-extern struct bt_clock_class *bt_clock_value_borrow_clock_class(
- struct bt_clock_value *clock_value);
-
-extern uint64_t bt_clock_value_get_value(
- struct bt_clock_value *clock_value);
-
-extern int bt_clock_value_get_ns_from_origin(
- struct bt_clock_value *clock_value, int64_t *ns_from_origin);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_CLOCK_VALUE_H */
-#ifndef BABELTRACE_CTF_IR_CLOCK_H
-#define BABELTRACE_CTF_IR_CLOCK_H
-
-/*
- * BabelTrace - CTF IR: Clock
- *
- * Copyright 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
+/* Pre-2.0 CTF writer backward compatibility */
#include <babeltrace/ctf-writer/clock.h>
-
-#endif /* BABELTRACE_CTF_IR_CLOCK_H */
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_EVENT_CLASS_INTERNAL_H
-#define BABELTRACE_CTF_IR_EVENT_CLASS_INTERNAL_H
-
-/*
- * Babeltrace - CTF IR: Event class internal
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/values.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/object-pool-internal.h>
-#include <babeltrace/property-internal.h>
-#include <glib.h>
-#include <stdbool.h>
-
-struct bt_event_class {
- struct bt_object base;
- struct bt_field_type *specific_context_ft;
- struct bt_field_type *payload_ft;
-
- struct {
- GString *str;
-
- /* NULL or `str->str` above */
- const char *value;
- } name;
-
- uint64_t id;
- struct bt_property_uint log_level;
-
- struct {
- GString *str;
-
- /* NULL or `str->str` above */
- const char *value;
- } emf_uri;
-
- /* Pool of `struct bt_event *` */
- struct bt_object_pool event_pool;
-
- bool frozen;
-};
-
-BT_HIDDEN
-void _bt_event_class_freeze(struct bt_event_class *event_class);
-
-#ifdef BT_DEV_MODE
-# define bt_event_class_freeze _bt_event_class_freeze
-#else
-# define bt_event_class_freeze(_ec)
-#endif
-
-static inline
-struct bt_stream_class *bt_event_class_borrow_stream_class_inline(
- struct bt_event_class *event_class)
-{
- BT_ASSERT(event_class);
- return (void *) bt_object_borrow_parent(&event_class->base);
-}
-
-#endif /* BABELTRACE_CTF_IR_EVENT_CLASS_INTERNAL_H */
-#ifndef BABELTRACE_CTF_IR_EVENT_CLASS_H
-#define BABELTRACE_CTF_IR_EVENT_CLASS_H
-
-/*
- * BabelTrace - CTF IR: Event class
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-/* For enum bt_property_availability */
-#include <babeltrace/property.h>
-
-#include <stdint.h>
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_event_class;
-struct bt_field_type;
-struct bt_stream_class;
-
-enum bt_event_class_log_level {
- BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY,
- BT_EVENT_CLASS_LOG_LEVEL_ALERT,
- BT_EVENT_CLASS_LOG_LEVEL_CRITICAL,
- BT_EVENT_CLASS_LOG_LEVEL_ERROR,
- BT_EVENT_CLASS_LOG_LEVEL_WARNING,
- BT_EVENT_CLASS_LOG_LEVEL_NOTICE,
- BT_EVENT_CLASS_LOG_LEVEL_INFO,
- BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM,
- BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM,
- BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS,
- BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE,
- BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT,
- BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION,
- BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE,
- BT_EVENT_CLASS_LOG_LEVEL_DEBUG,
-};
-
-extern struct bt_event_class *bt_event_class_create(
- struct bt_stream_class *stream_class);
-
-extern struct bt_event_class *bt_event_class_create_with_id(
- struct bt_stream_class *stream_class, uint64_t id);
-
-extern struct bt_stream_class *bt_event_class_borrow_stream_class(
- struct bt_event_class *event_class);
-
-extern const char *bt_event_class_get_name(struct bt_event_class *event_class);
-
-extern int bt_event_class_set_name(struct bt_event_class *event_class,
- const char *name);
-
-extern uint64_t bt_event_class_get_id(struct bt_event_class *event_class);
-
-extern enum bt_property_availability bt_event_class_get_log_level(
- struct bt_event_class *event_class,
- enum bt_event_class_log_level *log_level);
-
-extern int bt_event_class_set_log_level(struct bt_event_class *event_class,
- enum bt_event_class_log_level log_level);
-
-extern const char *bt_event_class_get_emf_uri(
- struct bt_event_class *event_class);
-
-extern int bt_event_class_set_emf_uri(struct bt_event_class *event_class,
- const char *emf_uri);
-
-extern struct bt_field_type *bt_event_class_borrow_specific_context_field_type(
- struct bt_event_class *event_class);
-
-extern int bt_event_class_set_specific_context_field_type(
- struct bt_event_class *event_class,
- struct bt_field_type *field_type);
-
-extern struct bt_field_type *bt_event_class_borrow_payload_field_type(
- struct bt_event_class *event_class);
-
-extern int bt_event_class_set_payload_field_type(
- struct bt_event_class *event_class,
- struct bt_field_type *field_type);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_EVENT_CLASS_H */
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/event-class.h>
--- /dev/null
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/event-fields.h>
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_EVENT_HEADER_FIELD_H
-#define BABELTRACE_CTF_IR_EVENT_HEADER_FIELD_H
-
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_stream_class;
-struct bt_event_header_field;
-struct bt_field;
-
-extern
-struct bt_event_header_field *bt_event_header_field_create(
- struct bt_stream_class *stream_class);
-
-extern
-struct bt_field *bt_event_header_field_borrow_field(
- struct bt_event_header_field *field);
-
-extern
-void bt_event_header_field_release(struct bt_event_header_field *field);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_EVENT_HEADER_FIELD_H */
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_EVENT_INTERNAL_H
-#define BABELTRACE_CTF_IR_EVENT_INTERNAL_H
-
-/*
- * Babeltrace - CTF IR: Event internal
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* Protection: this file uses BT_LIB_LOG*() macros directly */
-#ifndef BABELTRACE_LIB_LOGGING_INTERNAL_H
-# error Please define include <babeltrace/lib-logging-internal.h> before including this file.
-#endif
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/values.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
-#include <babeltrace/ctf-ir/packet.h>
-#include <babeltrace/ctf-ir/packet-internal.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/ctf-ir/field-wrapper-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <glib.h>
-
-#define BT_ASSERT_PRE_EVENT_HOT(_event) \
- BT_ASSERT_PRE_HOT((_event), "Event", ": %!+e", (_event))
-
-struct bt_event {
- struct bt_object base;
- struct bt_event_class *class;
- struct bt_packet *packet;
- struct bt_field_wrapper *header_field;
- struct bt_field *common_context_field;
- struct bt_field *specific_context_field;
- struct bt_field *payload_field;
- struct bt_clock_value *default_cv;
- bool frozen;
-};
-
-BT_HIDDEN
-void bt_event_destroy(struct bt_event *event);
-
-BT_HIDDEN
-struct bt_event *bt_event_new(struct bt_event_class *event_class);
-
-BT_HIDDEN
-void _bt_event_set_is_frozen(struct bt_event *event, bool is_frozen);
-
-#ifdef BT_DEV_MODE
-# define bt_event_set_is_frozen _bt_event_set_is_frozen
-#else
-# define bt_event_set_is_frozen(_event, _is_frozen)
-#endif
-
-BT_UNUSED
-static inline
-void _bt_event_reset_dev_mode(struct bt_event *event)
-{
- BT_ASSERT(event);
-
- if (event->header_field) {
- bt_field_set_is_frozen(
- event->header_field->field, false);
- bt_field_reset(
- event->header_field->field);
- }
-
- if (event->common_context_field) {
- bt_field_set_is_frozen(
- event->common_context_field, false);
- bt_field_reset(
- event->common_context_field);
- }
-
- if (event->specific_context_field) {
- bt_field_set_is_frozen(
- event->specific_context_field, false);
- bt_field_reset(event->specific_context_field);
- }
-
- if (event->payload_field) {
- bt_field_set_is_frozen(
- event->payload_field, false);
- bt_field_reset(event->payload_field);
- }
-}
-
-#ifdef BT_DEV_MODE
-# define bt_event_reset_dev_mode _bt_event_reset_dev_mode
-#else
-# define bt_event_reset_dev_mode(_x)
-#endif
-
-static inline
-void bt_event_reset(struct bt_event *event)
-{
- BT_ASSERT(event);
- BT_LIB_LOGD("Resetting event: %!+e", event);
- bt_event_set_is_frozen(event, false);
-
- if (event->default_cv) {
- bt_clock_value_reset(event->default_cv);
- }
-
- bt_object_put_no_null_check(&event->packet->base);
- event->packet = NULL;
-}
-
-static inline
-void bt_event_recycle(struct bt_event *event)
-{
- struct bt_event_class *event_class;
-
- BT_ASSERT(event);
- BT_LIB_LOGD("Recycling event: %!+e", event);
-
- /*
- * Those are the important ordered steps:
- *
- * 1. Reset the event object (put any permanent reference it
- * has, unfreeze it and its fields in developer mode, etc.),
- * but do NOT put its class's reference. This event class
- * contains the pool to which we're about to recycle this
- * event object, so we must guarantee its existence thanks
- * to this existing reference.
- *
- * 2. Move the event class reference to our `event_class`
- * variable so that we can set the event's class member
- * to NULL before recycling it. We CANNOT do this after
- * we put the event class reference because this bt_put()
- * could destroy the event class, also destroying its
- * event pool, thus also destroying our event object (this
- * would result in an invalid write access).
- *
- * 3. Recycle the event object.
- *
- * 4. Put our event class reference.
- */
- bt_event_reset(event);
- event_class = event->class;
- BT_ASSERT(event_class);
- event->class = NULL;
- bt_object_pool_recycle_object(&event_class->event_pool, event);
- bt_object_put_no_null_check(&event_class->base);
-}
-
-static inline
-void bt_event_set_packet(struct bt_event *event, struct bt_packet *packet)
-{
- BT_ASSERT_PRE_NON_NULL(event, "Event");
- BT_ASSERT_PRE_NON_NULL(packet, "Packet");
- BT_ASSERT_PRE_EVENT_HOT(event);
- BT_ASSERT_PRE(bt_event_class_borrow_stream_class(
- event->class) == packet->stream->class,
- "Packet's stream class and event's stream class differ: "
- "%![event-]+e, %![packet-]+a", event, packet);
-
- BT_ASSERT(!event->packet);
- event->packet = packet;
- bt_object_get_no_null_check_no_parent_check(&event->packet->base);
- BT_LIB_LOGV("Set event's packet: %![event-]+e, %![packet-]+a",
- event, packet);
-}
-
-static inline
-struct bt_event *bt_event_create(struct bt_event_class *event_class,
- struct bt_packet *packet)
-{
- struct bt_event *event = NULL;
-
- BT_ASSERT(event_class);
- event = bt_object_pool_create_object(&event_class->event_pool);
- if (unlikely(!event)) {
- BT_LIB_LOGE("Cannot allocate one event from event class's event pool: "
- "%![ec-]+E", event_class);
- goto end;
- }
-
- if (likely(!event->class)) {
- event->class = event_class;
- bt_object_get_no_null_check(&event_class->base);
- }
-
- BT_ASSERT(packet);
- bt_event_set_packet(event, packet);
- goto end;
-
-end:
- return event;
-}
-
-#endif /* BABELTRACE_CTF_IR_EVENT_INTERNAL_H */
--- /dev/null
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/event-types.h>
-#ifndef BABELTRACE_CTF_IR_EVENT_H
-#define BABELTRACE_CTF_IR_EVENT_H
-
-/*
- * BabelTrace - CTF IR: Event
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <stdint.h>
-#include <stddef.h>
-
-/* For enum bt_clock_value_status */
-#include <babeltrace/ctf-ir/clock-value.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_event;
-struct bt_event_header_field;
-struct bt_clock_value;
-struct bt_event_class;
-struct bt_field;
-struct bt_packet;
-
-extern struct bt_event_class *bt_event_borrow_class(struct bt_event *event);
-
-extern struct bt_packet *bt_event_borrow_packet(struct bt_event *event);
-
-extern struct bt_stream *bt_event_borrow_stream(struct bt_event *event);
-
-extern struct bt_field *bt_event_borrow_header_field(struct bt_event *event);
-
-extern int bt_event_move_header(struct bt_event *event,
- struct bt_event_header_field *header);
-
-extern struct bt_field *bt_event_borrow_common_context_field(
- struct bt_event *event);
-
-extern struct bt_field *bt_event_borrow_specific_context_field(
- struct bt_event *event);
-
-extern struct bt_field *bt_event_borrow_payload_field(struct bt_event *event);
-
-extern int bt_event_set_default_clock_value(struct bt_event *event,
- uint64_t value_cycles);
-
-extern enum bt_clock_value_status bt_event_borrow_default_clock_value(
- struct bt_event *event, struct bt_clock_value **clock_value);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_EVENT_H */
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/event.h>
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_FIELD_PATH_INTERNAL
-#define BABELTRACE_CTF_IR_FIELD_PATH_INTERNAL
-
-/*
- * BabelTrace - CTF IR: Field path
- *
- * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <babeltrace/object-internal.h>
-#include <babeltrace/ctf-ir/field-path.h>
-#include <babeltrace/assert-internal.h>
-#include <glib.h>
-
-struct bt_field_path {
- struct bt_object base;
- enum bt_scope root;
-
- /* Array of `uint64_t` (indexes) */
- GArray *indexes;
-};
-
-BT_HIDDEN
-struct bt_field_path *bt_field_path_create(void);
-
-static inline
-uint64_t bt_field_path_get_index_by_index_inline(
- struct bt_field_path *field_path, uint64_t index)
-{
- BT_ASSERT(field_path);
- BT_ASSERT(index < field_path->indexes->len);
- return g_array_index(field_path->indexes, uint64_t, index);
-}
-
-#endif /* BABELTRACE_CTF_IR_FIELD_PATH_INTERNAL */
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_FIELD_PATH_H
-#define BABELTRACE_CTF_IR_FIELD_PATH_H
-
-/*
- * BabelTrace - CTF IR: Field path
- *
- * Copyright 2016-2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_field_path;
-
-enum bt_scope {
- BT_SCOPE_PACKET_HEADER,
- BT_SCOPE_PACKET_CONTEXT,
- BT_SCOPE_EVENT_HEADER,
- BT_SCOPE_EVENT_COMMON_CONTEXT,
- BT_SCOPE_EVENT_SPECIFIC_CONTEXT,
- BT_SCOPE_EVENT_PAYLOAD,
-};
-
-extern enum bt_scope bt_field_path_get_root_scope(
- struct bt_field_path *field_path);
-
-extern uint64_t bt_field_path_get_index_count(
- struct bt_field_path *field_path);
-
-extern uint64_t bt_field_path_get_index_by_index(
- struct bt_field_path *field_path, uint64_t index);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_FIELD_PATH_H */
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_FIELD_TYPES_INTERNAL_H
-#define BABELTRACE_CTF_IR_FIELD_TYPES_INTERNAL_H
-
-/*
- * BabelTrace - CTF IR: Event field types internal
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/types.h>
-#include <stdint.h>
-#include <glib.h>
-
-#define BT_ASSERT_PRE_FT_IS_INT(_ft, _name) \
- BT_ASSERT_PRE( \
- ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_INTEGER || \
- ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_SIGNED_INTEGER || \
- ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION || \
- ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_SIGNED_ENUMERATION, \
- _name " is not an integer field type: %![ft-]+F", (_ft))
-
-#define BT_ASSERT_PRE_FT_IS_UNSIGNED_INT(_ft, _name) \
- BT_ASSERT_PRE( \
- ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_INTEGER || \
- ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION, \
- _name " is not an unsigned integer field type: %![ft-]+F", (_ft))
-
-#define BT_ASSERT_PRE_FT_IS_ENUM(_ft, _name) \
- BT_ASSERT_PRE( \
- ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION || \
- ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_SIGNED_ENUMERATION, \
- _name " is not an enumeration field type: %![ft-]+F", (_ft))
-
-#define BT_ASSERT_PRE_FT_IS_ARRAY(_ft, _name) \
- BT_ASSERT_PRE( \
- ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_STATIC_ARRAY || \
- ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_DYNAMIC_ARRAY, \
- _name " is not an array field type: %![ft-]+F", (_ft))
-
-#define BT_ASSERT_PRE_FT_HAS_ID(_ft, _id, _name) \
- BT_ASSERT_PRE(((struct bt_field_type *) (_ft))->id == (_id), \
- _name " has the wrong ID: expected-id=%s, " \
- "%![ft-]+F", bt_common_field_type_id_string(_id), (_ft))
-
-#define BT_ASSERT_PRE_FT_HOT(_ft, _name) \
- BT_ASSERT_PRE_HOT((struct bt_field_type *) (_ft), \
- (_name), ": %!+F", (_ft))
-
-#define BT_FIELD_TYPE_NAMED_FT_AT_INDEX(_ft, _index) \
- (&g_array_index(((struct bt_field_type_named_field_types_container *) (_ft))->named_fts, \
- struct bt_named_field_type, (_index)))
-
-#define BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(_ft, _index) \
- (&g_array_index(((struct bt_field_type_enumeration *) (_ft))->mappings, \
- struct bt_field_type_enumeration_mapping, (_index)))
-
-#define BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(_mapping, _index) \
- (&g_array_index((_mapping)->ranges, \
- struct bt_field_type_enumeration_mapping_range, (_index)))
-
-struct bt_field;
-struct bt_field_type;
-
-struct bt_field_type {
- struct bt_object base;
- enum bt_field_type_id id;
- bool frozen;
-
- /*
- * Only used in developer mode, this flag indicates whether or
- * not this field type is part of a trace.
- */
- bool part_of_trace;
-};
-
-struct bt_field_type_integer {
- struct bt_field_type common;
-
- /*
- * Value range of fields built from this integer field type:
- * this is an equivalent integer size in bits. More formally,
- * `range` is `n` in:
- *
- * Unsigned range: [0, 2^n - 1]
- * Signed range: [-2^(n - 1), 2^(n - 1) - 1]
- */
- uint64_t range;
-
- enum bt_field_type_integer_preferred_display_base base;
-};
-
-struct bt_field_type_enumeration_mapping_range {
- union {
- uint64_t u;
- int64_t i;
- } lower;
-
- union {
- uint64_t u;
- int64_t i;
- } upper;
-};
-
-struct bt_field_type_enumeration_mapping {
- GString *label;
-
- /* Array of `struct bt_field_type_enumeration_mapping_range` */
- GArray *ranges;
-};
-
-struct bt_field_type_enumeration {
- struct bt_field_type_integer common;
-
- /* Array of `struct bt_field_type_enumeration_mapping *` */
- GArray *mappings;
-
- /*
- * This is an array of `const char *` which acts as a temporary
- * (potentially growing) buffer for
- * bt_field_type_unsigned_enumeration_get_mapping_labels_by_value()
- * and
- * bt_field_type_signed_enumeration_get_mapping_labels_by_value().
- *
- * The actual strings are owned by the mappings above.
- */
- GPtrArray *label_buf;
-};
-
-struct bt_field_type_real {
- struct bt_field_type common;
- bool is_single_precision;
-};
-
-struct bt_field_type_string {
- struct bt_field_type common;
-};
-
-/* A named field type is a (name, field type) pair */
-struct bt_named_field_type {
- GString *name;
-
- /* Owned by this */
- struct bt_field_type *ft;
-};
-
-/*
- * This is the base field type for a container of named field types.
- * Structure and variant field types inherit this.
- */
-struct bt_field_type_named_field_types_container {
- struct bt_field_type common;
-
- /*
- * Key: `const char *`, not owned by this (owned by named field
- * type objects contained in `named_fts` below).
- */
- GHashTable *name_to_index;
-
- /* Array of `struct bt_named_field_type` */
- GArray *named_fts;
-};
-
-struct bt_field_type_structure {
- struct bt_field_type_named_field_types_container common;
-};
-
-struct bt_field_type_array {
- struct bt_field_type common;
-
- /* Owned by this */
- struct bt_field_type *element_ft;
-};
-
-struct bt_field_type_static_array {
- struct bt_field_type_array common;
- uint64_t length;
-};
-
-struct bt_field_type_dynamic_array {
- struct bt_field_type_array common;
-
- /* Weak: never dereferenced, only use to find it elsewhere */
- struct bt_field_type *length_ft;
-
- /* Owned by this */
- struct bt_field_path *length_field_path;
-};
-
-struct bt_field_type_variant {
- struct bt_field_type_named_field_types_container common;
-
- /* Weak: never dereferenced, only use to find it elsewhere */
- struct bt_field_type *selector_ft;
-
- /* Owned by this */
- struct bt_field_path *selector_field_path;
-};
-
-static inline
-bool bt_field_type_has_known_id(struct bt_field_type *ft)
-{
- return ft->id >= BT_FIELD_TYPE_ID_UNSIGNED_INTEGER &&
- ft->id <= BT_FIELD_TYPE_ID_VARIANT;
-}
-
-BT_HIDDEN
-void _bt_field_type_freeze(struct bt_field_type *field_type);
-
-#ifdef BT_DEV_MODE
-# define bt_field_type_freeze _bt_field_type_freeze
-#else
-# define bt_field_type_freeze(_ft)
-#endif
-
-/*
- * This function recursively marks `field_type` and its children as
- * being part of a trace. This is used to validate that all field types
- * are used at a single location within trace objects even if they are
- * shared objects for other purposes.
- */
-BT_HIDDEN
-void _bt_field_type_make_part_of_trace(struct bt_field_type *field_type);
-
-#ifdef BT_DEV_MODE
-# define bt_field_type_make_part_of_trace _bt_field_type_make_part_of_trace
-#else
-# define bt_field_type_make_part_of_trace(_ft) ((void) _ft)
-#endif
-
-#endif /* BABELTRACE_CTF_IR_FIELD_TYPES_INTERNAL_H */
-#ifndef BABELTRACE_CTF_IR_FIELD_TYPES_H
-#define BABELTRACE_CTF_IR_FIELD_TYPES_H
-
-/*
- * BabelTrace - CTF IR: Event field types
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-/* For bt_get() */
-#include <babeltrace/ref.h>
-
-/* For bt_bool */
-#include <babeltrace/types.h>
-
-#include <stdint.h>
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_field_type;
-struct bt_field_path;
-struct bt_field_type_signed_enumeration_mapping_ranges;
-struct bt_field_type_unsigned_enumeration_mapping_ranges;
-
-typedef const char * const *bt_field_type_enumeration_mapping_label_array;
-
-enum bt_field_type_id {
- BT_FIELD_TYPE_ID_UNSIGNED_INTEGER,
- BT_FIELD_TYPE_ID_SIGNED_INTEGER,
- BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION,
- BT_FIELD_TYPE_ID_SIGNED_ENUMERATION,
- BT_FIELD_TYPE_ID_REAL,
- BT_FIELD_TYPE_ID_STRING,
- BT_FIELD_TYPE_ID_STRUCTURE,
- BT_FIELD_TYPE_ID_STATIC_ARRAY,
- BT_FIELD_TYPE_ID_DYNAMIC_ARRAY,
- BT_FIELD_TYPE_ID_VARIANT,
-};
-
-enum bt_field_type_integer_preferred_display_base {
- BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_BINARY,
- BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL,
- BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL,
- BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL,
-};
-
-extern enum bt_field_type_id bt_field_type_get_type_id(
- struct bt_field_type *field_type);
-
-extern struct bt_field_type *bt_field_type_unsigned_integer_create(void);
-
-extern struct bt_field_type *bt_field_type_signed_integer_create(void);
-
-extern uint64_t bt_field_type_integer_get_field_value_range(
- struct bt_field_type *field_type);
-
-extern int bt_field_type_integer_set_field_value_range(
- struct bt_field_type *field_type, uint64_t size);
-
-extern enum bt_field_type_integer_preferred_display_base
-bt_field_type_integer_get_preferred_display_base(
- struct bt_field_type *field_type);
-
-extern int bt_field_type_integer_set_preferred_display_base(
- struct bt_field_type *field_type,
- enum bt_field_type_integer_preferred_display_base base);
-
-extern struct bt_field_type *bt_field_type_real_create(void);
-
-extern bt_bool bt_field_type_real_is_single_precision(
- struct bt_field_type *field_type);
-
-extern int bt_field_type_real_set_is_single_precision(
- struct bt_field_type *field_type,
- bt_bool is_single_precision);
-
-extern struct bt_field_type *bt_field_type_unsigned_enumeration_create(void);
-
-extern struct bt_field_type *bt_field_type_signed_enumeration_create(void);
-
-extern uint64_t bt_field_type_enumeration_get_mapping_count(
- struct bt_field_type *field_type);
-
-extern void bt_field_type_unsigned_enumeration_borrow_mapping_by_index(
- struct bt_field_type *field_type, uint64_t index,
- const char **label,
- struct bt_field_type_unsigned_enumeration_mapping_ranges **ranges);
-
-extern void bt_field_type_signed_enumeration_borrow_mapping_by_index(
- struct bt_field_type *field_type, uint64_t index,
- const char **label,
- struct bt_field_type_signed_enumeration_mapping_ranges **ranges);
-
-extern uint64_t bt_field_type_unsigned_enumeration_mapping_ranges_get_range_count(
- struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges);
-
-extern uint64_t bt_field_type_signed_enumeration_mapping_ranges_get_range_count(
- struct bt_field_type_signed_enumeration_mapping_ranges *ranges);
-
-extern void bt_field_type_unsigned_enumeration_mapping_ranges_get_range_by_index(
- struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges,
- uint64_t index, uint64_t *lower, uint64_t *upper);
-
-extern void bt_field_type_signed_enumeration_mapping_ranges_get_range_by_index(
- struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges,
- uint64_t index, int64_t *lower, int64_t *upper);
-
-extern int bt_field_type_unsigned_enumeration_get_mapping_labels_by_value(
- struct bt_field_type *field_type, uint64_t value,
- bt_field_type_enumeration_mapping_label_array *label_array,
- uint64_t *count);
-
-extern int bt_field_type_signed_enumeration_get_mapping_labels_by_value(
- struct bt_field_type *field_type, int64_t value,
- bt_field_type_enumeration_mapping_label_array *label_array,
- uint64_t *count);
-
-extern int bt_field_type_unsigned_enumeration_map_range(
- struct bt_field_type *field_type, const char *label,
- uint64_t range_lower, uint64_t range_upper);
-
-extern int bt_field_type_signed_enumeration_map_range(
- struct bt_field_type *field_type, const char *label,
- int64_t range_lower, int64_t range_upper);
-
-extern struct bt_field_type *bt_field_type_string_create(void);
-
-extern struct bt_field_type *bt_field_type_structure_create(void);
-
-extern uint64_t bt_field_type_structure_get_member_count(
- struct bt_field_type *field_type);
-
-extern void bt_field_type_structure_borrow_member_by_index(
- struct bt_field_type *struct_field_type, uint64_t index,
- const char **name, struct bt_field_type **field_type);
-
-extern
-struct bt_field_type *bt_field_type_structure_borrow_member_field_type_by_name(
- struct bt_field_type *field_type, const char *name);
-
-extern int bt_field_type_structure_append_member(
- struct bt_field_type *struct_field_type, const char *name,
- struct bt_field_type *field_type);
-
-extern struct bt_field_type *bt_field_type_static_array_create(
- struct bt_field_type *elem_field_type,
- uint64_t length);
-
-extern struct bt_field_type *bt_field_type_dynamic_array_create(
- struct bt_field_type *elem_field_type);
-
-extern struct bt_field_type *bt_field_type_array_borrow_element_field_type(
- struct bt_field_type *field_type);
-
-extern uint64_t bt_field_type_static_array_get_length(
- struct bt_field_type *field_type);
-
-extern struct bt_field_path *
-bt_field_type_dynamic_array_borrow_length_field_path(
- struct bt_field_type *field_type);
-
-extern int bt_field_type_dynamic_array_set_length_field_type(
- struct bt_field_type *field_type,
- struct bt_field_type *length_field_type);
-
-extern struct bt_field_type *bt_field_type_variant_create(void);
-
-extern struct bt_field_path *
-bt_field_type_variant_borrow_selector_field_path(
- struct bt_field_type *field_type);
-
-extern int bt_field_type_variant_set_selector_field_type(
- struct bt_field_type *field_type,
- struct bt_field_type *selector_field_type);
-
-extern uint64_t bt_field_type_variant_get_option_count(
- struct bt_field_type *field_type);
-
-extern void bt_field_type_variant_borrow_option_by_index(
- struct bt_field_type *variant_field_type, uint64_t index,
- const char **name, struct bt_field_type **field_type);
-
-extern
-struct bt_field_type *bt_field_type_variant_borrow_option_field_type_by_name(
- struct bt_field_type *field_type,
- const char *name);
-
-extern int bt_field_type_variant_append_option(
- struct bt_field_type *var_field_type,
- const char *name, struct bt_field_type *field_type);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_FIELD_TYPES_H */
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/field-types.h>
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_FIELD_WRAPPER_INTERNAL_H
-#define BABELTRACE_CTF_IR_FIELD_WRAPPER_INTERNAL_H
-
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/object-pool-internal.h>
-#include <babeltrace/object-internal.h>
-
-struct bt_field_wrapper {
- struct bt_object base;
-
- /* Owned by this */
- struct bt_field *field;
-};
-
-BT_HIDDEN
-struct bt_field_wrapper *bt_field_wrapper_new(void *data);
-
-BT_HIDDEN
-void bt_field_wrapper_destroy(struct bt_field_wrapper *field);
-
-BT_HIDDEN
-struct bt_field_wrapper *bt_field_wrapper_create(
- struct bt_object_pool *pool, struct bt_field_type *ft);
-
-#endif /* BABELTRACE_CTF_IR_FIELD_WRAPPER_INTERNAL_H */
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_FIELDS_INTERNAL_H
-#define BABELTRACE_CTF_IR_FIELDS_INTERNAL_H
-
-/*
- * Babeltrace - CTF IR: Event Fields internal
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/common-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/types.h>
-#include <stdint.h>
-#include <string.h>
-#include <inttypes.h>
-#include <stdbool.h>
-#include <glib.h>
-
-#define BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(_field, _type_id, _name) \
- BT_ASSERT_PRE(((struct bt_field *) (_field))->type->id == (_type_id), \
- _name " has the wrong type ID: expected-type-id=%s, " \
- "%![field-]+f", \
- bt_common_field_type_id_string(_type_id), (_field))
-
-#define BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(_field, _name) \
- BT_ASSERT_PRE( \
- ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_UNSIGNED_INTEGER || \
- ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION, \
- _name " is not an unsigned integer field: %![field-]+f", \
- (_field))
-
-#define BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(_field, _name) \
- BT_ASSERT_PRE( \
- ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_SIGNED_INTEGER || \
- ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_SIGNED_ENUMERATION, \
- _name " is not a signed integer field: %![field-]+f", \
- (_field))
-
-#define BT_ASSERT_PRE_FIELD_IS_ARRAY(_field, _name) \
- BT_ASSERT_PRE( \
- ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_STATIC_ARRAY || \
- ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_DYNAMIC_ARRAY, \
- _name " is not an array field: %![field-]+f", (_field))
-
-#define BT_ASSERT_PRE_FIELD_IS_SET(_field, _name) \
- BT_ASSERT_PRE(bt_field_is_set(_field), \
- _name " is not set: %!+f", (_field))
-
-#define BT_ASSERT_PRE_FIELD_HOT(_field, _name) \
- BT_ASSERT_PRE_HOT((struct bt_field *) (_field), (_name), \
- ": %!+f", (_field))
-
-struct bt_field;
-
-typedef struct bt_field *(* bt_field_create_func)(struct bt_field_type *);
-typedef void (*bt_field_method_set_is_frozen)(struct bt_field *, bool);
-typedef bool (*bt_field_method_is_set)(struct bt_field *);
-typedef void (*bt_field_method_reset)(struct bt_field *);
-
-struct bt_field_methods {
- bt_field_method_set_is_frozen set_is_frozen;
- bt_field_method_is_set is_set;
- bt_field_method_reset reset;
-};
-
-struct bt_field {
- struct bt_object base;
-
- /* Owned by this */
- struct bt_field_type *type;
-
- /* Virtual table for slow path (dev mode) operations */
- struct bt_field_methods *methods;
-
- bool is_set;
- bool frozen;
-};
-
-struct bt_field_integer {
- struct bt_field common;
-
- union {
- uint64_t u;
- int64_t i;
- } value;
-};
-
-struct bt_field_real {
- struct bt_field common;
- double value;
-};
-
-struct bt_field_structure {
- struct bt_field common;
-
- /* Array of `struct bt_field *`, owned by this */
- GPtrArray *fields;
-};
-
-struct bt_field_variant {
- struct bt_field common;
-
- /* Weak: belongs to `fields` below */
- struct bt_field *selected_field;
-
- /* Index of currently selected field */
- uint64_t selected_index;
-
- /* Array of `struct bt_field *`, owned by this */
- GPtrArray *fields;
-};
-
-struct bt_field_array {
- struct bt_field common;
-
- /* Array of `struct bt_field *`, owned by this */
- GPtrArray *fields;
-
- /* Current effective length */
- uint64_t length;
-};
-
-struct bt_field_string {
- struct bt_field common;
- GArray *buf;
- uint64_t length;
-};
-
-#ifdef BT_DEV_MODE
-# define bt_field_set_is_frozen _bt_field_set_is_frozen
-# define bt_field_is_set _bt_field_is_set
-# define bt_field_reset _bt_field_reset
-# define bt_field_set_single _bt_field_set_single
-#else
-# define bt_field_set_is_frozen(_field, _is_frozen)
-# define bt_field_is_set(_field) (BT_FALSE)
-# define bt_field_reset(_field)
-# define bt_field_set_single(_field, _val)
-#endif
-
-BT_HIDDEN
-void _bt_field_set_is_frozen(struct bt_field *field, bool is_frozen);
-
-static inline
-void _bt_field_reset(struct bt_field *field)
-{
- BT_ASSERT(field);
- BT_ASSERT(field->methods->reset);
- field->methods->reset(field);
-}
-
-static inline
-void _bt_field_set_single(struct bt_field *field, bool value)
-{
- BT_ASSERT(field);
- field->is_set = value;
-}
-
-static inline
-bt_bool _bt_field_is_set(struct bt_field *field)
-{
- bt_bool is_set = BT_FALSE;
-
- if (!field) {
- goto end;
- }
-
- BT_ASSERT(bt_field_type_has_known_id(field->type));
- BT_ASSERT(field->methods->is_set);
- is_set = field->methods->is_set(field);
-
-end:
- return is_set;
-}
-
-BT_HIDDEN
-struct bt_field *bt_field_create(struct bt_field_type *type);
-
-BT_HIDDEN
-void bt_field_destroy(struct bt_field *field);
-
-#endif /* BABELTRACE_CTF_IR_FIELDS_INTERNAL_H */
-#ifndef BABELTRACE_CTF_IR_FIELDS_H
-#define BABELTRACE_CTF_IR_FIELDS_H
-
-/*
- * Babeltrace - CTF IR: Event Fields
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <stdint.h>
-
-/* For bt_bool */
-#include <babeltrace/types.h>
-
-/* For enum bt_field_type_id */
-#include <babeltrace/ctf-ir/field-types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_field;
-struct bt_field_type;
-struct bt_field_type_enumeration_mapping_iterator;
-
-extern struct bt_field_type *bt_field_borrow_type(struct bt_field *field);
-
-extern enum bt_field_type_id bt_field_get_type_id(struct bt_field *field);
-
-extern int64_t bt_field_signed_integer_get_value(struct bt_field *field);
-
-extern void bt_field_signed_integer_set_value(struct bt_field *field,
- int64_t value);
-
-extern uint64_t bt_field_unsigned_integer_get_value(struct bt_field *field);
-
-extern void bt_field_unsigned_integer_set_value(struct bt_field *field,
- uint64_t value);
-
-extern double bt_field_real_get_value(struct bt_field *field);
-
-extern void bt_field_real_set_value(struct bt_field *field, double value);
-
-extern int bt_field_unsigned_enumeration_get_mapping_labels(
- struct bt_field *field,
- bt_field_type_enumeration_mapping_label_array *label_array,
- uint64_t *count);
-
-extern int bt_field_signed_enumeration_get_mapping_labels(
- struct bt_field *field,
- bt_field_type_enumeration_mapping_label_array *label_array,
- uint64_t *count);
-
-extern const char *bt_field_string_get_value(struct bt_field *field);
-
-extern uint64_t bt_field_string_get_length(struct bt_field *field);
-
-extern int bt_field_string_set_value(struct bt_field *field, const char *value);
-
-extern int bt_field_string_append(struct bt_field *field, const char *value);
-
-extern int bt_field_string_append_with_length(struct bt_field *field,
- const char *value, uint64_t length);
-
-extern int bt_field_string_clear(struct bt_field *field);
-
-extern struct bt_field *bt_field_structure_borrow_member_field_by_index(
- struct bt_field *field, uint64_t index);
-
-extern struct bt_field *bt_field_structure_borrow_member_field_by_name(
- struct bt_field *field, const char *name);
-
-extern uint64_t bt_field_array_get_length(struct bt_field *field);
-
-extern struct bt_field *bt_field_array_borrow_element_field_by_index(
- struct bt_field *field, uint64_t index);
-
-extern int bt_field_dynamic_array_set_length(struct bt_field *field,
- uint64_t length);
-
-extern int bt_field_variant_select_option_field(struct bt_field *field,
- uint64_t index);
-
-extern uint64_t bt_field_variant_get_selected_option_field_index(
- struct bt_field *field);
-
-extern struct bt_field *bt_field_variant_borrow_selected_option_field(
- struct bt_field *field);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_FIELDS_H */
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/fields.h>
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_PACKET_CONTEXT_FIELD_H
-#define BABELTRACE_CTF_IR_PACKET_CONTEXT_FIELD_H
-
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_stream_class;
-struct bt_packet_context_field;
-struct bt_field;
-
-extern
-struct bt_packet_context_field *bt_packet_context_field_create(
- struct bt_stream_class *stream_class);
-
-extern
-struct bt_field *bt_packet_context_field_borrow_field(
- struct bt_packet_context_field *field);
-
-extern
-void bt_packet_context_field_release(struct bt_packet_context_field *field);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_PACKET_CONTEXT_FIELD_H */
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_PACKET_HEADER_FIELD_H
-#define BABELTRACE_CTF_IR_PACKET_HEADER_FIELD_H
-
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_trace;
-struct bt_packet_header_field;
-struct bt_field;
-
-extern
-struct bt_packet_header_field *bt_packet_header_field_create(
- struct bt_trace *trace);
-
-extern
-struct bt_field *bt_packet_header_field_borrow_field(
- struct bt_packet_header_field *field);
-
-extern
-void bt_packet_header_field_release(struct bt_packet_header_field *field);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_PACKET_HEADER_FIELD_H */
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_PACKET_INTERNAL_H
-#define BABELTRACE_CTF_IR_PACKET_INTERNAL_H
-
-/*
- * Babeltrace - CTF IR: Stream packet internal
- *
- * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <stdbool.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/ctf-ir/clock-value.h>
-#include <babeltrace/ctf-ir/packet.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/field-wrapper-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/property-internal.h>
-
-struct bt_packet {
- struct bt_object base;
- struct bt_field_wrapper *header_field;
- struct bt_field_wrapper *context_field;
- struct bt_stream *stream;
- struct bt_clock_value *default_beginning_cv;
- struct bt_clock_value *default_end_cv;
- struct bt_property_uint discarded_event_counter_snapshot;
- struct bt_property_uint packet_counter_snapshot;
- bool frozen;
-};
-
-BT_HIDDEN
-void _bt_packet_set_is_frozen(struct bt_packet *packet, bool is_frozen);
-
-#ifdef BT_DEV_MODE
-# define bt_packet_set_is_frozen _bt_packet_set_is_frozen
-#else
-# define bt_packet_set_is_frozen(_packet, _is_frozen)
-#endif /* BT_DEV_MODE */
-
-BT_HIDDEN
-struct bt_packet *bt_packet_new(struct bt_stream *stream);
-
-BT_HIDDEN
-void bt_packet_recycle(struct bt_packet *packet);
-
-BT_HIDDEN
-void bt_packet_destroy(struct bt_packet *packet);
-
-#endif /* BABELTRACE_CTF_IR_PACKET_INTERNAL_H */
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_PACKET_H
-#define BABELTRACE_CTF_IR_PACKET_H
-
-/*
- * BabelTrace - CTF IR: Stream packet
- *
- * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <stdint.h>
-
-/* For enum bt_property_availability */
-#include <babeltrace/property.h>
-
-/* For enum bt_clock_value_status */
-#include <babeltrace/ctf-ir/clock-value.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_packet;
-struct bt_packet_header_field;
-struct bt_packet_context_field;
-struct bt_stream;
-struct bt_clock_value;
-
-extern struct bt_packet *bt_packet_create(struct bt_stream *stream);
-
-extern struct bt_stream *bt_packet_borrow_stream(struct bt_packet *packet);
-
-extern
-struct bt_field *bt_packet_borrow_header_field(struct bt_packet *packet);
-
-extern
-int bt_packet_move_header_field(struct bt_packet *packet,
- struct bt_packet_header_field *header);
-
-extern
-struct bt_field *bt_packet_borrow_context_field(struct bt_packet *packet);
-
-extern
-int bt_packet_move_context_field(struct bt_packet *packet,
- struct bt_packet_context_field *context);
-
-extern
-enum bt_clock_value_status bt_packet_borrow_default_beginning_clock_value(
- struct bt_packet *packet, struct bt_clock_value **clock_value);
-
-extern
-int bt_packet_set_default_beginning_clock_value(struct bt_packet *packet,
- uint64_t value_cycles);
-
-extern
-enum bt_clock_value_status bt_packet_borrow_default_end_clock_valeu(
- struct bt_packet *packet, struct bt_clock_value **clock_value);
-
-extern
-int bt_packet_set_default_end_clock_value(struct bt_packet *packet,
- uint64_t value_cycles);
-
-extern
-enum bt_property_availability bt_packet_get_discarded_event_counter_snapshot(
- struct bt_packet *packet, uint64_t *value);
-
-extern
-int bt_packet_set_discarded_event_counter_snapshot(struct bt_packet *packet,
- uint64_t value);
-
-extern
-enum bt_property_availability bt_packet_get_packet_counter_snapshot(
- struct bt_packet *packet, uint64_t *value);
-
-extern
-int bt_packet_set_packet_counter_snapshot(struct bt_packet *packet,
- uint64_t value);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_PACKET_H */
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_RESOLVE_FIELD_PATH_INTERNAL
-#define BABELTRACE_CTF_IR_RESOLVE_FIELD_PATH_INTERNAL
-
-/*
- * BabelTrace - CTF IR: Field path
- *
- * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <babeltrace/object-internal.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/field-path.h>
-#include <glib.h>
-
-struct bt_resolve_field_path_context {
- struct bt_field_type *packet_header;
- struct bt_field_type *packet_context;
- struct bt_field_type *event_header;
- struct bt_field_type *event_common_context;
- struct bt_field_type *event_specific_context;
- struct bt_field_type *event_payload;
-};
-
-BT_HIDDEN
-int bt_resolve_field_paths(struct bt_field_type *ft,
- struct bt_resolve_field_path_context *ctx);
-
-#endif /* BABELTRACE_CTF_IR_RESOLVE_FIELD_PATH_INTERNAL */
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_RESOLVE_INTERNAL_H
-#define BABELTRACE_CTF_IR_RESOLVE_INTERNAL_H
-
-/*
- * Babeltrace - CTF IR: Type resolving internal
- *
- * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Authors: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- * Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/values.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <glib.h>
-
-enum bt_resolve_flag {
- BT_RESOLVE_FLAG_PACKET_HEADER = 0x01,
- BT_RESOLVE_FLAG_PACKET_CONTEXT = 0x02,
- BT_RESOLVE_FLAG_EVENT_HEADER = 0x04,
- BT_RESOLVE_FLAG_STREAM_EVENT_CTX = 0x08,
- BT_RESOLVE_FLAG_EVENT_CONTEXT = 0x10,
- BT_RESOLVE_FLAG_EVENT_PAYLOAD = 0x20,
-};
-
-/*
- * Resolves CTF IR field types: recursively locates the tag and length
- * field types of resp. variant and sequence field types.
- *
- * All `*_type` parameters may be resolved, and may as well serve as
- * resolving targets.
- *
- * Resolving is performed based on the flags in `flags`.
- *
- * It is expected that, amongst all the provided types, no common
- * references to sequence variant field types exist. In other words,
- * this function does not copy field types.
- *
- * All parameters are owned by the caller.
- */
-BT_HIDDEN
-int bt_resolve_types(struct bt_value *environment,
- struct bt_field_type *packet_header_type,
- struct bt_field_type *packet_context_type,
- struct bt_field_type *event_header_type,
- struct bt_field_type *stream_event_ctx_type,
- struct bt_field_type *event_context_type,
- struct bt_field_type *event_payload_type,
- enum bt_resolve_flag flags);
-
-#endif /* BABELTRACE_CTF_IR_RESOLVE_INTERNAL_H */
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H
-#define BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H
-
-/*
- * BabelTrace - CTF IR: Stream class internal
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/common-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/object-pool-internal.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <glib.h>
-#include <inttypes.h>
-
-struct bt_stream_class {
- struct bt_object base;
-
- struct {
- GString *str;
-
- /* NULL or `str->str` above */
- const char *value;
- } name;
-
- uint64_t id;
- bool assigns_automatic_event_class_id;
- bool assigns_automatic_stream_id;
- bool packets_have_discarded_event_counter_snapshot;
- bool packets_have_packet_counter_snapshot;
- bool packets_have_default_beginning_cv;
- bool packets_have_default_end_cv;
- struct bt_field_type *packet_context_ft;
- struct bt_field_type *event_header_ft;
- struct bt_field_type *event_common_context_ft;
- struct bt_clock_class *default_clock_class;
-
- /* Array of `struct bt_event_class *` */
- GPtrArray *event_classes;
-
- /* Pool of `struct bt_field_wrapper *` */
- struct bt_object_pool event_header_field_pool;
-
- /* Pool of `struct bt_field_wrapper *` */
- struct bt_object_pool packet_context_field_pool;
-
- bool frozen;
-};
-
-BT_HIDDEN
-void _bt_stream_class_freeze(struct bt_stream_class *stream_class);
-
-#ifdef BT_DEV_MODE
-# define bt_stream_class_freeze _bt_stream_class_freeze
-#else
-# define bt_stream_class_freeze(_sc)
-#endif
-
-static inline
-struct bt_trace *bt_stream_class_borrow_trace_inline(
- struct bt_stream_class *stream_class)
-{
- BT_ASSERT(stream_class);
- return (void *) bt_object_borrow_parent(&stream_class->base);
-}
-
-#endif /* BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H */
-#ifndef BABELTRACE_CTF_IR_STREAM_CLASS_H
-#define BABELTRACE_CTF_IR_STREAM_CLASS_H
-
-/*
- * BabelTrace - CTF IR: Stream Class
- *
- * Copyright 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <stdint.h>
-
-/* For bt_bool */
-#include <babeltrace/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_trace;
-struct bt_stream_class;
-struct bt_event_class;
-struct bt_clock_class;
-struct bt_event_header_field;
-struct bt_packet_context_field;
-
-extern struct bt_stream_class *bt_stream_class_create(struct bt_trace *trace);
-
-extern struct bt_stream_class *bt_stream_class_create_with_id(
- struct bt_trace *trace, uint64_t id);
-
-extern struct bt_trace *bt_stream_class_borrow_trace(
- struct bt_stream_class *stream_class);
-
-extern const char *bt_stream_class_get_name(
- struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_name(struct bt_stream_class *stream_class,
- const char *name);
-
-extern bt_bool bt_stream_class_assigns_automatic_event_class_id(
- struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_assigns_automatic_event_class_id(
- struct bt_stream_class *stream_class, bt_bool value);
-
-extern bt_bool bt_stream_class_assigns_automatic_stream_id(
- struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_assigns_automatic_stream_id(
- struct bt_stream_class *stream_class, bt_bool value);
-
-extern uint64_t bt_stream_class_get_id(struct bt_stream_class *stream_class);
-
-extern struct bt_field_type *bt_stream_class_borrow_packet_context_field_type(
- struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_packet_context_field_type(
- struct bt_stream_class *stream_class,
- struct bt_field_type *field_type);
-
-extern struct bt_field_type *
-bt_stream_class_borrow_event_header_field_type(
- struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_event_header_field_type(
- struct bt_stream_class *stream_class,
- struct bt_field_type *field_type);
-
-extern struct bt_field_type *
-bt_stream_class_borrow_event_common_context_field_type(
- struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_event_common_context_field_type(
- struct bt_stream_class *stream_class,
- struct bt_field_type *field_type);
-
-extern uint64_t bt_stream_class_get_event_class_count(
- struct bt_stream_class *stream_class);
-
-extern struct bt_event_class *bt_stream_class_borrow_event_class_by_index(
- struct bt_stream_class *stream_class, uint64_t index);
-
-extern struct bt_event_class *bt_stream_class_borrow_event_class_by_id(
- struct bt_stream_class *stream_class, uint64_t id);
-
-extern int bt_stream_class_set_default_clock_class(
- struct bt_stream_class *stream_class,
- struct bt_clock_class *clock_class);
-
-extern struct bt_clock_class *bt_stream_class_borrow_default_clock_class(
- struct bt_stream_class *stream_class);
-
-extern bt_bool bt_stream_class_default_clock_is_always_known(
- struct bt_stream_class *stream_class);
-
-extern bt_bool bt_stream_class_packets_have_discarded_event_counter_snapshot(
- struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_packets_have_discarded_event_counter_snapshot(
- struct bt_stream_class *stream_class, bt_bool value);
-
-extern bt_bool bt_stream_class_packets_have_packet_counter_snapshot(
- struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_packets_have_packet_counter_snapshot(
- struct bt_stream_class *stream_class, bt_bool value);
-
-extern bt_bool bt_stream_class_packets_have_default_beginning_clock_value(
- struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_packets_have_default_beginning_clock_value(
- struct bt_stream_class *stream_class, bt_bool value);
-
-extern bt_bool bt_stream_class_packets_have_default_end_clock_value(
- struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_packets_have_default_end_clock_value(
- struct bt_stream_class *stream_class, bt_bool value);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_STREAM_CLASS_H */
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/stream-class.h>
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_STREAM_INTERNAL_H
-#define BABELTRACE_CTF_IR_STREAM_INTERNAL_H
-
-/*
- * BabelTrace - CTF Writer: Stream internal
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/object-pool-internal.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <glib.h>
-
-struct bt_stream_class;
-struct bt_stream;
-
-struct bt_stream {
- struct bt_object base;
-
- /* Weak: parent is this class's trace */
- struct bt_stream_class *class;
-
- struct {
- GString *str;
-
- /* NULL or `str->str` above */
- const char *value;
- } name;
-
- uint64_t id;
-
- /* Pool of `struct bt_packet *` */
- struct bt_object_pool packet_pool;
-
- bool frozen;
-};
-
-BT_HIDDEN
-void _bt_stream_freeze(struct bt_stream *stream);
-
-#ifdef BT_DEV_MODE
-# define bt_stream_freeze _bt_stream_freeze
-#else
-# define bt_stream_freeze(_stream)
-#endif
-
-#endif /* BABELTRACE_CTF_IR_STREAM_INTERNAL_H */
-#ifndef BABELTRACE_CTF_IR_STREAM_H
-#define BABELTRACE_CTF_IR_STREAM_H
-
-/*
- * BabelTrace - CTF IR: Stream
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-/* For enum bt_property_availability */
-#include <babeltrace/property.h>
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_stream;
-struct bt_stream_class;
-
-extern struct bt_stream *bt_stream_create(struct bt_stream_class *stream_class);
-
-extern struct bt_stream *bt_stream_create_with_id(
- struct bt_stream_class *stream_class, uint64_t id);
-
-extern struct bt_stream_class *bt_stream_borrow_class(struct bt_stream *stream);
-
-extern const char *bt_stream_get_name(struct bt_stream *stream);
-
-extern int bt_stream_set_name(struct bt_stream *stream, const char *name);
-
-extern uint64_t bt_stream_get_id(struct bt_stream *stream);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_STREAM_H */
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/stream.h>
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_TRACE_INTERNAL_H
-#define BABELTRACE_CTF_IR_TRACE_INTERNAL_H
-
-/*
- * BabelTrace - CTF IR: Trace internal
- *
- * Copyright 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/trace.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/attributes-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/object-pool-internal.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/values.h>
-#include <babeltrace/types.h>
-#include <glib.h>
-#include <sys/types.h>
-#include <babeltrace/compat/uuid-internal.h>
-
-struct bt_trace {
- struct bt_object base;
-
- struct {
- GString *str;
-
- /* NULL or `str->str` above */
- const char *value;
- } name;
-
- struct {
- uint8_t uuid[BABELTRACE_UUID_LEN];
-
- /* NULL or `uuid` above */
- bt_uuid value;
- } uuid;
-
- struct bt_value *environment;
-
- /* Array of `struct bt_stream_class *` */
- GPtrArray *stream_classes;
-
- /* Array of `struct bt_stream *` */
- GPtrArray *streams;
-
- /*
- * Stream class (weak) to number of instantiated streams, used
- * to automatically assign stream IDs per stream class.
- */
- GHashTable *stream_classes_stream_count;
-
- struct bt_field_type *packet_header_ft;
- bool assigns_automatic_stream_class_id;
-
- GArray *is_static_listeners;
- bool is_static;
- bool in_remove_listener;
-
- /* Pool of `struct bt_field_wrapper *` */
- struct bt_object_pool packet_header_field_pool;
-
- bool frozen;
-};
-
-BT_HIDDEN
-void _bt_trace_freeze(struct bt_trace *trace);
-
-#ifdef BT_DEV_MODE
-# define bt_trace_freeze _bt_trace_freeze
-#else
-# define bt_trace_freeze(_trace)
-#endif
-
-BT_HIDDEN
-void bt_trace_add_stream(struct bt_trace *trace, struct bt_stream *stream);
-
-BT_HIDDEN
-uint64_t bt_trace_get_automatic_stream_id(struct bt_trace *trace,
- struct bt_stream_class *stream_class);
-
-#endif /* BABELTRACE_CTF_IR_TRACE_INTERNAL_H */
-#ifndef BABELTRACE_CTF_IR_TRACE_H
-#define BABELTRACE_CTF_IR_TRACE_H
-
-/*
- * BabelTrace - CTF IR: Trace
- *
- * Copyright 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-/* For bt_bool, bt_uuid */
-#include <babeltrace/types.h>
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_trace;
-struct bt_stream;
-struct bt_stream_class;
-struct bt_field_type;
-struct bt_value;
-struct bt_packet_header_field;
-
-typedef void (* bt_trace_is_static_listener)(
- struct bt_trace *trace, void *data);
-
-typedef void (* bt_trace_listener_removed)(
- struct bt_trace *trace, void *data);
-
-extern struct bt_trace *bt_trace_create(void);
-
-extern bt_bool bt_trace_assigns_automatic_stream_class_id(
- struct bt_trace *trace);
-
-extern int bt_trace_set_assigns_automatic_stream_class_id(
- struct bt_trace *trace, bt_bool value);
-
-extern const char *bt_trace_get_name(struct bt_trace *trace);
-
-extern int bt_trace_set_name(struct bt_trace *trace, const char *name);
-
-extern bt_uuid bt_trace_get_uuid(struct bt_trace *trace);
-
-extern int bt_trace_set_uuid(struct bt_trace *trace, bt_uuid uuid);
-
-extern uint64_t bt_trace_get_environment_entry_count(struct bt_trace *trace);
-
-extern void bt_trace_borrow_environment_entry_by_index(
- struct bt_trace *trace, uint64_t index,
- const char **name, struct bt_value **value);
-
-extern struct bt_value *bt_trace_borrow_environment_entry_value_by_name(
- struct bt_trace *trace, const char *name);
-
-extern int bt_trace_set_environment_entry_integer(
- struct bt_trace *trace, const char *name,
- int64_t value);
-
-extern int bt_trace_set_environment_entry_string(
- struct bt_trace *trace, const char *name,
- const char *value);
-
-extern struct bt_field_type *bt_trace_borrow_packet_header_field_type(
- struct bt_trace *trace);
-
-extern int bt_trace_set_packet_header_field_type(struct bt_trace *trace,
- struct bt_field_type *packet_header_type);
-
-extern uint64_t bt_trace_get_stream_class_count(struct bt_trace *trace);
-
-extern struct bt_stream_class *bt_trace_borrow_stream_class_by_index(
- struct bt_trace *trace, uint64_t index);
-
-extern struct bt_stream_class *bt_trace_borrow_stream_class_by_id(
- struct bt_trace *trace, uint64_t id);
-
-extern uint64_t bt_trace_get_stream_count(struct bt_trace *trace);
-
-extern struct bt_stream *bt_trace_borrow_stream_by_index(
- struct bt_trace *trace, uint64_t index);
-
-extern struct bt_stream *bt_trace_borrow_stream_by_id(
- struct bt_trace *trace, uint64_t id);
-
-extern bt_bool bt_trace_is_static(struct bt_trace *trace);
-
-extern int bt_trace_make_static(struct bt_trace *trace);
-
-extern int bt_trace_add_is_static_listener(
- struct bt_trace *trace,
- bt_trace_is_static_listener listener,
- bt_trace_listener_removed listener_removed, void *data,
- uint64_t *listener_id);
-
-extern int bt_trace_remove_is_static_listener(
- struct bt_trace *trace, uint64_t listener_id);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_TRACE_H */
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/trace.h>
+++ /dev/null
-#ifndef BABELTRACE_CTF_IR_UTILS_INTERNAL_H
-#define BABELTRACE_CTF_IR_UTILS_INTERNAL_H
-
-/*
- * Babeltrace - Internal CTF IR utilities
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <stdint.h>
-
-struct search_query {
- gpointer value;
- int found;
-};
-
-static inline
-uint64_t bt_util_ns_from_value(uint64_t frequency, uint64_t value_cycles)
-{
- uint64_t ns;
-
- if (frequency == UINT64_C(1000000000)) {
- ns = value_cycles;
- } else {
- double dblres = ((1e9 * (double) value_cycles) / (double) frequency);
-
- if (dblres >= (double) UINT64_MAX) {
- /* Overflows uint64_t */
- ns = UINT64_C(-1);
- } else {
- ns = (uint64_t) dblres;
- }
- }
-
- return ns;
-}
-
-static inline
-int bt_util_ns_from_origin(struct bt_clock_class *clock_class, uint64_t value,
- int64_t *ns_from_origin)
-{
- int ret = 0;
- uint64_t value_ns_unsigned;
- int64_t value_ns_signed;
-
- if (clock_class->base_offset.overflows) {
- ret = -1;
- goto end;
- }
-
- /* Initialize to clock class's base offset */
- *ns_from_origin = clock_class->base_offset.value_ns;
-
- /* Add given value in cycles */
- value_ns_unsigned = bt_util_ns_from_value(clock_class->frequency, value);
- if (value_ns_unsigned >= (uint64_t) INT64_MAX) {
- /*
- * FIXME: `value_ns_unsigned` could be greater than
- * `INT64_MAX` in fact: in this case, we need to
- * subtract `INT64_MAX` from `value_ns_unsigned`, make
- * sure that the difference is less than `INT64_MAX`,
- * and try to add them one after the other to
- * `*ns_from_origin`.
- */
- ret = -1;
- goto end;
- }
-
- value_ns_signed = (int64_t) value_ns_unsigned;
- BT_ASSERT(value_ns_signed >= 0);
-
- if (*ns_from_origin <= 0) {
- goto add_value;
- }
-
- if (value_ns_signed > INT64_MAX - *ns_from_origin) {
- ret = -1;
- goto end;
- }
-
-add_value:
- *ns_from_origin += value_ns_signed;
-
-end:
- return ret;
-}
-
-static inline
-bool bt_util_value_is_in_range_signed(uint64_t size, int64_t value)
-{
- int64_t min_value = UINT64_C(-1) << (size - 1);
- int64_t max_value = (UINT64_C(1) << (size - 1)) - 1;
- return value >= min_value && value <= max_value;
-}
-
-static inline
-bool bt_util_value_is_in_range_unsigned(unsigned int size, uint64_t value)
-{
- uint64_t max_value = (size == 64) ? UINT64_MAX :
- (UINT64_C(1) << size) - 1;
- return value <= max_value;
-}
-
-#endif /* BABELTRACE_CTF_IR_UTILS_INTERNAL_H */
--- /dev/null
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/utils.h>
@brief CTF IR visitor.
@code
-#include <babeltrace/ctf-ir/visitor.h>
+#include <babeltrace/trace-ir/visitor.h>
@endcode
A CTF IR <strong><em>visitor</em></strong> is a function that you
-#ifndef BABELTRACE_CTF_EVENTS_H
-#define BABELTRACE_CTF_EVENTS_H
-
-/*
- * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-/*
- * This header still exists for backward compatibility reasons because
- * CTF writer needed it to be included.
- */
-
+/* Pre-2.0 CTF writer backward compatibility */
#include <babeltrace/ctf-writer/clock.h>
#include <babeltrace/ctf-writer/event-fields.h>
#include <babeltrace/ctf-writer/event-types.h>
#include <babeltrace/ctf-writer/stream-class.h>
#include <babeltrace/ctf-writer/stream.h>
#include <babeltrace/ctf-writer/writer.h>
-
-#endif /* BABELTRACE_CTF_EVENTS_H */
*/
#include <babeltrace/compiler-internal.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/event.h>
+#include <babeltrace/trace-ir/event-class.h>
+#include <babeltrace/trace-ir/event.h>
#include <babeltrace/graph/notification-internal.h>
#include <babeltrace/assert-internal.h>
*/
#include <glib.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
#include <babeltrace/graph/notification.h>
struct bt_notification_inactivity {
#include <babeltrace/assert-internal.h>
#include <babeltrace/graph/graph.h>
#include <babeltrace/graph/notification.h>
-#include <babeltrace/ctf-ir/stream.h>
+#include <babeltrace/trace-ir/stream.h>
#include <babeltrace/object-pool-internal.h>
#include <babeltrace/types.h>
*/
#include <babeltrace/compiler-internal.h>
-#include <babeltrace/ctf-ir/packet.h>
+#include <babeltrace/trace-ir/packet.h>
#include <babeltrace/graph/notification-internal.h>
#include <babeltrace/assert-internal.h>
*/
#include <babeltrace/compiler-internal.h>
-#include <babeltrace/ctf-ir/packet.h>
+#include <babeltrace/trace-ir/packet.h>
#include <babeltrace/graph/notification-internal.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
#include <babeltrace/assert-internal.h>
struct bt_notification_stream_begin {
* The available format specifiers are:
*
* `F`:
- * CTF IR field type. The parameter type is `struct bt_field_type *`.
+ * Trace IR field type. The parameter type is `struct
+ * bt_field_type *`.
*
* `f`:
- * CTF IR field. The parameter type is `struct bt_field *`.
+ * Trace IR field. The parameter type is `struct bt_field *`.
*
* `P`:
* Field path. The parameter type is `struct bt_field_path *`.
*
* `E`:
- * CTF IR event class. The parameter type is `struct bt_event_class *`.
+ * Trace IR event class. The parameter type is `struct
+ * bt_event_class *`.
*
* `e`:
- * CTF IR event. The parameter type is `struct bt_event *`.
+ * Trace IR event. The parameter type is `struct bt_event *`.
*
* `S`:
- * CTF IR stream class. The parameter type is `struct bt_stream_class *`.
+ * Trace IR stream class. The parameter type is `struct
+ * bt_stream_class *`.
*
* `s`:
- * CTF IR stream. The parameter type is `struct bt_stream *`.
+ * Trace IR stream. The parameter type is `struct bt_stream *`.
*
* `a`:
* Packet. The parameter type is `struct bt_packet *`.
*
* `t`:
- * CTF IR trace. The parameter type is `struct bt_trace *`.
+ * Trace IR trace. The parameter type is `struct bt_trace *`.
*
* `K`:
* Clock class. The parameter type is `struct bt_clock_class *`.
* `struct bt_notification_iterator *`.
*
* `C`:
- * Component class. The parameter type is `struct bt_component_class *`.
+ * Component class. The parameter type is `struct
+ * bt_component_class *`.
*
* `c`:
* Component. The parameter type is `struct bt_component *`.
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_ATTRIBUTES_H
+#define BABELTRACE_TRACE_IR_ATTRIBUTES_H
+
+/*
+ * attributes.c
+ *
+ * Babeltrace - Trace IR: Attributes internal
+ *
+ * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
+ * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/values.h>
+
+BT_HIDDEN
+struct bt_value *bt_attributes_create(void);
+
+BT_HIDDEN
+void bt_attributes_destroy(struct bt_value *attr_obj);
+
+BT_HIDDEN
+int64_t bt_attributes_get_count(struct bt_value *attr_obj);
+
+BT_HIDDEN
+const char *bt_attributes_get_field_name(struct bt_value *attr_obj,
+ uint64_t index);
+
+BT_HIDDEN
+struct bt_value *bt_attributes_borrow_field_value(struct bt_value *attr_obj,
+ uint64_t index);
+
+BT_HIDDEN
+int bt_attributes_set_field_value(struct bt_value *attr_obj,
+ const char *name, struct bt_value *value_obj);
+
+BT_HIDDEN
+struct bt_value *bt_attributes_borrow_field_value_by_name(
+ struct bt_value *attr_obj, const char *name);
+
+BT_HIDDEN
+int bt_attributes_freeze(struct bt_value *attr_obj);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_ATTRIBUTES_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_CLOCK_CLASS_INTERNAL_H
+#define BABELTRACE_TRACE_IR_CLOCK_CLASS_INTERNAL_H
+
+/*
+ * BabelTrace - Trace IR: Clock internal
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/trace-ir/clock-class.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/object-pool-internal.h>
+#include <babeltrace/compat/uuid-internal.h>
+#include <babeltrace/types.h>
+#include <babeltrace/property-internal.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <glib.h>
+
+struct bt_clock_class {
+ struct bt_object base;
+
+ struct {
+ GString *str;
+
+ /* NULL or `str->str` above */
+ const char *value;
+ } name;
+
+ struct {
+ GString *str;
+
+ /* NULL or `str->str` above */
+ const char *value;
+ } description;
+
+ uint64_t frequency;
+ uint64_t precision;
+ int64_t offset_seconds;
+ uint64_t offset_cycles;
+
+ struct {
+ uint8_t uuid[BABELTRACE_UUID_LEN];
+
+ /* NULL or `uuid` above */
+ bt_uuid value;
+ } uuid;
+
+ bool is_absolute;
+
+ /*
+ * This is computed every time you call
+ * bt_clock_class_set_frequency() or
+ * bt_clock_class_set_offset(), as well as initially. It is the
+ * base offset in nanoseconds including both `offset_seconds`
+ * and `offset_cycles` above in the result. It is used to
+ * accelerate future calls to
+ * bt_clock_value_get_ns_from_origin() and
+ * bt_clock_class_cycles_to_ns_from_origin().
+ *
+ * `overflows` is true if the base offset cannot be computed
+ * because of an overflow.
+ */
+ struct {
+ int64_t value_ns;
+ bool overflows;
+ } base_offset;
+
+ /* Pool of `struct bt_clock_value *` */
+ struct bt_object_pool cv_pool;
+
+ bool frozen;
+};
+
+BT_HIDDEN
+void _bt_clock_class_freeze(struct bt_clock_class *clock_class);
+
+#ifdef BT_DEV_MODE
+# define bt_clock_class_freeze _bt_clock_class_freeze
+#else
+# define bt_clock_class_freeze(_cc)
+#endif
+
+BT_HIDDEN
+bt_bool bt_clock_class_is_valid(struct bt_clock_class *clock_class);
+
+#endif /* BABELTRACE_TRACE_IR_CLOCK_CLASS_INTERNAL_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_CLOCK_CLASS_H
+#define BABELTRACE_TRACE_IR_CLOCK_CLASS_H
+
+/*
+ * BabelTrace - Trace IR: Clock class
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <stdint.h>
+
+/* For bt_bool, bt_uuid */
+#include <babeltrace/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_clock_class;
+struct bt_clock_value;
+
+extern struct bt_clock_class *bt_clock_class_create(void);
+
+extern const char *bt_clock_class_get_name(struct bt_clock_class *clock_class);
+
+extern int bt_clock_class_set_name(struct bt_clock_class *clock_class,
+ const char *name);
+
+extern const char *bt_clock_class_get_description(
+ struct bt_clock_class *clock_class);
+
+extern int bt_clock_class_set_description(struct bt_clock_class *clock_class,
+ const char *description);
+
+extern uint64_t bt_clock_class_get_frequency(
+ struct bt_clock_class *clock_class);
+
+extern int bt_clock_class_set_frequency(struct bt_clock_class *clock_class,
+ uint64_t freq);
+
+extern uint64_t bt_clock_class_get_precision(
+ struct bt_clock_class *clock_class);
+
+extern int bt_clock_class_set_precision(struct bt_clock_class *clock_class,
+ uint64_t precision);
+
+extern void bt_clock_class_get_offset(struct bt_clock_class *clock_class,
+ int64_t *seconds, uint64_t *cycles);
+
+extern int bt_clock_class_set_offset(struct bt_clock_class *clock_class,
+ int64_t seconds, uint64_t cycles);
+
+extern bt_bool bt_clock_class_is_absolute(struct bt_clock_class *clock_class);
+
+extern int bt_clock_class_set_is_absolute(struct bt_clock_class *clock_class,
+ bt_bool is_absolute);
+
+extern bt_uuid bt_clock_class_get_uuid(struct bt_clock_class *clock_class);
+
+extern int bt_clock_class_set_uuid(struct bt_clock_class *clock_class,
+ bt_uuid uuid);
+
+extern int bt_clock_class_cycles_to_ns_from_origin(
+ struct bt_clock_class *clock_class,
+ uint64_t cycles, int64_t *ns_from_origin);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_CLOCK_CLASS_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_CLOCK_VALUE_INTERNAL_H
+#define BABELTRACE_TRACE_IR_CLOCK_VALUE_INTERNAL_H
+
+/*
+ * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/trace-ir/utils-internal.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+struct bt_clock_class;
+
+struct bt_clock_value {
+ struct bt_object base;
+ struct bt_clock_class *clock_class;
+ uint64_t value_cycles;
+ bool ns_from_origin_overflows;
+ int64_t ns_from_origin;
+ bool is_set;
+};
+
+static inline
+void bt_clock_value_set(struct bt_clock_value *clock_value)
+{
+ BT_ASSERT(clock_value);
+ clock_value->is_set = true;
+}
+
+static inline
+void bt_clock_value_reset(struct bt_clock_value *clock_value)
+{
+ BT_ASSERT(clock_value);
+ clock_value->is_set = false;
+}
+
+static inline
+void set_ns_from_origin(struct bt_clock_value *clock_value)
+{
+ if (bt_util_ns_from_origin(clock_value->clock_class, clock_value->value_cycles,
+ &clock_value->ns_from_origin)) {
+ clock_value->ns_from_origin_overflows = true;
+ }
+
+}
+
+static inline
+void bt_clock_value_set_raw_value(struct bt_clock_value *clock_value,
+ uint64_t cycles)
+{
+ BT_ASSERT(clock_value);
+ clock_value->value_cycles = cycles;
+ set_ns_from_origin(clock_value);
+ bt_clock_value_set(clock_value);
+}
+
+static inline
+void bt_clock_value_set_value_inline(struct bt_clock_value *clock_value,
+ uint64_t raw_value)
+{
+ bt_clock_value_set_raw_value(clock_value, raw_value);
+}
+
+BT_HIDDEN
+void bt_clock_value_destroy(struct bt_clock_value *clock_value);
+
+BT_HIDDEN
+struct bt_clock_value *bt_clock_value_new(struct bt_clock_class *clock_class);
+
+BT_HIDDEN
+struct bt_clock_value *bt_clock_value_create(
+ struct bt_clock_class *clock_class);
+
+BT_HIDDEN
+void bt_clock_value_recycle(struct bt_clock_value *clock_value);
+
+BT_HIDDEN
+void bt_clock_value_set_raw_value(struct bt_clock_value *clock_value,
+ uint64_t cycles);
+
+#endif /* BABELTRACE_TRACE_IR_CLOCK_VALUE_INTERNAL_H */
--- /dev/null
+#ifndef BABELTRACE_GRAPH_CLOCK_VALUE_SET_H
+#define BABELTRACE_GRAPH_CLOCK_VALUE_SET_H
+
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdint.h>
+#include <glib.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/assert-internal.h>
+
+struct bt_clock_value_set {
+ /* Unique objects owned by this */
+ GPtrArray *clock_values;
+
+ /* Weak; points to one of the clock values above */
+ struct bt_clock_value *default_cv;
+};
+
+static inline
+int bt_clock_value_set_initialize(struct bt_clock_value_set *cv_set)
+{
+ int ret = 0;
+
+ cv_set->clock_values = g_ptr_array_sized_new(1);
+ if (!cv_set->clock_values) {
+#ifdef BT_LOGE_STR
+ BT_LOGE_STR("Failed to allocate one GPtrArray.");
+#endif
+
+ ret = -1;
+ goto end;
+ }
+
+ cv_set->default_cv = NULL;
+
+end:
+ return ret;
+}
+
+static inline
+void bt_clock_value_set_reset(struct bt_clock_value_set *cv_set)
+{
+ uint64_t i;
+
+ BT_ASSERT(cv_set);
+ BT_ASSERT(cv_set->clock_values);
+
+ for (i = 0; i < cv_set->clock_values->len; i++) {
+ struct bt_clock_value *cv = cv_set->clock_values->pdata[i];
+
+ BT_ASSERT(cv);
+ bt_clock_value_reset(cv);
+ }
+
+ cv_set->default_cv = NULL;
+}
+
+static inline
+void bt_clock_value_set_finalize(struct bt_clock_value_set *cv_set)
+{
+ uint64_t i;
+
+ BT_ASSERT(cv_set);
+
+ if (cv_set->clock_values) {
+ for (i = 0; i < cv_set->clock_values->len; i++) {
+ struct bt_clock_value *cv =
+ cv_set->clock_values->pdata[i];
+
+ BT_ASSERT(cv);
+ bt_clock_value_recycle(cv);
+ }
+
+ g_ptr_array_free(cv_set->clock_values, TRUE);
+ }
+
+ cv_set->default_cv = NULL;
+}
+
+static inline
+int bt_clock_value_set_set_clock_value(struct bt_clock_value_set *cv_set,
+ struct bt_clock_class *cc, uint64_t raw_value)
+{
+ int ret = 0;
+ struct bt_clock_value *clock_value = NULL;
+ uint64_t i;
+
+ BT_ASSERT(cv_set);
+ BT_ASSERT(cc);
+
+ /*
+ * Check if we already have a value for this clock class.
+ *
+ * TODO: When we have many clock classes, make this more
+ * efficient.
+ */
+ for (i = 0; i < cv_set->clock_values->len; i++) {
+ struct bt_clock_value *cv = cv_set->clock_values->pdata[i];
+
+ BT_ASSERT(cv);
+
+ if (cv->clock_class == cc) {
+ clock_value = cv;
+ break;
+ }
+ }
+
+ if (!clock_value) {
+ clock_value = bt_clock_value_create(cc);
+ if (!clock_value) {
+#ifdef BT_LIB_LOGE
+ BT_LIB_LOGE("Cannot create a clock value from a clock class: "
+ "%![cc-]+K", cc);
+#endif
+
+ ret = -1;
+ goto end;
+ }
+
+ g_ptr_array_add(cv_set->clock_values, clock_value);
+ }
+
+ bt_clock_value_set_value_inline(clock_value, raw_value);
+
+end:
+ return ret;
+}
+
+static inline
+void bt_clock_value_set_set_default_clock_value(
+ struct bt_clock_value_set *cv_set, uint64_t raw_value)
+{
+ BT_ASSERT(cv_set);
+ BT_ASSERT(cv_set->default_cv);
+ bt_clock_value_set_value_inline(cv_set->default_cv, raw_value);
+}
+
+#endif /* BABELTRACE_GRAPH_CLOCK_VALUE_SET_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_CLOCK_VALUE_H
+#define BABELTRACE_TRACE_IR_CLOCK_VALUE_H
+
+/*
+ * BabelTrace - Trace IR: Clock class
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_clock_class;
+struct bt_clock_value;
+
+enum bt_clock_value_status {
+ BT_CLOCK_VALUE_STATUS_KNOWN,
+ BT_CLOCK_VALUE_STATUS_UNKNOWN,
+};
+
+extern struct bt_clock_class *bt_clock_value_borrow_clock_class(
+ struct bt_clock_value *clock_value);
+
+extern uint64_t bt_clock_value_get_value(
+ struct bt_clock_value *clock_value);
+
+extern int bt_clock_value_get_ns_from_origin(
+ struct bt_clock_value *clock_value, int64_t *ns_from_origin);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_CLOCK_VALUE_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_CLOCK_H
+#define BABELTRACE_TRACE_IR_CLOCK_H
+
+/*
+ * BabelTrace - Trace IR: Clock
+ *
+ * Copyright 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <babeltrace/ctf-writer/clock.h>
+
+#endif /* BABELTRACE_TRACE_IR_CLOCK_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_EVENT_CLASS_INTERNAL_H
+#define BABELTRACE_TRACE_IR_EVENT_CLASS_INTERNAL_H
+
+/*
+ * Babeltrace - Trace IR: Event class internal
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/values.h>
+#include <babeltrace/trace-ir/trace-internal.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/event-class.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/object-pool-internal.h>
+#include <babeltrace/property-internal.h>
+#include <glib.h>
+#include <stdbool.h>
+
+struct bt_event_class {
+ struct bt_object base;
+ struct bt_field_type *specific_context_ft;
+ struct bt_field_type *payload_ft;
+
+ struct {
+ GString *str;
+
+ /* NULL or `str->str` above */
+ const char *value;
+ } name;
+
+ uint64_t id;
+ struct bt_property_uint log_level;
+
+ struct {
+ GString *str;
+
+ /* NULL or `str->str` above */
+ const char *value;
+ } emf_uri;
+
+ /* Pool of `struct bt_event *` */
+ struct bt_object_pool event_pool;
+
+ bool frozen;
+};
+
+BT_HIDDEN
+void _bt_event_class_freeze(struct bt_event_class *event_class);
+
+#ifdef BT_DEV_MODE
+# define bt_event_class_freeze _bt_event_class_freeze
+#else
+# define bt_event_class_freeze(_ec)
+#endif
+
+static inline
+struct bt_stream_class *bt_event_class_borrow_stream_class_inline(
+ struct bt_event_class *event_class)
+{
+ BT_ASSERT(event_class);
+ return (void *) bt_object_borrow_parent(&event_class->base);
+}
+
+#endif /* BABELTRACE_TRACE_IR_EVENT_CLASS_INTERNAL_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_EVENT_CLASS_H
+#define BABELTRACE_TRACE_IR_EVENT_CLASS_H
+
+/*
+ * BabelTrace - Trace IR: Event class
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+/* For enum bt_property_availability */
+#include <babeltrace/property.h>
+
+#include <stdint.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_event_class;
+struct bt_field_type;
+struct bt_stream_class;
+
+enum bt_event_class_log_level {
+ BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY,
+ BT_EVENT_CLASS_LOG_LEVEL_ALERT,
+ BT_EVENT_CLASS_LOG_LEVEL_CRITICAL,
+ BT_EVENT_CLASS_LOG_LEVEL_ERROR,
+ BT_EVENT_CLASS_LOG_LEVEL_WARNING,
+ BT_EVENT_CLASS_LOG_LEVEL_NOTICE,
+ BT_EVENT_CLASS_LOG_LEVEL_INFO,
+ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM,
+ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM,
+ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS,
+ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE,
+ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT,
+ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION,
+ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE,
+ BT_EVENT_CLASS_LOG_LEVEL_DEBUG,
+};
+
+extern struct bt_event_class *bt_event_class_create(
+ struct bt_stream_class *stream_class);
+
+extern struct bt_event_class *bt_event_class_create_with_id(
+ struct bt_stream_class *stream_class, uint64_t id);
+
+extern struct bt_stream_class *bt_event_class_borrow_stream_class(
+ struct bt_event_class *event_class);
+
+extern const char *bt_event_class_get_name(struct bt_event_class *event_class);
+
+extern int bt_event_class_set_name(struct bt_event_class *event_class,
+ const char *name);
+
+extern uint64_t bt_event_class_get_id(struct bt_event_class *event_class);
+
+extern enum bt_property_availability bt_event_class_get_log_level(
+ struct bt_event_class *event_class,
+ enum bt_event_class_log_level *log_level);
+
+extern int bt_event_class_set_log_level(struct bt_event_class *event_class,
+ enum bt_event_class_log_level log_level);
+
+extern const char *bt_event_class_get_emf_uri(
+ struct bt_event_class *event_class);
+
+extern int bt_event_class_set_emf_uri(struct bt_event_class *event_class,
+ const char *emf_uri);
+
+extern struct bt_field_type *bt_event_class_borrow_specific_context_field_type(
+ struct bt_event_class *event_class);
+
+extern int bt_event_class_set_specific_context_field_type(
+ struct bt_event_class *event_class,
+ struct bt_field_type *field_type);
+
+extern struct bt_field_type *bt_event_class_borrow_payload_field_type(
+ struct bt_event_class *event_class);
+
+extern int bt_event_class_set_payload_field_type(
+ struct bt_event_class *event_class,
+ struct bt_field_type *field_type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_EVENT_CLASS_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_EVENT_HEADER_FIELD_H
+#define BABELTRACE_TRACE_IR_EVENT_HEADER_FIELD_H
+
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_stream_class;
+struct bt_event_header_field;
+struct bt_field;
+
+extern
+struct bt_event_header_field *bt_event_header_field_create(
+ struct bt_stream_class *stream_class);
+
+extern
+struct bt_field *bt_event_header_field_borrow_field(
+ struct bt_event_header_field *field);
+
+extern
+void bt_event_header_field_release(struct bt_event_header_field *field);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_EVENT_HEADER_FIELD_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_EVENT_INTERNAL_H
+#define BABELTRACE_TRACE_IR_EVENT_INTERNAL_H
+
+/*
+ * Babeltrace - Trace IR: Event internal
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* Protection: this file uses BT_LIB_LOG*() macros directly */
+#ifndef BABELTRACE_LIB_LOGGING_INTERNAL_H
+# error Please define include <babeltrace/lib-logging-internal.h> before including this file.
+#endif
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/values.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/stream-internal.h>
+#include <babeltrace/trace-ir/packet.h>
+#include <babeltrace/trace-ir/packet-internal.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/event-class-internal.h>
+#include <babeltrace/trace-ir/field-wrapper-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <glib.h>
+
+#define BT_ASSERT_PRE_EVENT_HOT(_event) \
+ BT_ASSERT_PRE_HOT((_event), "Event", ": %!+e", (_event))
+
+struct bt_event {
+ struct bt_object base;
+ struct bt_event_class *class;
+ struct bt_packet *packet;
+ struct bt_field_wrapper *header_field;
+ struct bt_field *common_context_field;
+ struct bt_field *specific_context_field;
+ struct bt_field *payload_field;
+ struct bt_clock_value *default_cv;
+ bool frozen;
+};
+
+BT_HIDDEN
+void bt_event_destroy(struct bt_event *event);
+
+BT_HIDDEN
+struct bt_event *bt_event_new(struct bt_event_class *event_class);
+
+BT_HIDDEN
+void _bt_event_set_is_frozen(struct bt_event *event, bool is_frozen);
+
+#ifdef BT_DEV_MODE
+# define bt_event_set_is_frozen _bt_event_set_is_frozen
+#else
+# define bt_event_set_is_frozen(_event, _is_frozen)
+#endif
+
+BT_UNUSED
+static inline
+void _bt_event_reset_dev_mode(struct bt_event *event)
+{
+ BT_ASSERT(event);
+
+ if (event->header_field) {
+ bt_field_set_is_frozen(
+ event->header_field->field, false);
+ bt_field_reset(
+ event->header_field->field);
+ }
+
+ if (event->common_context_field) {
+ bt_field_set_is_frozen(
+ event->common_context_field, false);
+ bt_field_reset(
+ event->common_context_field);
+ }
+
+ if (event->specific_context_field) {
+ bt_field_set_is_frozen(
+ event->specific_context_field, false);
+ bt_field_reset(event->specific_context_field);
+ }
+
+ if (event->payload_field) {
+ bt_field_set_is_frozen(
+ event->payload_field, false);
+ bt_field_reset(event->payload_field);
+ }
+}
+
+#ifdef BT_DEV_MODE
+# define bt_event_reset_dev_mode _bt_event_reset_dev_mode
+#else
+# define bt_event_reset_dev_mode(_x)
+#endif
+
+static inline
+void bt_event_reset(struct bt_event *event)
+{
+ BT_ASSERT(event);
+ BT_LIB_LOGD("Resetting event: %!+e", event);
+ bt_event_set_is_frozen(event, false);
+
+ if (event->default_cv) {
+ bt_clock_value_reset(event->default_cv);
+ }
+
+ bt_object_put_no_null_check(&event->packet->base);
+ event->packet = NULL;
+}
+
+static inline
+void bt_event_recycle(struct bt_event *event)
+{
+ struct bt_event_class *event_class;
+
+ BT_ASSERT(event);
+ BT_LIB_LOGD("Recycling event: %!+e", event);
+
+ /*
+ * Those are the important ordered steps:
+ *
+ * 1. Reset the event object (put any permanent reference it
+ * has, unfreeze it and its fields in developer mode, etc.),
+ * but do NOT put its class's reference. This event class
+ * contains the pool to which we're about to recycle this
+ * event object, so we must guarantee its existence thanks
+ * to this existing reference.
+ *
+ * 2. Move the event class reference to our `event_class`
+ * variable so that we can set the event's class member
+ * to NULL before recycling it. We CANNOT do this after
+ * we put the event class reference because this bt_put()
+ * could destroy the event class, also destroying its
+ * event pool, thus also destroying our event object (this
+ * would result in an invalid write access).
+ *
+ * 3. Recycle the event object.
+ *
+ * 4. Put our event class reference.
+ */
+ bt_event_reset(event);
+ event_class = event->class;
+ BT_ASSERT(event_class);
+ event->class = NULL;
+ bt_object_pool_recycle_object(&event_class->event_pool, event);
+ bt_object_put_no_null_check(&event_class->base);
+}
+
+static inline
+void bt_event_set_packet(struct bt_event *event, struct bt_packet *packet)
+{
+ BT_ASSERT_PRE_NON_NULL(event, "Event");
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ BT_ASSERT_PRE_EVENT_HOT(event);
+ BT_ASSERT_PRE(bt_event_class_borrow_stream_class(
+ event->class) == packet->stream->class,
+ "Packet's stream class and event's stream class differ: "
+ "%![event-]+e, %![packet-]+a", event, packet);
+
+ BT_ASSERT(!event->packet);
+ event->packet = packet;
+ bt_object_get_no_null_check_no_parent_check(&event->packet->base);
+ BT_LIB_LOGV("Set event's packet: %![event-]+e, %![packet-]+a",
+ event, packet);
+}
+
+static inline
+struct bt_event *bt_event_create(struct bt_event_class *event_class,
+ struct bt_packet *packet)
+{
+ struct bt_event *event = NULL;
+
+ BT_ASSERT(event_class);
+ event = bt_object_pool_create_object(&event_class->event_pool);
+ if (unlikely(!event)) {
+ BT_LIB_LOGE("Cannot allocate one event from event class's event pool: "
+ "%![ec-]+E", event_class);
+ goto end;
+ }
+
+ if (likely(!event->class)) {
+ event->class = event_class;
+ bt_object_get_no_null_check(&event_class->base);
+ }
+
+ BT_ASSERT(packet);
+ bt_event_set_packet(event, packet);
+ goto end;
+
+end:
+ return event;
+}
+
+#endif /* BABELTRACE_TRACE_IR_EVENT_INTERNAL_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_EVENT_H
+#define BABELTRACE_TRACE_IR_EVENT_H
+
+/*
+ * BabelTrace - Trace IR: Event
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+/* For enum bt_clock_value_status */
+#include <babeltrace/trace-ir/clock-value.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_event;
+struct bt_event_header_field;
+struct bt_clock_value;
+struct bt_event_class;
+struct bt_field;
+struct bt_packet;
+
+extern struct bt_event_class *bt_event_borrow_class(struct bt_event *event);
+
+extern struct bt_packet *bt_event_borrow_packet(struct bt_event *event);
+
+extern struct bt_stream *bt_event_borrow_stream(struct bt_event *event);
+
+extern struct bt_field *bt_event_borrow_header_field(struct bt_event *event);
+
+extern int bt_event_move_header(struct bt_event *event,
+ struct bt_event_header_field *header);
+
+extern struct bt_field *bt_event_borrow_common_context_field(
+ struct bt_event *event);
+
+extern struct bt_field *bt_event_borrow_specific_context_field(
+ struct bt_event *event);
+
+extern struct bt_field *bt_event_borrow_payload_field(struct bt_event *event);
+
+extern int bt_event_set_default_clock_value(struct bt_event *event,
+ uint64_t value_cycles);
+
+extern enum bt_clock_value_status bt_event_borrow_default_clock_value(
+ struct bt_event *event, struct bt_clock_value **clock_value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_EVENT_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_FIELD_PATH_INTERNAL
+#define BABELTRACE_TRACE_IR_FIELD_PATH_INTERNAL
+
+/*
+ * BabelTrace - Trace IR: Field path
+ *
+ * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <babeltrace/object-internal.h>
+#include <babeltrace/trace-ir/field-path.h>
+#include <babeltrace/assert-internal.h>
+#include <glib.h>
+
+struct bt_field_path {
+ struct bt_object base;
+ enum bt_scope root;
+
+ /* Array of `uint64_t` (indexes) */
+ GArray *indexes;
+};
+
+BT_HIDDEN
+struct bt_field_path *bt_field_path_create(void);
+
+static inline
+uint64_t bt_field_path_get_index_by_index_inline(
+ struct bt_field_path *field_path, uint64_t index)
+{
+ BT_ASSERT(field_path);
+ BT_ASSERT(index < field_path->indexes->len);
+ return g_array_index(field_path->indexes, uint64_t, index);
+}
+
+#endif /* BABELTRACE_TRACE_IR_FIELD_PATH_INTERNAL */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_FIELD_PATH_H
+#define BABELTRACE_TRACE_IR_FIELD_PATH_H
+
+/*
+ * BabelTrace - Trace IR: Field path
+ *
+ * Copyright 2016-2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_field_path;
+
+enum bt_scope {
+ BT_SCOPE_PACKET_HEADER,
+ BT_SCOPE_PACKET_CONTEXT,
+ BT_SCOPE_EVENT_HEADER,
+ BT_SCOPE_EVENT_COMMON_CONTEXT,
+ BT_SCOPE_EVENT_SPECIFIC_CONTEXT,
+ BT_SCOPE_EVENT_PAYLOAD,
+};
+
+extern enum bt_scope bt_field_path_get_root_scope(
+ struct bt_field_path *field_path);
+
+extern uint64_t bt_field_path_get_index_count(
+ struct bt_field_path *field_path);
+
+extern uint64_t bt_field_path_get_index_by_index(
+ struct bt_field_path *field_path, uint64_t index);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_FIELD_PATH_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_FIELD_TYPES_INTERNAL_H
+#define BABELTRACE_TRACE_IR_FIELD_TYPES_INTERNAL_H
+
+/*
+ * BabelTrace - Trace IR: Event field types internal
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/clock-class.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/types.h>
+#include <stdint.h>
+#include <glib.h>
+
+#define BT_ASSERT_PRE_FT_IS_INT(_ft, _name) \
+ BT_ASSERT_PRE( \
+ ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_INTEGER || \
+ ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_SIGNED_INTEGER || \
+ ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION || \
+ ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_SIGNED_ENUMERATION, \
+ _name " is not an integer field type: %![ft-]+F", (_ft))
+
+#define BT_ASSERT_PRE_FT_IS_UNSIGNED_INT(_ft, _name) \
+ BT_ASSERT_PRE( \
+ ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_INTEGER || \
+ ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION, \
+ _name " is not an unsigned integer field type: %![ft-]+F", (_ft))
+
+#define BT_ASSERT_PRE_FT_IS_ENUM(_ft, _name) \
+ BT_ASSERT_PRE( \
+ ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION || \
+ ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_SIGNED_ENUMERATION, \
+ _name " is not an enumeration field type: %![ft-]+F", (_ft))
+
+#define BT_ASSERT_PRE_FT_IS_ARRAY(_ft, _name) \
+ BT_ASSERT_PRE( \
+ ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_STATIC_ARRAY || \
+ ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_DYNAMIC_ARRAY, \
+ _name " is not an array field type: %![ft-]+F", (_ft))
+
+#define BT_ASSERT_PRE_FT_HAS_ID(_ft, _id, _name) \
+ BT_ASSERT_PRE(((struct bt_field_type *) (_ft))->id == (_id), \
+ _name " has the wrong ID: expected-id=%s, " \
+ "%![ft-]+F", bt_common_field_type_id_string(_id), (_ft))
+
+#define BT_ASSERT_PRE_FT_HOT(_ft, _name) \
+ BT_ASSERT_PRE_HOT((struct bt_field_type *) (_ft), \
+ (_name), ": %!+F", (_ft))
+
+#define BT_FIELD_TYPE_NAMED_FT_AT_INDEX(_ft, _index) \
+ (&g_array_index(((struct bt_field_type_named_field_types_container *) (_ft))->named_fts, \
+ struct bt_named_field_type, (_index)))
+
+#define BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(_ft, _index) \
+ (&g_array_index(((struct bt_field_type_enumeration *) (_ft))->mappings, \
+ struct bt_field_type_enumeration_mapping, (_index)))
+
+#define BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(_mapping, _index) \
+ (&g_array_index((_mapping)->ranges, \
+ struct bt_field_type_enumeration_mapping_range, (_index)))
+
+struct bt_field;
+struct bt_field_type;
+
+struct bt_field_type {
+ struct bt_object base;
+ enum bt_field_type_id id;
+ bool frozen;
+
+ /*
+ * Only used in developer mode, this flag indicates whether or
+ * not this field type is part of a trace.
+ */
+ bool part_of_trace;
+};
+
+struct bt_field_type_integer {
+ struct bt_field_type common;
+
+ /*
+ * Value range of fields built from this integer field type:
+ * this is an equivalent integer size in bits. More formally,
+ * `range` is `n` in:
+ *
+ * Unsigned range: [0, 2^n - 1]
+ * Signed range: [-2^(n - 1), 2^(n - 1) - 1]
+ */
+ uint64_t range;
+
+ enum bt_field_type_integer_preferred_display_base base;
+};
+
+struct bt_field_type_enumeration_mapping_range {
+ union {
+ uint64_t u;
+ int64_t i;
+ } lower;
+
+ union {
+ uint64_t u;
+ int64_t i;
+ } upper;
+};
+
+struct bt_field_type_enumeration_mapping {
+ GString *label;
+
+ /* Array of `struct bt_field_type_enumeration_mapping_range` */
+ GArray *ranges;
+};
+
+struct bt_field_type_enumeration {
+ struct bt_field_type_integer common;
+
+ /* Array of `struct bt_field_type_enumeration_mapping *` */
+ GArray *mappings;
+
+ /*
+ * This is an array of `const char *` which acts as a temporary
+ * (potentially growing) buffer for
+ * bt_field_type_unsigned_enumeration_get_mapping_labels_by_value()
+ * and
+ * bt_field_type_signed_enumeration_get_mapping_labels_by_value().
+ *
+ * The actual strings are owned by the mappings above.
+ */
+ GPtrArray *label_buf;
+};
+
+struct bt_field_type_real {
+ struct bt_field_type common;
+ bool is_single_precision;
+};
+
+struct bt_field_type_string {
+ struct bt_field_type common;
+};
+
+/* A named field type is a (name, field type) pair */
+struct bt_named_field_type {
+ GString *name;
+
+ /* Owned by this */
+ struct bt_field_type *ft;
+};
+
+/*
+ * This is the base field type for a container of named field types.
+ * Structure and variant field types inherit this.
+ */
+struct bt_field_type_named_field_types_container {
+ struct bt_field_type common;
+
+ /*
+ * Key: `const char *`, not owned by this (owned by named field
+ * type objects contained in `named_fts` below).
+ */
+ GHashTable *name_to_index;
+
+ /* Array of `struct bt_named_field_type` */
+ GArray *named_fts;
+};
+
+struct bt_field_type_structure {
+ struct bt_field_type_named_field_types_container common;
+};
+
+struct bt_field_type_array {
+ struct bt_field_type common;
+
+ /* Owned by this */
+ struct bt_field_type *element_ft;
+};
+
+struct bt_field_type_static_array {
+ struct bt_field_type_array common;
+ uint64_t length;
+};
+
+struct bt_field_type_dynamic_array {
+ struct bt_field_type_array common;
+
+ /* Weak: never dereferenced, only use to find it elsewhere */
+ struct bt_field_type *length_ft;
+
+ /* Owned by this */
+ struct bt_field_path *length_field_path;
+};
+
+struct bt_field_type_variant {
+ struct bt_field_type_named_field_types_container common;
+
+ /* Weak: never dereferenced, only use to find it elsewhere */
+ struct bt_field_type *selector_ft;
+
+ /* Owned by this */
+ struct bt_field_path *selector_field_path;
+};
+
+static inline
+bool bt_field_type_has_known_id(struct bt_field_type *ft)
+{
+ return ft->id >= BT_FIELD_TYPE_ID_UNSIGNED_INTEGER &&
+ ft->id <= BT_FIELD_TYPE_ID_VARIANT;
+}
+
+BT_HIDDEN
+void _bt_field_type_freeze(struct bt_field_type *field_type);
+
+#ifdef BT_DEV_MODE
+# define bt_field_type_freeze _bt_field_type_freeze
+#else
+# define bt_field_type_freeze(_ft)
+#endif
+
+/*
+ * This function recursively marks `field_type` and its children as
+ * being part of a trace. This is used to validate that all field types
+ * are used at a single location within trace objects even if they are
+ * shared objects for other purposes.
+ */
+BT_HIDDEN
+void _bt_field_type_make_part_of_trace(struct bt_field_type *field_type);
+
+#ifdef BT_DEV_MODE
+# define bt_field_type_make_part_of_trace _bt_field_type_make_part_of_trace
+#else
+# define bt_field_type_make_part_of_trace(_ft) ((void) _ft)
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_FIELD_TYPES_INTERNAL_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_FIELD_TYPES_H
+#define BABELTRACE_TRACE_IR_FIELD_TYPES_H
+
+/*
+ * BabelTrace - Trace IR: Event field types
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+/* For bt_get() */
+#include <babeltrace/ref.h>
+
+/* For bt_bool */
+#include <babeltrace/types.h>
+
+#include <stdint.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_field_type;
+struct bt_field_path;
+struct bt_field_type_signed_enumeration_mapping_ranges;
+struct bt_field_type_unsigned_enumeration_mapping_ranges;
+
+typedef const char * const *bt_field_type_enumeration_mapping_label_array;
+
+enum bt_field_type_id {
+ BT_FIELD_TYPE_ID_UNSIGNED_INTEGER,
+ BT_FIELD_TYPE_ID_SIGNED_INTEGER,
+ BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION,
+ BT_FIELD_TYPE_ID_SIGNED_ENUMERATION,
+ BT_FIELD_TYPE_ID_REAL,
+ BT_FIELD_TYPE_ID_STRING,
+ BT_FIELD_TYPE_ID_STRUCTURE,
+ BT_FIELD_TYPE_ID_STATIC_ARRAY,
+ BT_FIELD_TYPE_ID_DYNAMIC_ARRAY,
+ BT_FIELD_TYPE_ID_VARIANT,
+};
+
+enum bt_field_type_integer_preferred_display_base {
+ BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_BINARY,
+ BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL,
+ BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL,
+ BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL,
+};
+
+extern enum bt_field_type_id bt_field_type_get_type_id(
+ struct bt_field_type *field_type);
+
+extern struct bt_field_type *bt_field_type_unsigned_integer_create(void);
+
+extern struct bt_field_type *bt_field_type_signed_integer_create(void);
+
+extern uint64_t bt_field_type_integer_get_field_value_range(
+ struct bt_field_type *field_type);
+
+extern int bt_field_type_integer_set_field_value_range(
+ struct bt_field_type *field_type, uint64_t size);
+
+extern enum bt_field_type_integer_preferred_display_base
+bt_field_type_integer_get_preferred_display_base(
+ struct bt_field_type *field_type);
+
+extern int bt_field_type_integer_set_preferred_display_base(
+ struct bt_field_type *field_type,
+ enum bt_field_type_integer_preferred_display_base base);
+
+extern struct bt_field_type *bt_field_type_real_create(void);
+
+extern bt_bool bt_field_type_real_is_single_precision(
+ struct bt_field_type *field_type);
+
+extern int bt_field_type_real_set_is_single_precision(
+ struct bt_field_type *field_type,
+ bt_bool is_single_precision);
+
+extern struct bt_field_type *bt_field_type_unsigned_enumeration_create(void);
+
+extern struct bt_field_type *bt_field_type_signed_enumeration_create(void);
+
+extern uint64_t bt_field_type_enumeration_get_mapping_count(
+ struct bt_field_type *field_type);
+
+extern void bt_field_type_unsigned_enumeration_borrow_mapping_by_index(
+ struct bt_field_type *field_type, uint64_t index,
+ const char **label,
+ struct bt_field_type_unsigned_enumeration_mapping_ranges **ranges);
+
+extern void bt_field_type_signed_enumeration_borrow_mapping_by_index(
+ struct bt_field_type *field_type, uint64_t index,
+ const char **label,
+ struct bt_field_type_signed_enumeration_mapping_ranges **ranges);
+
+extern uint64_t bt_field_type_unsigned_enumeration_mapping_ranges_get_range_count(
+ struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges);
+
+extern uint64_t bt_field_type_signed_enumeration_mapping_ranges_get_range_count(
+ struct bt_field_type_signed_enumeration_mapping_ranges *ranges);
+
+extern void bt_field_type_unsigned_enumeration_mapping_ranges_get_range_by_index(
+ struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges,
+ uint64_t index, uint64_t *lower, uint64_t *upper);
+
+extern void bt_field_type_signed_enumeration_mapping_ranges_get_range_by_index(
+ struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges,
+ uint64_t index, int64_t *lower, int64_t *upper);
+
+extern int bt_field_type_unsigned_enumeration_get_mapping_labels_by_value(
+ struct bt_field_type *field_type, uint64_t value,
+ bt_field_type_enumeration_mapping_label_array *label_array,
+ uint64_t *count);
+
+extern int bt_field_type_signed_enumeration_get_mapping_labels_by_value(
+ struct bt_field_type *field_type, int64_t value,
+ bt_field_type_enumeration_mapping_label_array *label_array,
+ uint64_t *count);
+
+extern int bt_field_type_unsigned_enumeration_map_range(
+ struct bt_field_type *field_type, const char *label,
+ uint64_t range_lower, uint64_t range_upper);
+
+extern int bt_field_type_signed_enumeration_map_range(
+ struct bt_field_type *field_type, const char *label,
+ int64_t range_lower, int64_t range_upper);
+
+extern struct bt_field_type *bt_field_type_string_create(void);
+
+extern struct bt_field_type *bt_field_type_structure_create(void);
+
+extern uint64_t bt_field_type_structure_get_member_count(
+ struct bt_field_type *field_type);
+
+extern void bt_field_type_structure_borrow_member_by_index(
+ struct bt_field_type *struct_field_type, uint64_t index,
+ const char **name, struct bt_field_type **field_type);
+
+extern
+struct bt_field_type *bt_field_type_structure_borrow_member_field_type_by_name(
+ struct bt_field_type *field_type, const char *name);
+
+extern int bt_field_type_structure_append_member(
+ struct bt_field_type *struct_field_type, const char *name,
+ struct bt_field_type *field_type);
+
+extern struct bt_field_type *bt_field_type_static_array_create(
+ struct bt_field_type *elem_field_type,
+ uint64_t length);
+
+extern struct bt_field_type *bt_field_type_dynamic_array_create(
+ struct bt_field_type *elem_field_type);
+
+extern struct bt_field_type *bt_field_type_array_borrow_element_field_type(
+ struct bt_field_type *field_type);
+
+extern uint64_t bt_field_type_static_array_get_length(
+ struct bt_field_type *field_type);
+
+extern struct bt_field_path *
+bt_field_type_dynamic_array_borrow_length_field_path(
+ struct bt_field_type *field_type);
+
+extern int bt_field_type_dynamic_array_set_length_field_type(
+ struct bt_field_type *field_type,
+ struct bt_field_type *length_field_type);
+
+extern struct bt_field_type *bt_field_type_variant_create(void);
+
+extern struct bt_field_path *
+bt_field_type_variant_borrow_selector_field_path(
+ struct bt_field_type *field_type);
+
+extern int bt_field_type_variant_set_selector_field_type(
+ struct bt_field_type *field_type,
+ struct bt_field_type *selector_field_type);
+
+extern uint64_t bt_field_type_variant_get_option_count(
+ struct bt_field_type *field_type);
+
+extern void bt_field_type_variant_borrow_option_by_index(
+ struct bt_field_type *variant_field_type, uint64_t index,
+ const char **name, struct bt_field_type **field_type);
+
+extern
+struct bt_field_type *bt_field_type_variant_borrow_option_field_type_by_name(
+ struct bt_field_type *field_type,
+ const char *name);
+
+extern int bt_field_type_variant_append_option(
+ struct bt_field_type *var_field_type,
+ const char *name, struct bt_field_type *field_type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_FIELD_TYPES_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_FIELD_WRAPPER_INTERNAL_H
+#define BABELTRACE_TRACE_IR_FIELD_WRAPPER_INTERNAL_H
+
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/object-pool-internal.h>
+#include <babeltrace/object-internal.h>
+
+struct bt_field_wrapper {
+ struct bt_object base;
+
+ /* Owned by this */
+ struct bt_field *field;
+};
+
+BT_HIDDEN
+struct bt_field_wrapper *bt_field_wrapper_new(void *data);
+
+BT_HIDDEN
+void bt_field_wrapper_destroy(struct bt_field_wrapper *field);
+
+BT_HIDDEN
+struct bt_field_wrapper *bt_field_wrapper_create(
+ struct bt_object_pool *pool, struct bt_field_type *ft);
+
+#endif /* BABELTRACE_TRACE_IR_FIELD_WRAPPER_INTERNAL_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_FIELDS_INTERNAL_H
+#define BABELTRACE_TRACE_IR_FIELDS_INTERNAL_H
+
+/*
+ * Babeltrace - Trace IR: Event Fields internal
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/common-internal.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/utils-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/types.h>
+#include <stdint.h>
+#include <string.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <glib.h>
+
+#define BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(_field, _type_id, _name) \
+ BT_ASSERT_PRE(((struct bt_field *) (_field))->type->id == (_type_id), \
+ _name " has the wrong type ID: expected-type-id=%s, " \
+ "%![field-]+f", \
+ bt_common_field_type_id_string(_type_id), (_field))
+
+#define BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(_field, _name) \
+ BT_ASSERT_PRE( \
+ ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_UNSIGNED_INTEGER || \
+ ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION, \
+ _name " is not an unsigned integer field: %![field-]+f", \
+ (_field))
+
+#define BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(_field, _name) \
+ BT_ASSERT_PRE( \
+ ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_SIGNED_INTEGER || \
+ ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_SIGNED_ENUMERATION, \
+ _name " is not a signed integer field: %![field-]+f", \
+ (_field))
+
+#define BT_ASSERT_PRE_FIELD_IS_ARRAY(_field, _name) \
+ BT_ASSERT_PRE( \
+ ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_STATIC_ARRAY || \
+ ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_DYNAMIC_ARRAY, \
+ _name " is not an array field: %![field-]+f", (_field))
+
+#define BT_ASSERT_PRE_FIELD_IS_SET(_field, _name) \
+ BT_ASSERT_PRE(bt_field_is_set(_field), \
+ _name " is not set: %!+f", (_field))
+
+#define BT_ASSERT_PRE_FIELD_HOT(_field, _name) \
+ BT_ASSERT_PRE_HOT((struct bt_field *) (_field), (_name), \
+ ": %!+f", (_field))
+
+struct bt_field;
+
+typedef struct bt_field *(* bt_field_create_func)(struct bt_field_type *);
+typedef void (*bt_field_method_set_is_frozen)(struct bt_field *, bool);
+typedef bool (*bt_field_method_is_set)(struct bt_field *);
+typedef void (*bt_field_method_reset)(struct bt_field *);
+
+struct bt_field_methods {
+ bt_field_method_set_is_frozen set_is_frozen;
+ bt_field_method_is_set is_set;
+ bt_field_method_reset reset;
+};
+
+struct bt_field {
+ struct bt_object base;
+
+ /* Owned by this */
+ struct bt_field_type *type;
+
+ /* Virtual table for slow path (dev mode) operations */
+ struct bt_field_methods *methods;
+
+ bool is_set;
+ bool frozen;
+};
+
+struct bt_field_integer {
+ struct bt_field common;
+
+ union {
+ uint64_t u;
+ int64_t i;
+ } value;
+};
+
+struct bt_field_real {
+ struct bt_field common;
+ double value;
+};
+
+struct bt_field_structure {
+ struct bt_field common;
+
+ /* Array of `struct bt_field *`, owned by this */
+ GPtrArray *fields;
+};
+
+struct bt_field_variant {
+ struct bt_field common;
+
+ /* Weak: belongs to `fields` below */
+ struct bt_field *selected_field;
+
+ /* Index of currently selected field */
+ uint64_t selected_index;
+
+ /* Array of `struct bt_field *`, owned by this */
+ GPtrArray *fields;
+};
+
+struct bt_field_array {
+ struct bt_field common;
+
+ /* Array of `struct bt_field *`, owned by this */
+ GPtrArray *fields;
+
+ /* Current effective length */
+ uint64_t length;
+};
+
+struct bt_field_string {
+ struct bt_field common;
+ GArray *buf;
+ uint64_t length;
+};
+
+#ifdef BT_DEV_MODE
+# define bt_field_set_is_frozen _bt_field_set_is_frozen
+# define bt_field_is_set _bt_field_is_set
+# define bt_field_reset _bt_field_reset
+# define bt_field_set_single _bt_field_set_single
+#else
+# define bt_field_set_is_frozen(_field, _is_frozen)
+# define bt_field_is_set(_field) (BT_FALSE)
+# define bt_field_reset(_field)
+# define bt_field_set_single(_field, _val)
+#endif
+
+BT_HIDDEN
+void _bt_field_set_is_frozen(struct bt_field *field, bool is_frozen);
+
+static inline
+void _bt_field_reset(struct bt_field *field)
+{
+ BT_ASSERT(field);
+ BT_ASSERT(field->methods->reset);
+ field->methods->reset(field);
+}
+
+static inline
+void _bt_field_set_single(struct bt_field *field, bool value)
+{
+ BT_ASSERT(field);
+ field->is_set = value;
+}
+
+static inline
+bt_bool _bt_field_is_set(struct bt_field *field)
+{
+ bt_bool is_set = BT_FALSE;
+
+ if (!field) {
+ goto end;
+ }
+
+ BT_ASSERT(bt_field_type_has_known_id(field->type));
+ BT_ASSERT(field->methods->is_set);
+ is_set = field->methods->is_set(field);
+
+end:
+ return is_set;
+}
+
+BT_HIDDEN
+struct bt_field *bt_field_create(struct bt_field_type *type);
+
+BT_HIDDEN
+void bt_field_destroy(struct bt_field *field);
+
+#endif /* BABELTRACE_TRACE_IR_FIELDS_INTERNAL_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_FIELDS_H
+#define BABELTRACE_TRACE_IR_FIELDS_H
+
+/*
+ * Babeltrace - Trace IR: Event Fields
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <stdint.h>
+
+/* For bt_bool */
+#include <babeltrace/types.h>
+
+/* For enum bt_field_type_id */
+#include <babeltrace/trace-ir/field-types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_field;
+struct bt_field_type;
+struct bt_field_type_enumeration_mapping_iterator;
+
+extern struct bt_field_type *bt_field_borrow_type(struct bt_field *field);
+
+extern enum bt_field_type_id bt_field_get_type_id(struct bt_field *field);
+
+extern int64_t bt_field_signed_integer_get_value(struct bt_field *field);
+
+extern void bt_field_signed_integer_set_value(struct bt_field *field,
+ int64_t value);
+
+extern uint64_t bt_field_unsigned_integer_get_value(struct bt_field *field);
+
+extern void bt_field_unsigned_integer_set_value(struct bt_field *field,
+ uint64_t value);
+
+extern double bt_field_real_get_value(struct bt_field *field);
+
+extern void bt_field_real_set_value(struct bt_field *field, double value);
+
+extern int bt_field_unsigned_enumeration_get_mapping_labels(
+ struct bt_field *field,
+ bt_field_type_enumeration_mapping_label_array *label_array,
+ uint64_t *count);
+
+extern int bt_field_signed_enumeration_get_mapping_labels(
+ struct bt_field *field,
+ bt_field_type_enumeration_mapping_label_array *label_array,
+ uint64_t *count);
+
+extern const char *bt_field_string_get_value(struct bt_field *field);
+
+extern uint64_t bt_field_string_get_length(struct bt_field *field);
+
+extern int bt_field_string_set_value(struct bt_field *field, const char *value);
+
+extern int bt_field_string_append(struct bt_field *field, const char *value);
+
+extern int bt_field_string_append_with_length(struct bt_field *field,
+ const char *value, uint64_t length);
+
+extern int bt_field_string_clear(struct bt_field *field);
+
+extern struct bt_field *bt_field_structure_borrow_member_field_by_index(
+ struct bt_field *field, uint64_t index);
+
+extern struct bt_field *bt_field_structure_borrow_member_field_by_name(
+ struct bt_field *field, const char *name);
+
+extern uint64_t bt_field_array_get_length(struct bt_field *field);
+
+extern struct bt_field *bt_field_array_borrow_element_field_by_index(
+ struct bt_field *field, uint64_t index);
+
+extern int bt_field_dynamic_array_set_length(struct bt_field *field,
+ uint64_t length);
+
+extern int bt_field_variant_select_option_field(struct bt_field *field,
+ uint64_t index);
+
+extern uint64_t bt_field_variant_get_selected_option_field_index(
+ struct bt_field *field);
+
+extern struct bt_field *bt_field_variant_borrow_selected_option_field(
+ struct bt_field *field);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_FIELDS_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_PACKET_CONTEXT_FIELD_H
+#define BABELTRACE_TRACE_IR_PACKET_CONTEXT_FIELD_H
+
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_stream_class;
+struct bt_packet_context_field;
+struct bt_field;
+
+extern
+struct bt_packet_context_field *bt_packet_context_field_create(
+ struct bt_stream_class *stream_class);
+
+extern
+struct bt_field *bt_packet_context_field_borrow_field(
+ struct bt_packet_context_field *field);
+
+extern
+void bt_packet_context_field_release(struct bt_packet_context_field *field);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_PACKET_CONTEXT_FIELD_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_PACKET_HEADER_FIELD_H
+#define BABELTRACE_TRACE_IR_PACKET_HEADER_FIELD_H
+
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_trace;
+struct bt_packet_header_field;
+struct bt_field;
+
+extern
+struct bt_packet_header_field *bt_packet_header_field_create(
+ struct bt_trace *trace);
+
+extern
+struct bt_field *bt_packet_header_field_borrow_field(
+ struct bt_packet_header_field *field);
+
+extern
+void bt_packet_header_field_release(struct bt_packet_header_field *field);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_PACKET_HEADER_FIELD_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_PACKET_INTERNAL_H
+#define BABELTRACE_TRACE_IR_PACKET_INTERNAL_H
+
+/*
+ * Babeltrace - Trace IR: Stream packet internal
+ *
+ * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdbool.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/trace-ir/clock-value.h>
+#include <babeltrace/trace-ir/packet.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/field-wrapper-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/property-internal.h>
+
+struct bt_packet {
+ struct bt_object base;
+ struct bt_field_wrapper *header_field;
+ struct bt_field_wrapper *context_field;
+ struct bt_stream *stream;
+ struct bt_clock_value *default_beginning_cv;
+ struct bt_clock_value *default_end_cv;
+ struct bt_property_uint discarded_event_counter_snapshot;
+ struct bt_property_uint packet_counter_snapshot;
+ bool frozen;
+};
+
+BT_HIDDEN
+void _bt_packet_set_is_frozen(struct bt_packet *packet, bool is_frozen);
+
+#ifdef BT_DEV_MODE
+# define bt_packet_set_is_frozen _bt_packet_set_is_frozen
+#else
+# define bt_packet_set_is_frozen(_packet, _is_frozen)
+#endif /* BT_DEV_MODE */
+
+BT_HIDDEN
+struct bt_packet *bt_packet_new(struct bt_stream *stream);
+
+BT_HIDDEN
+void bt_packet_recycle(struct bt_packet *packet);
+
+BT_HIDDEN
+void bt_packet_destroy(struct bt_packet *packet);
+
+#endif /* BABELTRACE_TRACE_IR_PACKET_INTERNAL_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_PACKET_H
+#define BABELTRACE_TRACE_IR_PACKET_H
+
+/*
+ * BabelTrace - Trace IR: Stream packet
+ *
+ * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <stdint.h>
+
+/* For enum bt_property_availability */
+#include <babeltrace/property.h>
+
+/* For enum bt_clock_value_status */
+#include <babeltrace/trace-ir/clock-value.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_packet;
+struct bt_packet_header_field;
+struct bt_packet_context_field;
+struct bt_stream;
+struct bt_clock_value;
+
+extern struct bt_packet *bt_packet_create(struct bt_stream *stream);
+
+extern struct bt_stream *bt_packet_borrow_stream(struct bt_packet *packet);
+
+extern
+struct bt_field *bt_packet_borrow_header_field(struct bt_packet *packet);
+
+extern
+int bt_packet_move_header_field(struct bt_packet *packet,
+ struct bt_packet_header_field *header);
+
+extern
+struct bt_field *bt_packet_borrow_context_field(struct bt_packet *packet);
+
+extern
+int bt_packet_move_context_field(struct bt_packet *packet,
+ struct bt_packet_context_field *context);
+
+extern
+enum bt_clock_value_status bt_packet_borrow_default_beginning_clock_value(
+ struct bt_packet *packet, struct bt_clock_value **clock_value);
+
+extern
+int bt_packet_set_default_beginning_clock_value(struct bt_packet *packet,
+ uint64_t value_cycles);
+
+extern
+enum bt_clock_value_status bt_packet_borrow_default_end_clock_valeu(
+ struct bt_packet *packet, struct bt_clock_value **clock_value);
+
+extern
+int bt_packet_set_default_end_clock_value(struct bt_packet *packet,
+ uint64_t value_cycles);
+
+extern
+enum bt_property_availability bt_packet_get_discarded_event_counter_snapshot(
+ struct bt_packet *packet, uint64_t *value);
+
+extern
+int bt_packet_set_discarded_event_counter_snapshot(struct bt_packet *packet,
+ uint64_t value);
+
+extern
+enum bt_property_availability bt_packet_get_packet_counter_snapshot(
+ struct bt_packet *packet, uint64_t *value);
+
+extern
+int bt_packet_set_packet_counter_snapshot(struct bt_packet *packet,
+ uint64_t value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_PACKET_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_RESOLVE_FIELD_PATH_INTERNAL
+#define BABELTRACE_TRACE_IR_RESOLVE_FIELD_PATH_INTERNAL
+
+/*
+ * BabelTrace - Trace IR: Field path
+ *
+ * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <babeltrace/object-internal.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/field-path.h>
+#include <glib.h>
+
+struct bt_resolve_field_path_context {
+ struct bt_field_type *packet_header;
+ struct bt_field_type *packet_context;
+ struct bt_field_type *event_header;
+ struct bt_field_type *event_common_context;
+ struct bt_field_type *event_specific_context;
+ struct bt_field_type *event_payload;
+};
+
+BT_HIDDEN
+int bt_resolve_field_paths(struct bt_field_type *ft,
+ struct bt_resolve_field_path_context *ctx);
+
+#endif /* BABELTRACE_TRACE_IR_RESOLVE_FIELD_PATH_INTERNAL */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_RESOLVE_INTERNAL_H
+#define BABELTRACE_TRACE_IR_RESOLVE_INTERNAL_H
+
+/*
+ * Babeltrace - Trace IR: Type resolving internal
+ *
+ * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Authors: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/values.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <glib.h>
+
+enum bt_resolve_flag {
+ BT_RESOLVE_FLAG_PACKET_HEADER = 0x01,
+ BT_RESOLVE_FLAG_PACKET_CONTEXT = 0x02,
+ BT_RESOLVE_FLAG_EVENT_HEADER = 0x04,
+ BT_RESOLVE_FLAG_STREAM_EVENT_CTX = 0x08,
+ BT_RESOLVE_FLAG_EVENT_CONTEXT = 0x10,
+ BT_RESOLVE_FLAG_EVENT_PAYLOAD = 0x20,
+};
+
+/*
+ * Resolves Trace IR field types: recursively locates the tag and length
+ * field types of resp. variant and sequence field types.
+ *
+ * All `*_type` parameters may be resolved, and may as well serve as
+ * resolving targets.
+ *
+ * Resolving is performed based on the flags in `flags`.
+ *
+ * It is expected that, amongst all the provided types, no common
+ * references to sequence variant field types exist. In other words,
+ * this function does not copy field types.
+ *
+ * All parameters are owned by the caller.
+ */
+BT_HIDDEN
+int bt_resolve_types(struct bt_value *environment,
+ struct bt_field_type *packet_header_type,
+ struct bt_field_type *packet_context_type,
+ struct bt_field_type *event_header_type,
+ struct bt_field_type *stream_event_ctx_type,
+ struct bt_field_type *event_context_type,
+ struct bt_field_type *event_payload_type,
+ enum bt_resolve_flag flags);
+
+#endif /* BABELTRACE_TRACE_IR_RESOLVE_INTERNAL_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_STREAM_CLASS_INTERNAL_H
+#define BABELTRACE_TRACE_IR_STREAM_CLASS_INTERNAL_H
+
+/*
+ * BabelTrace - Trace IR: Stream class internal
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/common-internal.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/utils-internal.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/object-pool-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <glib.h>
+#include <inttypes.h>
+
+struct bt_stream_class {
+ struct bt_object base;
+
+ struct {
+ GString *str;
+
+ /* NULL or `str->str` above */
+ const char *value;
+ } name;
+
+ uint64_t id;
+ bool assigns_automatic_event_class_id;
+ bool assigns_automatic_stream_id;
+ bool packets_have_discarded_event_counter_snapshot;
+ bool packets_have_packet_counter_snapshot;
+ bool packets_have_default_beginning_cv;
+ bool packets_have_default_end_cv;
+ struct bt_field_type *packet_context_ft;
+ struct bt_field_type *event_header_ft;
+ struct bt_field_type *event_common_context_ft;
+ struct bt_clock_class *default_clock_class;
+
+ /* Array of `struct bt_event_class *` */
+ GPtrArray *event_classes;
+
+ /* Pool of `struct bt_field_wrapper *` */
+ struct bt_object_pool event_header_field_pool;
+
+ /* Pool of `struct bt_field_wrapper *` */
+ struct bt_object_pool packet_context_field_pool;
+
+ bool frozen;
+};
+
+BT_HIDDEN
+void _bt_stream_class_freeze(struct bt_stream_class *stream_class);
+
+#ifdef BT_DEV_MODE
+# define bt_stream_class_freeze _bt_stream_class_freeze
+#else
+# define bt_stream_class_freeze(_sc)
+#endif
+
+static inline
+struct bt_trace *bt_stream_class_borrow_trace_inline(
+ struct bt_stream_class *stream_class)
+{
+ BT_ASSERT(stream_class);
+ return (void *) bt_object_borrow_parent(&stream_class->base);
+}
+
+#endif /* BABELTRACE_TRACE_IR_STREAM_CLASS_INTERNAL_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_STREAM_CLASS_H
+#define BABELTRACE_TRACE_IR_STREAM_CLASS_H
+
+/*
+ * BabelTrace - Trace IR: Stream Class
+ *
+ * Copyright 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <stdint.h>
+
+/* For bt_bool */
+#include <babeltrace/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_trace;
+struct bt_stream_class;
+struct bt_event_class;
+struct bt_clock_class;
+struct bt_event_header_field;
+struct bt_packet_context_field;
+
+extern struct bt_stream_class *bt_stream_class_create(struct bt_trace *trace);
+
+extern struct bt_stream_class *bt_stream_class_create_with_id(
+ struct bt_trace *trace, uint64_t id);
+
+extern struct bt_trace *bt_stream_class_borrow_trace(
+ struct bt_stream_class *stream_class);
+
+extern const char *bt_stream_class_get_name(
+ struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_name(struct bt_stream_class *stream_class,
+ const char *name);
+
+extern bt_bool bt_stream_class_assigns_automatic_event_class_id(
+ struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_assigns_automatic_event_class_id(
+ struct bt_stream_class *stream_class, bt_bool value);
+
+extern bt_bool bt_stream_class_assigns_automatic_stream_id(
+ struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_assigns_automatic_stream_id(
+ struct bt_stream_class *stream_class, bt_bool value);
+
+extern uint64_t bt_stream_class_get_id(struct bt_stream_class *stream_class);
+
+extern struct bt_field_type *bt_stream_class_borrow_packet_context_field_type(
+ struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_packet_context_field_type(
+ struct bt_stream_class *stream_class,
+ struct bt_field_type *field_type);
+
+extern struct bt_field_type *
+bt_stream_class_borrow_event_header_field_type(
+ struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_event_header_field_type(
+ struct bt_stream_class *stream_class,
+ struct bt_field_type *field_type);
+
+extern struct bt_field_type *
+bt_stream_class_borrow_event_common_context_field_type(
+ struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_event_common_context_field_type(
+ struct bt_stream_class *stream_class,
+ struct bt_field_type *field_type);
+
+extern uint64_t bt_stream_class_get_event_class_count(
+ struct bt_stream_class *stream_class);
+
+extern struct bt_event_class *bt_stream_class_borrow_event_class_by_index(
+ struct bt_stream_class *stream_class, uint64_t index);
+
+extern struct bt_event_class *bt_stream_class_borrow_event_class_by_id(
+ struct bt_stream_class *stream_class, uint64_t id);
+
+extern int bt_stream_class_set_default_clock_class(
+ struct bt_stream_class *stream_class,
+ struct bt_clock_class *clock_class);
+
+extern struct bt_clock_class *bt_stream_class_borrow_default_clock_class(
+ struct bt_stream_class *stream_class);
+
+extern bt_bool bt_stream_class_default_clock_is_always_known(
+ struct bt_stream_class *stream_class);
+
+extern bt_bool bt_stream_class_packets_have_discarded_event_counter_snapshot(
+ struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_packets_have_discarded_event_counter_snapshot(
+ struct bt_stream_class *stream_class, bt_bool value);
+
+extern bt_bool bt_stream_class_packets_have_packet_counter_snapshot(
+ struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_packets_have_packet_counter_snapshot(
+ struct bt_stream_class *stream_class, bt_bool value);
+
+extern bt_bool bt_stream_class_packets_have_default_beginning_clock_value(
+ struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_packets_have_default_beginning_clock_value(
+ struct bt_stream_class *stream_class, bt_bool value);
+
+extern bt_bool bt_stream_class_packets_have_default_end_clock_value(
+ struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_packets_have_default_end_clock_value(
+ struct bt_stream_class *stream_class, bt_bool value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_STREAM_CLASS_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_STREAM_INTERNAL_H
+#define BABELTRACE_TRACE_IR_STREAM_INTERNAL_H
+
+/*
+ * BabelTrace - CTF Writer: Stream internal
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/utils-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/object-pool-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <glib.h>
+
+struct bt_stream_class;
+struct bt_stream;
+
+struct bt_stream {
+ struct bt_object base;
+
+ /* Weak: parent is this class's trace */
+ struct bt_stream_class *class;
+
+ struct {
+ GString *str;
+
+ /* NULL or `str->str` above */
+ const char *value;
+ } name;
+
+ uint64_t id;
+
+ /* Pool of `struct bt_packet *` */
+ struct bt_object_pool packet_pool;
+
+ bool frozen;
+};
+
+BT_HIDDEN
+void _bt_stream_freeze(struct bt_stream *stream);
+
+#ifdef BT_DEV_MODE
+# define bt_stream_freeze _bt_stream_freeze
+#else
+# define bt_stream_freeze(_stream)
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_STREAM_INTERNAL_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_STREAM_H
+#define BABELTRACE_TRACE_IR_STREAM_H
+
+/*
+ * BabelTrace - Trace IR: Stream
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+/* For enum bt_property_availability */
+#include <babeltrace/property.h>
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_stream;
+struct bt_stream_class;
+
+extern struct bt_stream *bt_stream_create(struct bt_stream_class *stream_class);
+
+extern struct bt_stream *bt_stream_create_with_id(
+ struct bt_stream_class *stream_class, uint64_t id);
+
+extern struct bt_stream_class *bt_stream_borrow_class(struct bt_stream *stream);
+
+extern const char *bt_stream_get_name(struct bt_stream *stream);
+
+extern int bt_stream_set_name(struct bt_stream *stream, const char *name);
+
+extern uint64_t bt_stream_get_id(struct bt_stream *stream);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_STREAM_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_TRACE_INTERNAL_H
+#define BABELTRACE_TRACE_IR_TRACE_INTERNAL_H
+
+/*
+ * BabelTrace - Trace IR: Trace internal
+ *
+ * Copyright 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/trace.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/trace-ir/attributes-internal.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/object-pool-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/values.h>
+#include <babeltrace/types.h>
+#include <glib.h>
+#include <sys/types.h>
+#include <babeltrace/compat/uuid-internal.h>
+
+struct bt_trace {
+ struct bt_object base;
+
+ struct {
+ GString *str;
+
+ /* NULL or `str->str` above */
+ const char *value;
+ } name;
+
+ struct {
+ uint8_t uuid[BABELTRACE_UUID_LEN];
+
+ /* NULL or `uuid` above */
+ bt_uuid value;
+ } uuid;
+
+ struct bt_value *environment;
+
+ /* Array of `struct bt_stream_class *` */
+ GPtrArray *stream_classes;
+
+ /* Array of `struct bt_stream *` */
+ GPtrArray *streams;
+
+ /*
+ * Stream class (weak) to number of instantiated streams, used
+ * to automatically assign stream IDs per stream class.
+ */
+ GHashTable *stream_classes_stream_count;
+
+ struct bt_field_type *packet_header_ft;
+ bool assigns_automatic_stream_class_id;
+
+ GArray *is_static_listeners;
+ bool is_static;
+ bool in_remove_listener;
+
+ /* Pool of `struct bt_field_wrapper *` */
+ struct bt_object_pool packet_header_field_pool;
+
+ bool frozen;
+};
+
+BT_HIDDEN
+void _bt_trace_freeze(struct bt_trace *trace);
+
+#ifdef BT_DEV_MODE
+# define bt_trace_freeze _bt_trace_freeze
+#else
+# define bt_trace_freeze(_trace)
+#endif
+
+BT_HIDDEN
+void bt_trace_add_stream(struct bt_trace *trace, struct bt_stream *stream);
+
+BT_HIDDEN
+uint64_t bt_trace_get_automatic_stream_id(struct bt_trace *trace,
+ struct bt_stream_class *stream_class);
+
+#endif /* BABELTRACE_TRACE_IR_TRACE_INTERNAL_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_TRACE_H
+#define BABELTRACE_TRACE_IR_TRACE_H
+
+/*
+ * BabelTrace - Trace IR: Trace
+ *
+ * Copyright 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+/* For bt_bool, bt_uuid */
+#include <babeltrace/types.h>
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_trace;
+struct bt_stream;
+struct bt_stream_class;
+struct bt_field_type;
+struct bt_value;
+struct bt_packet_header_field;
+
+typedef void (* bt_trace_is_static_listener)(
+ struct bt_trace *trace, void *data);
+
+typedef void (* bt_trace_listener_removed)(
+ struct bt_trace *trace, void *data);
+
+extern struct bt_trace *bt_trace_create(void);
+
+extern bt_bool bt_trace_assigns_automatic_stream_class_id(
+ struct bt_trace *trace);
+
+extern int bt_trace_set_assigns_automatic_stream_class_id(
+ struct bt_trace *trace, bt_bool value);
+
+extern const char *bt_trace_get_name(struct bt_trace *trace);
+
+extern int bt_trace_set_name(struct bt_trace *trace, const char *name);
+
+extern bt_uuid bt_trace_get_uuid(struct bt_trace *trace);
+
+extern int bt_trace_set_uuid(struct bt_trace *trace, bt_uuid uuid);
+
+extern uint64_t bt_trace_get_environment_entry_count(struct bt_trace *trace);
+
+extern void bt_trace_borrow_environment_entry_by_index(
+ struct bt_trace *trace, uint64_t index,
+ const char **name, struct bt_value **value);
+
+extern struct bt_value *bt_trace_borrow_environment_entry_value_by_name(
+ struct bt_trace *trace, const char *name);
+
+extern int bt_trace_set_environment_entry_integer(
+ struct bt_trace *trace, const char *name,
+ int64_t value);
+
+extern int bt_trace_set_environment_entry_string(
+ struct bt_trace *trace, const char *name,
+ const char *value);
+
+extern struct bt_field_type *bt_trace_borrow_packet_header_field_type(
+ struct bt_trace *trace);
+
+extern int bt_trace_set_packet_header_field_type(struct bt_trace *trace,
+ struct bt_field_type *packet_header_type);
+
+extern uint64_t bt_trace_get_stream_class_count(struct bt_trace *trace);
+
+extern struct bt_stream_class *bt_trace_borrow_stream_class_by_index(
+ struct bt_trace *trace, uint64_t index);
+
+extern struct bt_stream_class *bt_trace_borrow_stream_class_by_id(
+ struct bt_trace *trace, uint64_t id);
+
+extern uint64_t bt_trace_get_stream_count(struct bt_trace *trace);
+
+extern struct bt_stream *bt_trace_borrow_stream_by_index(
+ struct bt_trace *trace, uint64_t index);
+
+extern struct bt_stream *bt_trace_borrow_stream_by_id(
+ struct bt_trace *trace, uint64_t id);
+
+extern bt_bool bt_trace_is_static(struct bt_trace *trace);
+
+extern int bt_trace_make_static(struct bt_trace *trace);
+
+extern int bt_trace_add_is_static_listener(
+ struct bt_trace *trace,
+ bt_trace_is_static_listener listener,
+ bt_trace_listener_removed listener_removed, void *data,
+ uint64_t *listener_id);
+
+extern int bt_trace_remove_is_static_listener(
+ struct bt_trace *trace, uint64_t listener_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_TRACE_H */
--- /dev/null
+#ifndef BABELTRACE_TRACE_IR_UTILS_INTERNAL_H
+#define BABELTRACE_TRACE_IR_UTILS_INTERNAL_H
+
+/*
+ * Babeltrace - Internal Trace IR utilities
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <stdint.h>
+
+struct search_query {
+ gpointer value;
+ int found;
+};
+
+static inline
+uint64_t bt_util_ns_from_value(uint64_t frequency, uint64_t value_cycles)
+{
+ uint64_t ns;
+
+ if (frequency == UINT64_C(1000000000)) {
+ ns = value_cycles;
+ } else {
+ double dblres = ((1e9 * (double) value_cycles) / (double) frequency);
+
+ if (dblres >= (double) UINT64_MAX) {
+ /* Overflows uint64_t */
+ ns = UINT64_C(-1);
+ } else {
+ ns = (uint64_t) dblres;
+ }
+ }
+
+ return ns;
+}
+
+static inline
+int bt_util_ns_from_origin(struct bt_clock_class *clock_class, uint64_t value,
+ int64_t *ns_from_origin)
+{
+ int ret = 0;
+ uint64_t value_ns_unsigned;
+ int64_t value_ns_signed;
+
+ if (clock_class->base_offset.overflows) {
+ ret = -1;
+ goto end;
+ }
+
+ /* Initialize to clock class's base offset */
+ *ns_from_origin = clock_class->base_offset.value_ns;
+
+ /* Add given value in cycles */
+ value_ns_unsigned = bt_util_ns_from_value(clock_class->frequency, value);
+ if (value_ns_unsigned >= (uint64_t) INT64_MAX) {
+ /*
+ * FIXME: `value_ns_unsigned` could be greater than
+ * `INT64_MAX` in fact: in this case, we need to
+ * subtract `INT64_MAX` from `value_ns_unsigned`, make
+ * sure that the difference is less than `INT64_MAX`,
+ * and try to add them one after the other to
+ * `*ns_from_origin`.
+ */
+ ret = -1;
+ goto end;
+ }
+
+ value_ns_signed = (int64_t) value_ns_unsigned;
+ BT_ASSERT(value_ns_signed >= 0);
+
+ if (*ns_from_origin <= 0) {
+ goto add_value;
+ }
+
+ if (value_ns_signed > INT64_MAX - *ns_from_origin) {
+ ret = -1;
+ goto end;
+ }
+
+add_value:
+ *ns_from_origin += value_ns_signed;
+
+end:
+ return ret;
+}
+
+static inline
+bool bt_util_value_is_in_range_signed(uint64_t size, int64_t value)
+{
+ int64_t min_value = UINT64_C(-1) << (size - 1);
+ int64_t max_value = (UINT64_C(1) << (size - 1)) - 1;
+ return value >= min_value && value <= max_value;
+}
+
+static inline
+bool bt_util_value_is_in_range_unsigned(unsigned int size, uint64_t value)
+{
+ uint64_t max_value = (size == 64) ? UINT64_MAX :
+ (UINT64_C(1) << size) - 1;
+ return value <= max_value;
+}
+
+#endif /* BABELTRACE_TRACE_IR_UTILS_INTERNAL_H */
-SUBDIRS = ctf-ir ctf-writer prio_heap plugin graph .
+SUBDIRS = trace-ir ctf-writer prio_heap plugin graph .
lib_LTLIBRARIES = libbabeltrace.la libbabeltrace-ctf.la
prio_heap/libprio_heap.la \
graph/libgraph.la \
plugin/libplugin.la \
- ctf-ir/libctf-ir.la \
+ trace-ir/libtrace-ir.la \
ctf-writer/libctf-writer.la \
$(top_builddir)/logging/libbabeltrace-logging.la \
$(top_builddir)/common/libbabeltrace-common.la \
libbabeltrace_ctf_la_LIBADD = \
graph/libgraph.la \
- ctf-ir/libctf-ir.la \
+ trace-ir/libtrace-ir.la \
ctf-writer/libctf-writer.la \
$(top_builddir)/logging/libbabeltrace-logging.la \
$(top_builddir)/common/libbabeltrace-common.la \
+++ /dev/null
-noinst_LTLIBRARIES = libctf-ir.la
-
-libctf_ir_la_SOURCES = \
- attributes.c \
- clock-class.c \
- clock-value.c \
- event.c \
- event-class.c \
- event-header-field.c \
- field-wrapper.c \
- fields.c \
- field-types.c \
- field-path.c \
- packet.c \
- packet-context-field.c \
- packet-header-field.c \
- resolve-field-path.c \
- stream.c \
- stream-class.c \
- trace.c \
- utils.c
-
-libctf_ir_la_LIBADD = $(UUID_LIBS)
+++ /dev/null
-/*
- * attributes.c
- *
- * Babeltrace CTF IR - Attributes
- *
- * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
- * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "ATTRS"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/ref.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/values.h>
-#include <babeltrace/values-internal.h>
-#include <inttypes.h>
-#include <babeltrace/compat/string-internal.h>
-#include <babeltrace/assert-internal.h>
-
-#define BT_ATTR_NAME_INDEX 0
-#define BT_ATTR_VALUE_INDEX 1
-
-BT_HIDDEN
-struct bt_value *bt_attributes_create(void)
-{
- struct bt_value *attr_obj;
-
- /*
- * Attributes: array value object of array value objects, each one
- * containing two entries: a string value object (attributes
- * field name), and a value object (attributes field value).
- *
- * Example (JSON representation):
- *
- * [
- * ["hostname", "eeppdesk"],
- * ["sysname", "Linux"],
- * ["tracer_major", 2],
- * ["tracer_minor", 5]
- * ]
- */
- BT_LOGD_STR("Creating attributes object.");
- attr_obj = bt_value_array_create();
- if (!attr_obj) {
- BT_LOGE_STR("Failed to create array value.");
- } else {
- BT_LOGD("Created attributes object: addr=%p",
- attr_obj);
- }
-
- return attr_obj;
-}
-
-BT_HIDDEN
-void bt_attributes_destroy(struct bt_value *attr_obj)
-{
- BT_LOGD("Destroying attributes object: addr=%p", attr_obj);
- bt_put(attr_obj);
-}
-
-BT_HIDDEN
-int64_t bt_attributes_get_count(struct bt_value *attr_obj)
-{
- return bt_value_array_size(attr_obj);
-}
-
-BT_HIDDEN
-const char *bt_attributes_get_field_name(struct bt_value *attr_obj,
- uint64_t index)
-{
- int rc;
- const char *ret = NULL;
- struct bt_value *attr_field_obj = NULL;
- struct bt_value *attr_field_name_obj = NULL;
-
- if (!attr_obj) {
- BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
- goto end;
- }
-
- if (index >= bt_value_array_size(attr_obj)) {
- BT_LOGW("Invalid parameter: index is out of bounds: "
- "index=%" PRIu64 ", count=%" PRId64,
- index, bt_value_array_size(attr_obj));
- goto end;
- }
-
- attr_field_obj = bt_value_array_borrow(attr_obj, index);
- if (!attr_field_obj) {
- BT_LOGE("Cannot get attributes object's array value's element by index: "
- "value-addr=%p, index=%" PRIu64, attr_obj, index);
- goto end;
- }
-
- attr_field_name_obj = bt_value_array_borrow(attr_field_obj,
- BT_ATTR_NAME_INDEX);
- if (!attr_field_name_obj) {
- BT_LOGE("Cannot get attribute array value's element by index: "
- "value-addr=%p, index=%" PRIu64, attr_field_obj,
- (uint64_t) BT_ATTR_NAME_INDEX);
- goto end;
- }
-
- rc = bt_value_string_get(attr_field_name_obj, &ret);
- if (rc) {
- BT_LOGE("Cannot get raw value from string value: value-addr=%p",
- attr_field_name_obj);
- ret = NULL;
- }
-
-end:
- return ret;
-}
-
-BT_HIDDEN
-struct bt_value *bt_attributes_borrow_field_value(struct bt_value *attr_obj,
- uint64_t index)
-{
- struct bt_value *value_obj = NULL;
- struct bt_value *attr_field_obj = NULL;
-
- if (!attr_obj) {
- BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
- goto end;
- }
-
- if (index >= bt_value_array_size(attr_obj)) {
- BT_LOGW("Invalid parameter: index is out of bounds: "
- "index=%" PRIu64 ", count=%" PRId64,
- index, bt_value_array_size(attr_obj));
- goto end;
- }
-
- attr_field_obj = bt_value_array_borrow(attr_obj, index);
- if (!attr_field_obj) {
- BT_LOGE("Cannot get attributes object's array value's element by index: "
- "value-addr=%p, index=%" PRIu64, attr_obj, index);
- goto end;
- }
-
- value_obj = bt_value_array_borrow(attr_field_obj,
- BT_ATTR_VALUE_INDEX);
- if (!value_obj) {
- BT_LOGE("Cannot get attribute array value's element by index: "
- "value-addr=%p, index=%" PRIu64, attr_field_obj,
- (uint64_t) BT_ATTR_VALUE_INDEX);
- }
-
-end:
- return value_obj;
-}
-
-static
-struct bt_value *bt_attributes_borrow_field_by_name(
- struct bt_value *attr_obj, const char *name)
-{
- uint64_t i;
- int64_t attr_size;
- struct bt_value *value_obj = NULL;
- struct bt_value *attr_field_name_obj = NULL;
-
- attr_size = bt_value_array_size(attr_obj);
- if (attr_size < 0) {
- BT_LOGE("Cannot get array value's size: value-addr=%p",
- attr_obj);
- goto error;
- }
-
- for (i = 0; i < attr_size; ++i) {
- int ret;
- const char *field_name;
-
- value_obj = bt_value_array_borrow(attr_obj, i);
- if (!value_obj) {
- BT_LOGE("Cannot get attributes object's array value's element by index: "
- "value-addr=%p, index=%" PRIu64, attr_obj, i);
- goto error;
- }
-
- attr_field_name_obj = bt_value_array_borrow(value_obj,
- BT_ATTR_NAME_INDEX);
- if (!attr_field_name_obj) {
- BT_LOGE("Cannot get attribute array value's element by index: "
- "value-addr=%p, index=%" PRIu64,
- value_obj, (int64_t) BT_ATTR_NAME_INDEX);
- goto error;
- }
-
- ret = bt_value_string_get(attr_field_name_obj, &field_name);
- if (ret) {
- BT_LOGE("Cannot get raw value from string value: value-addr=%p",
- attr_field_name_obj);
- goto error;
- }
-
- if (!strcmp(field_name, name)) {
- break;
- }
-
- value_obj = NULL;
- }
-
- return value_obj;
-
-error:
- value_obj = NULL;
- return value_obj;
-}
-
-BT_HIDDEN
-int bt_attributes_set_field_value(struct bt_value *attr_obj,
- const char *name, struct bt_value *value_obj)
-{
- int ret = 0;
- struct bt_value *attr_field_obj = NULL;
-
- if (!attr_obj || !name || !value_obj) {
- BT_LOGW("Invalid parameter: attributes object, name, or value object is NULL: "
- "attr-value-addr=%p, name-addr=%p, value-addr=%p",
- attr_obj, name, value_obj);
- ret = -1;
- goto end;
- }
-
- attr_field_obj = bt_attributes_borrow_field_by_name(attr_obj, name);
- if (attr_field_obj) {
- ret = bt_value_array_set(attr_field_obj,
- BT_ATTR_VALUE_INDEX, value_obj);
- attr_field_obj = NULL;
- goto end;
- }
-
- attr_field_obj = bt_value_array_create();
- if (!attr_field_obj) {
- BT_LOGE_STR("Failed to create empty array value.");
- ret = -1;
- goto end;
- }
-
- ret = bt_value_array_append_string(attr_field_obj, name);
- ret |= bt_value_array_append(attr_field_obj, value_obj);
- if (ret) {
- BT_LOGE("Cannot append elements to array value: addr=%p",
- attr_field_obj);
- goto end;
- }
-
- ret = bt_value_array_append(attr_obj, attr_field_obj);
- if (ret) {
- BT_LOGE("Cannot append element to array value: "
- "array-value-addr=%p, element-value-addr=%p",
- attr_obj, attr_field_obj);
- }
-
-end:
- bt_put(attr_field_obj);
- return ret;
-}
-
-BT_HIDDEN
-struct bt_value *bt_attributes_borrow_field_value_by_name(
- struct bt_value *attr_obj, const char *name)
-{
- struct bt_value *value_obj = NULL;
- struct bt_value *attr_field_obj = NULL;
-
- if (!attr_obj || !name) {
- BT_LOGW("Invalid parameter: attributes object or name is NULL: "
- "value-addr=%p, name-addr=%p", attr_obj, name);
- goto end;
- }
-
- attr_field_obj = bt_attributes_borrow_field_by_name(attr_obj, name);
- if (!attr_field_obj) {
- BT_LOGD("Cannot find attributes object's field by name: "
- "value-addr=%p, name=\"%s\"", attr_obj, name);
- goto end;
- }
-
- value_obj = bt_value_array_borrow(attr_field_obj,
- BT_ATTR_VALUE_INDEX);
- if (!value_obj) {
- BT_LOGE("Cannot get attribute array value's element by index: "
- "value-addr=%p, index=%" PRIu64, attr_field_obj,
- (uint64_t) BT_ATTR_VALUE_INDEX);
- }
-
-end:
- return value_obj;
-}
-
-BT_HIDDEN
-int bt_attributes_freeze(struct bt_value *attr_obj)
-{
- uint64_t i;
- int64_t count;
- int ret = 0;
-
- if (!attr_obj) {
- BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
- ret = -1;
- goto end;
- }
-
- BT_LOGD("Freezing attributes object: value-addr=%p", attr_obj);
- count = bt_value_array_size(attr_obj);
- BT_ASSERT(count >= 0);
-
- /*
- * We do not freeze the array value object itself here, since
- * internal stuff could need to modify/add attributes. Each
- * attribute is frozen one by one.
- */
- for (i = 0; i < count; ++i) {
- struct bt_value *obj = NULL;
-
- obj = bt_attributes_borrow_field_value(attr_obj, i);
- if (!obj) {
- BT_LOGE("Cannot get attributes object's field value by index: "
- "value-addr=%p, index=%" PRIu64,
- attr_obj, i);
- ret = -1;
- goto end;
- }
-
- bt_value_freeze(obj);
- }
-
-end:
- return ret;
-}
+++ /dev/null
-/*
- * clock-class.c
- *
- * Babeltrace CTF IR - Clock class
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "CLOCK-CLASS"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/compat/uuid-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/types.h>
-#include <babeltrace/compat/string-internal.h>
-#include <inttypes.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/assert-internal.h>
-
-#define BT_ASSERT_PRE_CLOCK_CLASS_HOT(_cc) \
- BT_ASSERT_PRE_HOT((_cc), "Clock class", ": %!+K", (_cc))
-
-static
-void destroy_clock_class(struct bt_object *obj)
-{
- struct bt_clock_class *clock_class = (void *) obj;
-
- BT_LIB_LOGD("Destroying clock class: %!+K", clock_class);
-
- if (clock_class->name.str) {
- g_string_free(clock_class->name.str, TRUE);
- }
-
- if (clock_class->description.str) {
- g_string_free(clock_class->description.str, TRUE);
- }
-
- bt_object_pool_finalize(&clock_class->cv_pool);
- g_free(clock_class);
-}
-
-static
-void free_clock_value(struct bt_clock_value *clock_value,
- struct bt_clock_class *clock_class)
-{
- bt_clock_value_destroy(clock_value);
-}
-
-static inline
-void set_base_offset(struct bt_clock_class *clock_class)
-{
- uint64_t offset_cycles_ns;
-
- /* Initialize nanosecond timestamp to clock's offset in seconds */
- if (clock_class->offset_seconds <= (INT64_MIN / INT64_C(1000000000) - 1) ||
- clock_class->offset_seconds >= (INT64_MAX / INT64_C(1000000000)) - 1) {
- /*
- * Overflow: offset in seconds converted to nanoseconds
- * is outside the int64_t range. We also subtract 1 here
- * to leave "space" for the offset in cycles converted
- * to nanoseconds (which is always less than 1 second by
- * contract).
- */
- clock_class->base_offset.overflows = true;
- goto end;
- }
-
- /* Offset (seconds) to nanoseconds */
- clock_class->base_offset.value_ns = clock_class->offset_seconds *
- INT64_C(1000000000);
-
- /* Add offset in cycles */
- BT_ASSERT(clock_class->offset_cycles < clock_class->frequency);
- offset_cycles_ns = bt_util_ns_from_value(clock_class->frequency,
- clock_class->offset_cycles);
- BT_ASSERT(offset_cycles_ns < 1000000000);
- clock_class->base_offset.value_ns += (int64_t) offset_cycles_ns;
- clock_class->base_offset.overflows = false;
-
-end:
- return;
-}
-
-struct bt_clock_class *bt_clock_class_create(void)
-{
- int ret;
- struct bt_clock_class *clock_class = NULL;
-
- BT_LOGD_STR("Creating default clock class object");
-
- clock_class = g_new0(struct bt_clock_class, 1);
- if (!clock_class) {
- BT_LOGE_STR("Failed to allocate one clock class.");
- goto error;
- }
-
- bt_object_init_shared(&clock_class->base, destroy_clock_class);
- clock_class->name.str = g_string_new(NULL);
- if (!clock_class->name.str) {
- BT_LOGE_STR("Failed to allocate a GString.");
- goto error;
- }
-
- clock_class->description.str = g_string_new(NULL);
- if (!clock_class->description.str) {
- BT_LOGE_STR("Failed to allocate a GString.");
- goto error;
- }
-
- clock_class->frequency = UINT64_C(1000000000);
- clock_class->is_absolute = BT_TRUE;
- set_base_offset(clock_class);
- ret = bt_object_pool_initialize(&clock_class->cv_pool,
- (bt_object_pool_new_object_func) bt_clock_value_new,
- (bt_object_pool_destroy_object_func)
- free_clock_value,
- clock_class);
- if (ret) {
- BT_LOGE("Failed to initialize clock value pool: ret=%d",
- ret);
- goto error;
- }
-
- BT_LIB_LOGD("Created clock class object: %!+K", clock_class);
- goto end;
-
-error:
- BT_PUT(clock_class);
-
-end:
- return clock_class;
-}
-
-const char *bt_clock_class_get_name(
- struct bt_clock_class *clock_class)
-{
- BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
- return clock_class->name.value;
-}
-
-int bt_clock_class_set_name(struct bt_clock_class *clock_class,
- const char *name)
-{
- BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
- BT_ASSERT_PRE_NON_NULL(name, "Name");
- BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
- g_string_assign(clock_class->name.str, name);
- clock_class->name.value = clock_class->name.str->str;
- BT_LIB_LOGV("Set clock class's name: %!+K", clock_class);
- return 0;
-}
-
-const char *bt_clock_class_get_description(struct bt_clock_class *clock_class)
-{
- BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
- return clock_class->description.value;
-}
-
-int bt_clock_class_set_description(struct bt_clock_class *clock_class,
- const char *descr)
-{
- BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
- BT_ASSERT_PRE_NON_NULL(descr, "Description");
- BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
- g_string_assign(clock_class->description.str, descr);
- clock_class->description.value = clock_class->description.str->str;
- BT_LIB_LOGV("Set clock class's description: %!+K",
- clock_class);
- return 0;
-}
-
-uint64_t bt_clock_class_get_frequency(struct bt_clock_class *clock_class)
-{
- BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
- return clock_class->frequency;
-}
-
-int bt_clock_class_set_frequency(struct bt_clock_class *clock_class,
- uint64_t frequency)
-{
- BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
- BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
- BT_ASSERT_PRE(frequency != UINT64_C(-1) && frequency != 0,
- "Invalid frequency: %![cc-]+K, new-freq=%" PRIu64,
- clock_class, frequency);
- BT_ASSERT_PRE(clock_class->offset_cycles < frequency,
- "Offset (cycles) is greater than clock class's frequency: "
- "%![cc-]+K, new-freq=%" PRIu64, clock_class, frequency);
- clock_class->frequency = frequency;
- set_base_offset(clock_class);
- BT_LIB_LOGV("Set clock class's frequency: %!+K", clock_class);
- return 0;
-}
-
-uint64_t bt_clock_class_get_precision(struct bt_clock_class *clock_class)
-{
- BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
- return clock_class->precision;
-}
-
-int bt_clock_class_set_precision(struct bt_clock_class *clock_class,
- uint64_t precision)
-{
- BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
- BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
- BT_ASSERT_PRE(precision != UINT64_C(-1),
- "Invalid precision: %![cc-]+K, new-precision=%" PRIu64,
- clock_class, precision);
- clock_class->precision = precision;
- BT_LIB_LOGV("Set clock class's precision: %!+K", clock_class);
- return 0;
-}
-
-void bt_clock_class_get_offset(struct bt_clock_class *clock_class,
- int64_t *seconds, uint64_t *cycles)
-{
- BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
- BT_ASSERT_PRE_NON_NULL(seconds, "Seconds (output)");
- BT_ASSERT_PRE_NON_NULL(cycles, "Cycles (output)");
- *seconds = clock_class->offset_seconds;
- *cycles = clock_class->offset_cycles;
-}
-
-int bt_clock_class_set_offset(struct bt_clock_class *clock_class,
- int64_t seconds, uint64_t cycles)
-{
- BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
- BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
- BT_ASSERT_PRE(cycles < clock_class->frequency,
- "Offset (cycles) is greater than clock class's frequency: "
- "%![cc-]+K, new-offset-cycles=%" PRIu64, clock_class, cycles);
- clock_class->offset_seconds = seconds;
- clock_class->offset_cycles = cycles;
- set_base_offset(clock_class);
- BT_LIB_LOGV("Set clock class's offset: %!+K", clock_class);
- return 0;
-}
-
-bt_bool bt_clock_class_is_absolute(struct bt_clock_class *clock_class)
-{
- BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
- return (bool) clock_class->is_absolute;
-}
-
-int bt_clock_class_set_is_absolute(struct bt_clock_class *clock_class,
- bt_bool is_absolute)
-{
- BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
- BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
- clock_class->is_absolute = (bool) is_absolute;
- BT_LIB_LOGV("Set clock class's absolute property: %!+K",
- clock_class);
- return 0;
-}
-
-bt_uuid bt_clock_class_get_uuid(struct bt_clock_class *clock_class)
-{
- BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
- return clock_class->uuid.value;
-}
-
-int bt_clock_class_set_uuid(struct bt_clock_class *clock_class,
- bt_uuid uuid)
-{
- BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
- BT_ASSERT_PRE_NON_NULL(uuid, "UUID");
- BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
- memcpy(clock_class->uuid.uuid, uuid, BABELTRACE_UUID_LEN);
- clock_class->uuid.value = clock_class->uuid.uuid;
- BT_LIB_LOGV("Set clock class's UUID: %!+K", clock_class);
- return 0;
-}
-
-BT_HIDDEN
-void _bt_clock_class_freeze(struct bt_clock_class *clock_class)
-{
- BT_ASSERT(clock_class);
-
- if (clock_class->frozen) {
- return;
- }
-
- BT_LIB_LOGD("Freezing clock class: %!+K", clock_class);
- clock_class->frozen = 1;
-}
-
-int bt_clock_class_cycles_to_ns_from_origin(struct bt_clock_class *clock_class,
- uint64_t cycles, int64_t *ns)
-{
- int ret;
-
- BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
- BT_ASSERT_PRE_NON_NULL(ns, "Nanoseconds (output)");
- ret = bt_util_ns_from_origin(clock_class, cycles, ns);
- if (ret) {
- BT_LIB_LOGW("Cannot convert cycles to nanoseconds "
- "from origin for given clock class: "
- "value overflows the signed 64-bit integer range: "
- "%![cc-]+K, cycles=%" PRIu64,
- clock_class, cycles);
- }
-
- return ret;
-}
+++ /dev/null
-/*
- * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "CLOCK-VALUE"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/compat/uuid-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/types.h>
-#include <babeltrace/compat/string-internal.h>
-#include <inttypes.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/assert-internal.h>
-
-BT_HIDDEN
-void bt_clock_value_destroy(struct bt_clock_value *clock_value)
-{
- BT_LIB_LOGD("Destroying clock value: %!+k", clock_value);
- bt_put(clock_value->clock_class);
- g_free(clock_value);
-}
-
-BT_HIDDEN
-struct bt_clock_value *bt_clock_value_new(struct bt_clock_class *clock_class)
-{
- struct bt_clock_value *ret = NULL;
-
- BT_ASSERT(clock_class);
- BT_LIB_LOGD("Creating clock value object: %![cc-]+K=",
- clock_class);
- ret = g_new0(struct bt_clock_value, 1);
- if (!ret) {
- BT_LOGE_STR("Failed to allocate one clock value.");
- goto end;
- }
-
- bt_object_init_unique(&ret->base);
- ret->clock_class = bt_get(clock_class);
- bt_clock_class_freeze(clock_class);
- BT_LIB_LOGD("Created clock value object: %!+k", ret);
-
-end:
- return ret;
-}
-
-BT_HIDDEN
-struct bt_clock_value *bt_clock_value_create(struct bt_clock_class *clock_class)
-{
- struct bt_clock_value *clock_value = NULL;
-
- BT_ASSERT(clock_class);
- clock_value = bt_object_pool_create_object(&clock_class->cv_pool);
- if (!clock_value) {
- BT_LIB_LOGE("Cannot allocate one clock value from clock class's clock value pool: "
- "%![cc-]+K", clock_class);
- goto error;
- }
-
- if (likely(!clock_value->clock_class)) {
- clock_value->clock_class = bt_get(clock_class);
- }
-
- goto end;
-
-error:
- if (clock_value) {
- bt_clock_value_recycle(clock_value);
- clock_value = NULL;
- }
-
-end:
- return clock_value;
-}
-
-BT_HIDDEN
-void bt_clock_value_recycle(struct bt_clock_value *clock_value)
-{
- struct bt_clock_class *clock_class;
-
- BT_ASSERT(clock_value);
- BT_LIB_LOGD("Recycling clock value: %!+k", clock_value);
-
- /*
- * Those are the important ordered steps:
- *
- * 1. Reset the clock value object, but do NOT put its clock
- * class's reference. This clock class contains the pool to
- * which we're about to recycle this clock value object, so
- * we must guarantee its existence thanks to this existing
- * reference.
- *
- * 2. Move the clock class reference to our `clock_class`
- * variable so that we can set the clock value's clock class
- * member to NULL before recycling it. We CANNOT do this
- * after we put the clock class reference because this
- * bt_put() could destroy the clock class, also destroying
- * its clock value pool, thus also destroying our clock value
- * object (this would result in an invalid write access).
- *
- * 3. Recycle the clock value object.
- *
- * 4. Put our clock class reference.
- */
- bt_clock_value_reset(clock_value);
- clock_class = clock_value->clock_class;
- BT_ASSERT(clock_class);
- clock_value->clock_class = NULL;
- bt_object_pool_recycle_object(&clock_class->cv_pool, clock_value);
- bt_put(clock_class);
-}
-
-uint64_t bt_clock_value_get_value(struct bt_clock_value *clock_value)
-{
- BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value");
- BT_ASSERT_PRE(clock_value->is_set,
- "Clock value is not set: %!+k", clock_value);
- return clock_value->value_cycles;
-}
-
-int bt_clock_value_get_ns_from_origin(struct bt_clock_value *clock_value,
- int64_t *ret_value_ns)
-{
- int ret = 0;
- BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value");
- BT_ASSERT_PRE_NON_NULL(ret_value_ns, "Value (ns) (output)");
- BT_ASSERT_PRE(clock_value->is_set,
- "Clock value is not set: %!+k", clock_value);
-
- if (clock_value->ns_from_origin_overflows) {
- BT_LIB_LOGD("Clock value, once converted to nanoseconds from origin, "
- "overflows the signed 64-bit integer range: "
- "%![cv-]+k", clock_value);
- ret = -1;
- goto end;
- }
-
- *ret_value_ns = clock_value->ns_from_origin;
-
-end:
- return ret;
-}
-
-struct bt_clock_class *bt_clock_value_borrow_clock_class(
- struct bt_clock_value *clock_value)
-{
- BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value");
- return clock_value->clock_class;
-}
+++ /dev/null
-/*
- * event-class.c
- *
- * Babeltrace CTF IR - Event class
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "EVENT-CLASS"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/ctf-ir/event-internal.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/ctf-ir/resolve-field-path-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/attributes-internal.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/endian-internal.h>
-#include <babeltrace/types.h>
-#include <babeltrace/values-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <inttypes.h>
-#include <stdlib.h>
-
-#define BT_ASSERT_PRE_EVENT_CLASS_HOT(_ec) \
- BT_ASSERT_PRE_HOT((_ec), "Event class", ": %!+E", (_ec))
-
-static
-void destroy_event_class(struct bt_object *obj)
-{
- struct bt_event_class *event_class = (void *) obj;
-
- BT_LIB_LOGD("Destroying event class: %!+E", event_class);
-
- if (event_class->name.str) {
- g_string_free(event_class->name.str, TRUE);
- }
-
- if (event_class->emf_uri.str) {
- g_string_free(event_class->emf_uri.str, TRUE);
- }
-
- BT_LOGD_STR("Putting context field type.");
- bt_put(event_class->specific_context_ft);
- BT_LOGD_STR("Putting payload field type.");
- bt_put(event_class->payload_ft);
- bt_object_pool_finalize(&event_class->event_pool);
- g_free(obj);
-}
-
-static
-void free_event(struct bt_event *event,
- struct bt_event_class *event_class)
-{
- bt_event_destroy(event);
-}
-
-BT_ASSERT_PRE_FUNC
-static
-bool event_class_id_is_unique(struct bt_stream_class *stream_class, uint64_t id)
-{
- uint64_t i;
- bool is_unique = true;
-
- for (i = 0; i < stream_class->event_classes->len; i++) {
- struct bt_event_class *ec =
- stream_class->event_classes->pdata[i];
-
- if (ec->id == id) {
- is_unique = false;
- goto end;
- }
- }
-
-end:
- return is_unique;
-}
-
-static
-struct bt_event_class *create_event_class_with_id(
- struct bt_stream_class *stream_class, uint64_t id)
-{
- int ret;
- struct bt_event_class *event_class;
-
- BT_ASSERT(stream_class);
- BT_ASSERT_PRE(event_class_id_is_unique(stream_class, id),
- "Duplicate event class ID: %![sc-]+S, id=%" PRIu64,
- stream_class, id);
- BT_LIB_LOGD("Creating event class object: %![sc-]+S, id=%" PRIu64,
- stream_class, id);
- event_class = g_new0(struct bt_event_class, 1);
- if (!event_class) {
- BT_LOGE_STR("Failed to allocate one event class.");
- goto error;
- }
-
- bt_object_init_shared_with_parent(&event_class->base,
- destroy_event_class);
- event_class->id = id;
- bt_property_uint_init(&event_class->log_level,
- BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE, 0);
- event_class->name.str = g_string_new(NULL);
- if (!event_class->name.str) {
- BT_LOGE_STR("Failed to allocate a GString.");
- ret = -1;
- goto end;
- }
-
- event_class->emf_uri.str = g_string_new(NULL);
- if (!event_class->emf_uri.str) {
- BT_LOGE_STR("Failed to allocate a GString.");
- ret = -1;
- goto end;
- }
-
- ret = bt_object_pool_initialize(&event_class->event_pool,
- (bt_object_pool_new_object_func) bt_event_new,
- (bt_object_pool_destroy_object_func) free_event,
- event_class);
- if (ret) {
- BT_LOGE("Failed to initialize event pool: ret=%d",
- ret);
- goto error;
- }
-
- bt_object_set_parent(&event_class->base, &stream_class->base);
- g_ptr_array_add(stream_class->event_classes, event_class);
- bt_stream_class_freeze(stream_class);
- BT_LIB_LOGD("Created event class object: %!+E", event_class);
- goto end;
-
-error:
- BT_PUT(event_class);
-
-end:
- return event_class;
-}
-
-struct bt_event_class *bt_event_class_create(
- struct bt_stream_class *stream_class)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- BT_ASSERT_PRE(stream_class->assigns_automatic_event_class_id,
- "Stream class does not automatically assigns event class IDs: "
- "%![sc-]+S", stream_class);
- return create_event_class_with_id(stream_class,
- (uint64_t) stream_class->event_classes->len);
-}
-
-struct bt_event_class *bt_event_class_create_with_id(
- struct bt_stream_class *stream_class, uint64_t id)
-{
- BT_ASSERT_PRE(!stream_class->assigns_automatic_event_class_id,
- "Stream class automatically assigns event class IDs: "
- "%![sc-]+S", stream_class);
- return create_event_class_with_id(stream_class, id);
-}
-
-const char *bt_event_class_get_name(struct bt_event_class *event_class)
-{
- BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
- return event_class->name.value;
-}
-
-int bt_event_class_set_name(struct bt_event_class *event_class,
- const char *name)
-{
- BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
- BT_ASSERT_PRE_NON_NULL(name, "Name");
- BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
- g_string_assign(event_class->name.str, name);
- event_class->name.value = event_class->name.str->str;
- BT_LIB_LOGV("Set event class's name: %!+E", event_class);
- return 0;
-}
-
-uint64_t bt_event_class_get_id(struct bt_event_class *event_class)
-{
- BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
- return event_class->id;
-}
-
-enum bt_property_availability bt_event_class_get_log_level(
- struct bt_event_class *event_class,
- enum bt_event_class_log_level *log_level)
-{
- BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
- BT_ASSERT_PRE_NON_NULL(log_level, "Log level (output)");
- *log_level = (enum bt_event_class_log_level)
- event_class->log_level.value;
- return event_class->log_level.base.avail;
-}
-
-int bt_event_class_set_log_level(struct bt_event_class *event_class,
- enum bt_event_class_log_level log_level)
-{
- BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
- BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
- bt_property_uint_set(&event_class->log_level,
- (uint64_t) log_level);
- BT_LIB_LOGV("Set event class's log level: %!+E", event_class);
- return 0;
-}
-
-const char *bt_event_class_get_emf_uri(struct bt_event_class *event_class)
-{
- BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
- return event_class->emf_uri.value;
-}
-
-int bt_event_class_set_emf_uri(struct bt_event_class *event_class,
- const char *emf_uri)
-{
- BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
- BT_ASSERT_PRE_NON_NULL(emf_uri, "EMF URI");
- BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
- g_string_assign(event_class->emf_uri.str, emf_uri);
- event_class->emf_uri.value = event_class->emf_uri.str->str;
- BT_LIB_LOGV("Set event class's EMF URI: %!+E", event_class);
- return 0;
-}
-
-struct bt_stream_class *bt_event_class_borrow_stream_class(
- struct bt_event_class *event_class)
-{
- BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
- return bt_event_class_borrow_stream_class_inline(event_class);
-}
-
-struct bt_field_type *bt_event_class_borrow_specific_context_field_type(
- struct bt_event_class *event_class)
-{
- BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
- return event_class->specific_context_ft;
-}
-
-int bt_event_class_set_specific_context_field_type(
- struct bt_event_class *event_class,
- struct bt_field_type *field_type)
-{
- int ret;
- struct bt_stream_class *stream_class;
- struct bt_trace *trace;
- struct bt_resolve_field_path_context resolve_ctx = {
- .packet_header = NULL,
- .packet_context = NULL,
- .event_header = NULL,
- .event_common_context = NULL,
- .event_specific_context = field_type,
- .event_payload = NULL,
- };
-
- BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
- BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
- BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
- BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
- BT_FIELD_TYPE_ID_STRUCTURE,
- "Specific context field type is not a structure field type: "
- "%!+F", field_type);
- stream_class = bt_event_class_borrow_stream_class_inline(
- event_class);
- trace = bt_stream_class_borrow_trace_inline(stream_class);
- resolve_ctx.packet_header = trace->packet_header_ft;
- resolve_ctx.packet_context = stream_class->packet_context_ft;
- resolve_ctx.event_header = stream_class->event_header_ft;
- resolve_ctx.event_common_context =
- stream_class->event_common_context_ft;
-
- ret = bt_resolve_field_paths(field_type, &resolve_ctx);
- if (ret) {
- goto end;
- }
-
- bt_field_type_make_part_of_trace(field_type);
- bt_put(event_class->specific_context_ft);
- event_class->specific_context_ft = bt_get(field_type);
- bt_field_type_freeze(field_type);
- BT_LIB_LOGV("Set event class's specific context field type: %!+E",
- event_class);
-
-end:
- return ret;
-}
-
-struct bt_field_type *bt_event_class_borrow_payload_field_type(
- struct bt_event_class *event_class)
-{
- BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
- return event_class->payload_ft;
-}
-
-int bt_event_class_set_payload_field_type(struct bt_event_class *event_class,
- struct bt_field_type *field_type)
-{
- int ret;
- struct bt_stream_class *stream_class;
- struct bt_trace *trace;
- struct bt_resolve_field_path_context resolve_ctx = {
- .packet_header = NULL,
- .packet_context = NULL,
- .event_header = NULL,
- .event_common_context = NULL,
- .event_specific_context = NULL,
- .event_payload = field_type,
- };
-
- BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
- BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
- BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
- BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
- BT_FIELD_TYPE_ID_STRUCTURE,
- "Payload field type is not a structure field type: %!+F",
- field_type);
- stream_class = bt_event_class_borrow_stream_class_inline(
- event_class);
- trace = bt_stream_class_borrow_trace_inline(stream_class);
- resolve_ctx.packet_header = trace->packet_header_ft;
- resolve_ctx.packet_context = stream_class->packet_context_ft;
- resolve_ctx.event_header = stream_class->event_header_ft;
- resolve_ctx.event_common_context =
- stream_class->event_common_context_ft;
- resolve_ctx.event_specific_context = event_class->specific_context_ft;
-
- ret = bt_resolve_field_paths(field_type, &resolve_ctx);
- if (ret) {
- goto end;
- }
-
- bt_field_type_make_part_of_trace(field_type);
- bt_put(event_class->payload_ft);
- event_class->payload_ft = bt_get(field_type);
- bt_field_type_freeze(field_type);
- BT_LIB_LOGV("Set event class's payload field type: %!+E", event_class);
-
-end:
- return ret;
-}
-
-BT_HIDDEN
-void _bt_event_class_freeze(struct bt_event_class *event_class)
-{
- /* The field types are already frozen */
- BT_ASSERT(event_class);
- BT_LIB_LOGD("Freezing event class: %!+E", event_class);
- event_class->frozen = true;
-}
+++ /dev/null
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "EVENT-HEADER-FIELD"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/event-header-field.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/field-wrapper-internal.h>
-#include <glib.h>
-
-struct bt_field *bt_event_header_field_borrow_field(
- struct bt_event_header_field *header_field)
-{
- struct bt_field_wrapper *field_wrapper = (void *) header_field;
-
- BT_ASSERT_PRE_NON_NULL(field_wrapper, "Event header field");
- return (void *) field_wrapper->field;
-}
-
-void bt_event_header_field_release(struct bt_event_header_field *header_field)
-{
- struct bt_field_wrapper *field_wrapper = (void *) header_field;
-
- BT_ASSERT_PRE_NON_NULL(field_wrapper, "Event header field");
-
- /*
- * Do not recycle because the pool could be destroyed at this
- * point. This function is only called when there's an error
- * anyway because the goal of an event header field wrapper is
- * to eventually move it to an event with bt_event_move_header()
- * after creating it.
- */
- bt_field_wrapper_destroy(field_wrapper);
-}
-
-struct bt_event_header_field *bt_event_header_field_create(
- struct bt_stream_class *stream_class)
-{
- struct bt_field_wrapper *field_wrapper;
-
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- BT_ASSERT_PRE(bt_stream_class_borrow_trace_inline(stream_class),
- "Stream class is not part of a trace: %!+S", stream_class);
- BT_ASSERT_PRE(stream_class->event_header_ft,
- "Stream class has no event header field type: %!+S",
- stream_class);
- field_wrapper = bt_field_wrapper_create(
- &stream_class->event_header_field_pool,
- (void *) stream_class->event_header_ft);
- if (!field_wrapper) {
- BT_LIB_LOGE("Cannot allocate one event header field from stream class: "
- "%![sc-]+S", stream_class);
- goto error;
- }
-
- BT_ASSERT(field_wrapper->field);
- bt_stream_class_freeze(stream_class);
- goto end;
-
-error:
- if (field_wrapper) {
- bt_field_wrapper_destroy(field_wrapper);
- field_wrapper = NULL;
- }
-
-end:
- return (void *) field_wrapper;
-}
+++ /dev/null
-/*
- * event.c
- *
- * Babeltrace CTF IR - Event
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "EVENT"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/clock-value.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-ir/event-internal.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
-#include <babeltrace/ctf-ir/packet.h>
-#include <babeltrace/ctf-ir/packet-internal.h>
-#include <babeltrace/ctf-ir/trace.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/ctf-ir/packet-internal.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/attributes-internal.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <inttypes.h>
-
-BT_HIDDEN
-void _bt_event_set_is_frozen(struct bt_event *event, bool is_frozen)
-{
- BT_ASSERT(event);
- BT_LIB_LOGD("Setting event's frozen state: %!+e, is-frozen=%d",
- event, is_frozen);
-
- if (event->header_field) {
- BT_LOGD_STR("Setting event's header field's frozen state.");
- bt_field_set_is_frozen(
- event->header_field->field, is_frozen);
- }
-
- if (event->common_context_field) {
- BT_LOGD_STR("Setting event's common context field's frozen state.");
- bt_field_set_is_frozen(
- event->common_context_field, is_frozen);
- }
-
- if (event->specific_context_field) {
- BT_LOGD_STR("Setting event's specific context field's frozen state.");
- bt_field_set_is_frozen(event->specific_context_field,
- is_frozen);
- }
-
- if (event->payload_field) {
- BT_LOGD_STR("Setting event's payload field's frozen state.");
- bt_field_set_is_frozen(event->payload_field,
- is_frozen);
- }
-
- event->frozen = is_frozen;
- BT_LOGD_STR("Setting event's packet's frozen state.");
- bt_packet_set_is_frozen(event->packet, is_frozen);
-}
-
-static
-void recycle_event_header_field(struct bt_field_wrapper *field_wrapper,
- struct bt_stream_class *stream_class)
-{
- BT_ASSERT(field_wrapper);
- BT_LIB_LOGD("Recycling event header field: "
- "addr=%p, %![sc-]+S, %![field-]+f", field_wrapper,
- stream_class, field_wrapper->field);
- bt_object_pool_recycle_object(
- &stream_class->event_header_field_pool,
- field_wrapper);
-}
-
-static inline
-struct bt_field_wrapper *create_event_header_field(
- struct bt_stream_class *stream_class)
-{
- struct bt_field_wrapper *field_wrapper = NULL;
-
- field_wrapper = bt_field_wrapper_create(
- &stream_class->event_header_field_pool,
- bt_stream_class_borrow_event_header_field_type(stream_class));
- if (!field_wrapper) {
- goto error;
- }
-
- goto end;
-
-error:
- if (field_wrapper) {
- recycle_event_header_field(field_wrapper, stream_class);
- field_wrapper = NULL;
- }
-
-end:
- return field_wrapper;
-}
-
-BT_HIDDEN
-struct bt_event *bt_event_new(struct bt_event_class *event_class)
-{
- struct bt_event *event = NULL;
- struct bt_stream_class *stream_class;
- struct bt_field_type *ft;
-
- BT_ASSERT(event_class);
- event = g_new0(struct bt_event, 1);
- if (!event) {
- BT_LOGE_STR("Failed to allocate one event.");
- goto error;
- }
-
- bt_object_init_unique(&event->base);
- stream_class = bt_event_class_borrow_stream_class(event_class);
- BT_ASSERT(stream_class);
-
- if (bt_stream_class_borrow_event_header_field_type(stream_class)) {
- event->header_field = create_event_header_field(stream_class);
- if (!event->header_field) {
- BT_LOGE_STR("Cannot create event header field.");
- goto error;
- }
- }
-
- ft = bt_stream_class_borrow_event_common_context_field_type(
- stream_class);
- if (ft) {
- event->common_context_field = bt_field_create(ft);
- if (!event->common_context_field) {
- /* bt_field_create() logs errors */
- goto error;
- }
- }
-
- ft = bt_event_class_borrow_specific_context_field_type(event_class);
- if (ft) {
- event->specific_context_field = bt_field_create(ft);
- if (!event->specific_context_field) {
- /* bt_field_create() logs errors */
- goto error;
- }
- }
-
- ft = bt_event_class_borrow_payload_field_type(event_class);
- if (ft) {
- event->payload_field = bt_field_create(ft);
- if (!event->payload_field) {
- /* bt_field_create() logs errors */
- goto error;
- }
- }
-
- if (stream_class->default_clock_class) {
- event->default_cv = bt_clock_value_create(
- stream_class->default_clock_class);
- if (!event->default_cv) {
- /* bt_clock_value_create() logs errors */
- goto error;
- }
- }
-
- goto end;
-
-error:
- if (event) {
- bt_event_destroy(event);
- event = NULL;
- }
-
-end:
- return event;
-}
-
-struct bt_event_class *bt_event_borrow_class(struct bt_event *event)
-{
- BT_ASSERT_PRE_NON_NULL(event, "Event");
- return event->class;
-}
-
-struct bt_stream *bt_event_borrow_stream(struct bt_event *event)
-{
- BT_ASSERT_PRE_NON_NULL(event, "Event");
- return event->packet ? event->packet->stream : NULL;
-}
-
-struct bt_field *bt_event_borrow_header_field(struct bt_event *event)
-{
- BT_ASSERT_PRE_NON_NULL(event, "Event");
- return event->header_field ? event->header_field->field : NULL;
-}
-
-struct bt_field *bt_event_borrow_common_context_field(struct bt_event *event)
-{
- BT_ASSERT_PRE_NON_NULL(event, "Event");
- return event->common_context_field;
-}
-
-struct bt_field *bt_event_borrow_specific_context_field(struct bt_event *event)
-{
- BT_ASSERT_PRE_NON_NULL(event, "Event");
- return event->specific_context_field;
-}
-
-struct bt_field *bt_event_borrow_payload_field(struct bt_event *event)
-{
- BT_ASSERT_PRE_NON_NULL(event, "Event");
- return event->payload_field;
-}
-
-static
-void release_event_header_field(struct bt_field_wrapper *field_wrapper,
- struct bt_event *event)
-{
- if (!event->class) {
- bt_field_wrapper_destroy(field_wrapper);
- } else {
- struct bt_stream_class *stream_class =
- bt_event_class_borrow_stream_class(event->class);
-
- BT_ASSERT(stream_class);
- recycle_event_header_field(field_wrapper, stream_class);
- }
-}
-
-BT_HIDDEN
-void bt_event_destroy(struct bt_event *event)
-{
- BT_ASSERT(event);
- BT_LIB_LOGD("Destroying event: %!+e", event);
-
- if (event->header_field) {
- BT_LOGD_STR("Releasing event's header field.");
- release_event_header_field(event->header_field, event);
- }
-
- if (event->common_context_field) {
- BT_LOGD_STR("Destroying event's stream event context field.");
- bt_field_destroy(event->common_context_field);
- }
-
- if (event->specific_context_field) {
- BT_LOGD_STR("Destroying event's context field.");
- bt_field_destroy(event->specific_context_field);
- }
-
- if (event->payload_field) {
- BT_LOGD_STR("Destroying event's payload field.");
- bt_field_destroy(event->payload_field);
- }
-
- BT_LOGD_STR("Putting event's class.");
- bt_put(event->class);
-
- if (event->default_cv) {
- bt_clock_value_recycle(event->default_cv);
- }
-
- BT_LOGD_STR("Putting event's packet.");
- bt_put(event->packet);
- g_free(event);
-}
-
-int bt_event_set_default_clock_value(struct bt_event *event,
- uint64_t value_cycles)
-{
- struct bt_stream_class *sc;
-
- BT_ASSERT_PRE_NON_NULL(event, "Event");
- BT_ASSERT_PRE_EVENT_HOT(event);
- sc = bt_event_class_borrow_stream_class_inline(event->class);
- BT_ASSERT(sc);
- BT_ASSERT_PRE(sc->default_clock_class,
- "Event's stream class has no default clock class: "
- "%![ev-]+e, %![sc-]+S", event, sc);
- BT_ASSERT(event->default_cv);
- bt_clock_value_set_value_inline(event->default_cv, value_cycles);
- BT_LIB_LOGV("Set event's default clock value: %![event-]+e, "
- "value=%" PRIu64, event, value_cycles);
- return 0;
-}
-
-enum bt_clock_value_status bt_event_borrow_default_clock_value(
- struct bt_event *event, struct bt_clock_value **clock_value)
-{
- BT_ASSERT_PRE_NON_NULL(event, "Event");
- BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value (output)");
- *clock_value = event->default_cv;
- return BT_CLOCK_VALUE_STATUS_KNOWN;
-}
-
-struct bt_packet *bt_event_borrow_packet(struct bt_event *event)
-{
- BT_ASSERT_PRE_NON_NULL(event, "Event");
- return event->packet;
-}
-
-int bt_event_move_header(struct bt_event *event,
- struct bt_event_header_field *header_field)
-{
- struct bt_stream_class *stream_class;
- struct bt_field_wrapper *field_wrapper = (void *) header_field;
-
- BT_ASSERT_PRE_NON_NULL(event, "Event");
- BT_ASSERT_PRE_NON_NULL(field_wrapper, "Header field");
- BT_ASSERT_PRE_EVENT_HOT(event);
- stream_class = bt_event_class_borrow_stream_class_inline(event->class);
- BT_ASSERT_PRE(stream_class->event_header_ft,
- "Stream class has no event header field type: %!+S",
- stream_class);
-
- /* Recycle current header field: always exists */
- BT_ASSERT(event->header_field);
- recycle_event_header_field(event->header_field, stream_class);
-
- /* Move new field */
- event->header_field = field_wrapper;
- return 0;
-}
+++ /dev/null
-/*
- * field-path.c
- *
- * Babeltrace CTF IR - Field path
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "FIELD-PATH"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/field-path-internal.h>
-#include <babeltrace/ctf-ir/field-path.h>
-#include <limits.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <babeltrace/assert-internal.h>
-#include <glib.h>
-
-static
-void destroy_field_path(struct bt_object *obj)
-{
- struct bt_field_path *field_path = (struct bt_field_path *) obj;
-
- BT_ASSERT(field_path);
- BT_LIB_LOGD("Destroying field path: %!+P", field_path);
- g_array_free(field_path->indexes, TRUE);
- g_free(field_path);
-}
-
-BT_HIDDEN
-struct bt_field_path *bt_field_path_create(void)
-{
- struct bt_field_path *field_path = NULL;
-
- BT_LOGD_STR("Creating empty field path object.");
-
- field_path = g_new0(struct bt_field_path, 1);
- if (!field_path) {
- BT_LOGE_STR("Failed to allocate one field path.");
- goto error;
- }
-
- bt_object_init_shared(&field_path->base, destroy_field_path);
- field_path->indexes = g_array_new(FALSE, FALSE, sizeof(uint64_t));
- if (!field_path->indexes) {
- BT_LOGE_STR("Failed to allocate a GArray.");
- goto error;
- }
-
- BT_LIB_LOGD("Created empty field path object: %!+P", field_path);
- goto end;
-
-error:
- BT_PUT(field_path);
-
-end:
- return field_path;
-}
-
-enum bt_scope bt_field_path_get_root_scope(struct bt_field_path *field_path)
-{
- BT_ASSERT_PRE_NON_NULL(field_path, "Field path");
- return field_path->root;
-}
-
-uint64_t bt_field_path_get_index_count(struct bt_field_path *field_path)
-{
- BT_ASSERT_PRE_NON_NULL(field_path, "Field path");
- return (uint64_t) field_path->indexes->len;
-}
-
-uint64_t bt_field_path_get_index_by_index(struct bt_field_path *field_path,
- uint64_t index)
-{
- BT_ASSERT_PRE_NON_NULL(field_path, "Field path");
- BT_ASSERT_PRE_VALID_INDEX(index, field_path->indexes->len);
- return bt_field_path_get_index_by_index_inline(field_path, index);
-}
+++ /dev/null
-/*
- * field-types.c
- *
- * Babeltrace CTF IR - Event Types
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "FIELD-TYPES"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/field-path-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/endian-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/compat/glib-internal.h>
-#include <float.h>
-#include <inttypes.h>
-#include <stdlib.h>
-
-enum bt_field_type_id bt_field_type_get_type_id(struct bt_field_type *ft)
-{
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- return ft->id;
-}
-
-static
-void init_field_type(struct bt_field_type *ft, enum bt_field_type_id id,
- bt_object_release_func release_func)
-{
- BT_ASSERT(ft);
- BT_ASSERT(bt_field_type_has_known_id(ft));
- BT_ASSERT(release_func);
- bt_object_init_shared(&ft->base, release_func);
- ft->id = id;
-}
-
-static
-void init_integer_field_type(struct bt_field_type_integer *ft, enum bt_field_type_id id,
- bt_object_release_func release_func)
-{
- init_field_type((void *) ft, id, release_func);
- ft->range = 64;
- ft->base = BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
-}
-
-static
-void destroy_integer_field_type(struct bt_object *obj)
-{
- BT_ASSERT(obj);
- BT_LIB_LOGD("Destroying integer field type object: %!+F", obj);
- g_free(obj);
-}
-
-static inline
-struct bt_field_type *create_integer_field_type(enum bt_field_type_id id)
-{
- struct bt_field_type_integer *int_ft = NULL;
-
- BT_LOGD("Creating default integer field type object: id=%s",
- bt_common_field_type_id_string(id));
- int_ft = g_new0(struct bt_field_type_integer, 1);
- if (!int_ft) {
- BT_LOGE_STR("Failed to allocate one integer field type.");
- goto error;
- }
-
- init_integer_field_type(int_ft, id, destroy_integer_field_type);
- BT_LIB_LOGD("Created integer field type object: %!+F", int_ft);
- goto end;
-
-error:
- BT_PUT(int_ft);
-
-end:
- return (void *) int_ft;
-}
-
-struct bt_field_type *bt_field_type_unsigned_integer_create(void)
-{
- return create_integer_field_type(BT_FIELD_TYPE_ID_UNSIGNED_INTEGER);
-}
-
-struct bt_field_type *bt_field_type_signed_integer_create(void)
-{
- return create_integer_field_type(BT_FIELD_TYPE_ID_SIGNED_INTEGER);
-}
-
-uint64_t bt_field_type_integer_get_field_value_range(
- struct bt_field_type *ft)
-{
- struct bt_field_type_integer *int_ft = (void *) ft;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_IS_INT(ft, "Field type");
- return int_ft->range;
-}
-
-BT_ASSERT_PRE_FUNC
-static
-bool size_is_valid_for_enumeration_field_type(struct bt_field_type *ft,
- uint64_t size)
-{
- // TODO
- return true;
-}
-
-int bt_field_type_integer_set_field_value_range(
- struct bt_field_type *ft, uint64_t size)
-{
- struct bt_field_type_integer *int_ft = (void *) ft;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_IS_INT(ft, "Field type");
- BT_ASSERT_PRE_FT_HOT(ft, "Field type");
- BT_ASSERT_PRE(size <= 64,
- "Unsupported size for integer field type's field value range "
- "(maximum is 64): size=%" PRIu64, size);
- BT_ASSERT_PRE(int_ft->common.id == BT_FIELD_TYPE_ID_UNSIGNED_INTEGER ||
- int_ft->common.id == BT_FIELD_TYPE_ID_SIGNED_INTEGER ||
- size_is_valid_for_enumeration_field_type(ft, size),
- "Invalid field value range for enumeration field type: "
- "at least one of the current mapping ranges contains values "
- "which are outside this range: %!+F, size=%" PRIu64, ft, size);
- int_ft->range = size;
- BT_LIB_LOGV("Set integer field type's field value range: %!+F", ft);
- return 0;
-}
-
-enum bt_field_type_integer_preferred_display_base
-bt_field_type_integer_get_preferred_display_base(struct bt_field_type *ft)
-{
- struct bt_field_type_integer *int_ft = (void *) ft;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_IS_INT(ft, "Field type");
- return int_ft->base;
-}
-
-int bt_field_type_integer_set_preferred_display_base(struct bt_field_type *ft,
- enum bt_field_type_integer_preferred_display_base base)
-{
- struct bt_field_type_integer *int_ft = (void *) ft;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_IS_INT(ft, "Field type");
- BT_ASSERT_PRE_FT_HOT(ft, "Field type");
- int_ft->base = base;
- BT_LIB_LOGV("Set integer field type's preferred display base: %!+F", ft);
- return 0;
-}
-
-static
-void finalize_enumeration_field_type_mapping(
- struct bt_field_type_enumeration_mapping *mapping)
-{
- BT_ASSERT(mapping);
-
- if (mapping->label) {
- g_string_free(mapping->label, TRUE);
- }
-
- if (mapping->ranges) {
- g_array_free(mapping->ranges, TRUE);
- }
-}
-
-static
-void destroy_enumeration_field_type(struct bt_object *obj)
-{
- struct bt_field_type_enumeration *ft = (void *) obj;
-
- BT_ASSERT(ft);
- BT_LIB_LOGD("Destroying enumeration field type object: %!+F", ft);
-
- if (ft->mappings) {
- uint64_t i;
-
- for (i = 0; i < ft->mappings->len; i++) {
- finalize_enumeration_field_type_mapping(
- BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(ft, i));
- }
-
- g_array_free(ft->mappings, TRUE);
- }
-
- if (ft->label_buf) {
- g_ptr_array_free(ft->label_buf, TRUE);
- }
-
- g_free(ft);
-}
-
-static
-struct bt_field_type *create_enumeration_field_type(enum bt_field_type_id id)
-{
- struct bt_field_type_enumeration *enum_ft = NULL;
-
- BT_LOGD("Creating default enumeration field type object: id=%s",
- bt_common_field_type_id_string(id));
- enum_ft = g_new0(struct bt_field_type_enumeration, 1);
- if (!enum_ft) {
- BT_LOGE_STR("Failed to allocate one enumeration field type.");
- goto error;
- }
-
- init_integer_field_type((void *) enum_ft, id,
- destroy_enumeration_field_type);
- enum_ft->mappings = g_array_new(FALSE, TRUE,
- sizeof(struct bt_field_type_enumeration_mapping));
- if (!enum_ft->mappings) {
- BT_LOGE_STR("Failed to allocate a GArray.");
- goto error;
- }
-
- enum_ft->label_buf = g_ptr_array_new();
- if (!enum_ft->label_buf) {
- BT_LOGE_STR("Failed to allocate a GArray.");
- goto error;
- }
-
- BT_LIB_LOGD("Created enumeration field type object: %!+F", enum_ft);
- goto end;
-
-error:
- BT_PUT(enum_ft);
-
-end:
- return (void *) enum_ft;
-}
-
-struct bt_field_type *bt_field_type_unsigned_enumeration_create(void)
-{
- return create_enumeration_field_type(
- BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION);
-}
-
-struct bt_field_type *bt_field_type_signed_enumeration_create(void)
-{
- return create_enumeration_field_type(
- BT_FIELD_TYPE_ID_SIGNED_ENUMERATION);
-}
-
-uint64_t bt_field_type_enumeration_get_mapping_count(struct bt_field_type *ft)
-{
- struct bt_field_type_enumeration *enum_ft = (void *) ft;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_IS_ENUM(ft, "Field type");
- return (uint64_t) enum_ft->mappings->len;
-}
-
-void bt_field_type_unsigned_enumeration_borrow_mapping_by_index(
- struct bt_field_type *ft, uint64_t index,
- const char **name,
- struct bt_field_type_unsigned_enumeration_mapping_ranges **ranges)
-{
- struct bt_field_type_enumeration *enum_ft = (void *) ft;
- struct bt_field_type_enumeration_mapping *mapping;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_NON_NULL(name, "Name (output)");
- BT_ASSERT_PRE_NON_NULL(ranges, "Ranges (output)");
- BT_ASSERT_PRE_VALID_INDEX(index, enum_ft->mappings->len);
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION,
- "Field type");
- mapping = BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(ft, index);
- *name = mapping->label->str;
- *ranges = (void *) mapping;
-}
-
-void bt_field_type_signed_enumeration_borrow_mapping_by_index(
- struct bt_field_type *ft, uint64_t index,
- const char **name,
- struct bt_field_type_signed_enumeration_mapping_ranges **ranges)
-{
- struct bt_field_type_enumeration *enum_ft = (void *) ft;
- struct bt_field_type_enumeration_mapping *mapping;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_NON_NULL(name, "Name (output)");
- BT_ASSERT_PRE_NON_NULL(ranges, "Ranges (output)");
- BT_ASSERT_PRE_VALID_INDEX(index, enum_ft->mappings->len);
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_SIGNED_ENUMERATION,
- "Field type");
- mapping = BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(ft, index);
- *name = mapping->label->str;
- *ranges = (void *) mapping;
-}
-
-static inline
-uint64_t get_enumeration_field_type_mapping_range_count(
- struct bt_field_type_enumeration_mapping *mapping)
-{
- BT_ASSERT_PRE_NON_NULL(mapping, "Ranges");
- return (uint64_t) mapping->ranges->len;
-}
-
-uint64_t bt_field_type_unsigned_enumeration_mapping_ranges_get_range_count(
- struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges)
-{
- return get_enumeration_field_type_mapping_range_count((void *) ranges);
-}
-
-uint64_t bt_field_type_signed_enumeration_mapping_ranges_get_range_count(
- struct bt_field_type_signed_enumeration_mapping_ranges *ranges)
-{
- return get_enumeration_field_type_mapping_range_count((void *) ranges);
-}
-
-static inline
-void get_enumeration_field_type_mapping_range_at_index(
- struct bt_field_type_enumeration_mapping *mapping,
- uint64_t index, uint64_t *lower, uint64_t *upper)
-{
- struct bt_field_type_enumeration_mapping_range *range;
-
- BT_ASSERT_PRE_NON_NULL(mapping, "Ranges");
- BT_ASSERT_PRE_NON_NULL(lower, "Range's lower (output)");
- BT_ASSERT_PRE_NON_NULL(upper, "Range's upper (output)");
- BT_ASSERT_PRE_VALID_INDEX(index, mapping->ranges->len);
- range = BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(mapping, index);
- *lower = range->lower.u;
- *upper = range->upper.u;
-}
-
-void bt_field_type_unsigned_enumeration_mapping_ranges_get_range_by_index(
- struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges,
- uint64_t index, uint64_t *lower, uint64_t *upper)
-{
- get_enumeration_field_type_mapping_range_at_index((void *) ranges,
- index, lower, upper);
-}
-
-void bt_field_type_signed_enumeration_mapping_ranges_get_range_by_index(
- struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges,
- uint64_t index, int64_t *lower, int64_t *upper)
-{
- get_enumeration_field_type_mapping_range_at_index((void *) ranges,
- index, (uint64_t *) lower, (uint64_t *) upper);
-}
-
-
-
-int bt_field_type_unsigned_enumeration_get_mapping_labels_by_value(
- struct bt_field_type *ft, uint64_t value,
- bt_field_type_enumeration_mapping_label_array *label_array,
- uint64_t *count)
-{
- struct bt_field_type_enumeration *enum_ft = (void *) ft;
- uint64_t i;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)");
- BT_ASSERT_PRE_NON_NULL(count, "Count (output)");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION,
- "Field type");
- g_ptr_array_set_size(enum_ft->label_buf, 0);
-
- for (i = 0; i < enum_ft->mappings->len; i++) {
- uint64_t j;
- struct bt_field_type_enumeration_mapping *mapping =
- BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft, i);
-
- for (j = 0; j < mapping->ranges->len; j++) {
- struct bt_field_type_enumeration_mapping_range *range =
- BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(
- mapping, j);
-
- if (value >= range->lower.u &&
- value <= range->upper.u) {
- g_ptr_array_add(enum_ft->label_buf,
- mapping->label->str);
- break;
- }
- }
- }
-
- *label_array = (void *) enum_ft->label_buf->pdata;
- *count = (uint64_t) enum_ft->label_buf->len;
- return 0;
-}
-
-int bt_field_type_signed_enumeration_get_mapping_labels_by_value(
- struct bt_field_type *ft, int64_t value,
- bt_field_type_enumeration_mapping_label_array *label_array,
- uint64_t *count)
-{
- struct bt_field_type_enumeration *enum_ft = (void *) ft;
- uint64_t i;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)");
- BT_ASSERT_PRE_NON_NULL(count, "Count (output)");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_SIGNED_ENUMERATION,
- "Field type");
- g_ptr_array_set_size(enum_ft->label_buf, 0);
-
- for (i = 0; i < enum_ft->mappings->len; i++) {
- uint64_t j;
- struct bt_field_type_enumeration_mapping *mapping =
- BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft, i);
-
- for (j = 0; j < mapping->ranges->len; j++) {
- struct bt_field_type_enumeration_mapping_range *range =
- BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(
- mapping, j);
-
- if (value >= range->lower.i &&
- value <= range->upper.i) {
- g_ptr_array_add(enum_ft->label_buf,
- mapping->label->str);
- break;
- }
- }
- }
-
- *label_array = (void *) enum_ft->label_buf->pdata;
- *count = (uint64_t) enum_ft->label_buf->len;
- return 0;
-}
-
-static inline
-int add_mapping_to_enumeration_field_type(struct bt_field_type *ft,
- const char *label, uint64_t lower, uint64_t upper)
-{
- int ret = 0;
- uint64_t i;
- struct bt_field_type_enumeration *enum_ft = (void *) ft;
- struct bt_field_type_enumeration_mapping *mapping = NULL;
- struct bt_field_type_enumeration_mapping_range *range;
-
- BT_ASSERT(ft);
- BT_ASSERT_PRE_NON_NULL(label, "Label");
-
- /* Find existing mapping identified by this label */
- for (i = 0; i < enum_ft->mappings->len; i++) {
- struct bt_field_type_enumeration_mapping *mapping_candidate =
- BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft, i);
-
- if (strcmp(mapping_candidate->label->str, label) == 0) {
- mapping = mapping_candidate;
- break;
- }
- }
-
- if (!mapping) {
- /* Create new mapping for this label */
- g_array_set_size(enum_ft->mappings, enum_ft->mappings->len + 1);
- mapping = BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft,
- enum_ft->mappings->len - 1);
- mapping->ranges = g_array_new(FALSE, TRUE,
- sizeof(struct bt_field_type_enumeration_mapping_range));
- if (!mapping->ranges) {
- finalize_enumeration_field_type_mapping(mapping);
- g_array_set_size(enum_ft->mappings,
- enum_ft->mappings->len - 1);
- ret = -1;
- goto end;
- }
-
- mapping->label = g_string_new(label);
- if (!mapping->label) {
- finalize_enumeration_field_type_mapping(mapping);
- g_array_set_size(enum_ft->mappings,
- enum_ft->mappings->len - 1);
- ret = -1;
- goto end;
- }
- }
-
- /* Add range */
- BT_ASSERT(mapping);
- g_array_set_size(mapping->ranges, mapping->ranges->len + 1);
- range = BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(mapping,
- mapping->ranges->len - 1);
- range->lower.u = lower;
- range->upper.u = upper;
- BT_LIB_LOGV("Added mapping to enumeration field type: "
- "%![ft-]+F, label=\"%s\", lower-unsigned=%" PRIu64 ", "
- "upper-unsigned=%" PRIu64, ft, label, lower, upper);
-
-end:
- return ret;
-}
-
-int bt_field_type_unsigned_enumeration_map_range(
- struct bt_field_type *ft, const char *label,
- uint64_t range_lower, uint64_t range_upper)
-{
- struct bt_field_type_enumeration *enum_ft = (void *) ft;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION,
- "Field type");
- BT_ASSERT_PRE(range_lower <= range_upper,
- "Range's upper bound is less than lower bound: "
- "upper=%" PRIu64 ", lower=%" PRIu64,
- range_lower, range_upper);
- BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_ft->common.range,
- range_lower),
- "Range's lower bound is outside the enumeration field type's value range: "
- "%![ft-]+F, lower=%" PRIu64, ft, range_lower);
- BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_ft->common.range,
- range_upper),
- "Range's upper bound is outside the enumeration field type's value range: "
- "%![ft-]+F, upper=%" PRIu64, ft, range_upper);
- return add_mapping_to_enumeration_field_type(ft, label, range_lower,
- range_upper);
-}
-
-int bt_field_type_signed_enumeration_map_range(
- struct bt_field_type *ft, const char *label,
- int64_t range_lower, int64_t range_upper)
-{
- struct bt_field_type_enumeration *enum_ft = (void *) ft;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_SIGNED_ENUMERATION,
- "Field type");
- BT_ASSERT_PRE(range_lower <= range_upper,
- "Range's upper bound is less than lower bound: "
- "upper=%" PRId64 ", lower=%" PRId64,
- range_lower, range_upper);
- BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_ft->common.range,
- range_lower),
- "Range's lower bound is outside the enumeration field type's value range: "
- "%![ft-]+F, lower=%" PRId64, ft, range_lower);
- BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_ft->common.range,
- range_upper),
- "Range's upper bound is outside the enumeration field type's value range: "
- "%![ft-]+F, upper=%" PRId64, ft, range_upper);
- return add_mapping_to_enumeration_field_type(ft, label, range_lower,
- range_upper);
-}
-
-static
-void destroy_real_field_type(struct bt_object *obj)
-{
- BT_ASSERT(obj);
- BT_LIB_LOGD("Destroying real field type object: %!+F", obj);
- g_free(obj);
-}
-
-struct bt_field_type *bt_field_type_real_create(void)
-{
- struct bt_field_type_real *real_ft = NULL;
-
- BT_LOGD_STR("Creating default real field type object.");
- real_ft = g_new0(struct bt_field_type_real, 1);
- if (!real_ft) {
- BT_LOGE_STR("Failed to allocate one real field type.");
- goto error;
- }
-
- init_field_type((void *) real_ft, BT_FIELD_TYPE_ID_REAL,
- destroy_real_field_type);
- BT_LIB_LOGD("Created real field type object: %!+F", real_ft);
- goto end;
-
-error:
- BT_PUT(real_ft);
-
-end:
- return (void *) real_ft;
-}
-
-bt_bool bt_field_type_real_is_single_precision(struct bt_field_type *ft)
-{
- struct bt_field_type_real *real_ft = (void *) ft;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_REAL, "Field type");
- return real_ft->is_single_precision;
-}
-
-int bt_field_type_real_set_is_single_precision(struct bt_field_type *ft,
- bt_bool is_single_precision)
-{
- struct bt_field_type_real *real_ft = (void *) ft;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_REAL, "Field type");
- BT_ASSERT_PRE_FT_HOT(ft, "Field type");
- real_ft->is_single_precision = (bool) is_single_precision;
- BT_LIB_LOGV("Set real field type's \"is single precision\" property: "
- "%!+F", ft);
- return 0;
-}
-
-static
-int init_named_field_types_container(
- struct bt_field_type_named_field_types_container *ft,
- enum bt_field_type_id id, bt_object_release_func release_func)
-{
- int ret = 0;
-
- init_field_type((void *) ft, id, release_func);
- ft->named_fts = g_array_new(FALSE, TRUE,
- sizeof(struct bt_named_field_type));
- if (!ft->named_fts) {
- BT_LOGE_STR("Failed to allocate a GArray.");
- ret = -1;
- goto end;
- }
-
- ft->name_to_index = g_hash_table_new(g_str_hash, g_str_equal);
- if (!ft->name_to_index) {
- BT_LOGE_STR("Failed to allocate a GHashTable.");
- ret = -1;
- goto end;
- }
-
-end:
- return ret;
-}
-
-static
-void finalize_named_field_type(struct bt_named_field_type *named_ft)
-{
- BT_ASSERT(named_ft);
- BT_LIB_LOGD("Finalizing named field type: "
- "addr=%p, name=\"%s\", %![ft-]+F",
- named_ft, named_ft->name ? named_ft->name->str : NULL,
- named_ft->ft);
-
- if (named_ft->name) {
- g_string_free(named_ft->name, TRUE);
- }
-
- BT_LOGD_STR("Putting named field type's field type.");
- bt_put(named_ft->ft);
-}
-
-static
-void finalize_named_field_types_container(
- struct bt_field_type_named_field_types_container *ft)
-{
- uint64_t i;
-
- BT_ASSERT(ft);
-
- if (ft->named_fts) {
- for (i = 0; i < ft->named_fts->len; i++) {
- finalize_named_field_type(
- &g_array_index(ft->named_fts,
- struct bt_named_field_type, i));
- }
-
- g_array_free(ft->named_fts, TRUE);
- }
-
- if (ft->name_to_index) {
- g_hash_table_destroy(ft->name_to_index);
- }
-}
-
-static
-void destroy_structure_field_type(struct bt_object *obj)
-{
- BT_ASSERT(obj);
- BT_LIB_LOGD("Destroying string field type object: %!+F", obj);
- finalize_named_field_types_container((void *) obj);
- g_free(obj);
-}
-
-struct bt_field_type *bt_field_type_structure_create(void)
-{
- int ret;
- struct bt_field_type_structure *struct_ft = NULL;
-
- BT_LOGD_STR("Creating default structure field type object.");
- struct_ft = g_new0(struct bt_field_type_structure, 1);
- if (!struct_ft) {
- BT_LOGE_STR("Failed to allocate one structure field type.");
- goto error;
- }
-
- ret = init_named_field_types_container((void *) struct_ft,
- BT_FIELD_TYPE_ID_STRUCTURE, destroy_structure_field_type);
- if (ret) {
- goto error;
- }
-
- BT_LIB_LOGD("Created structure field type object: %!+F", struct_ft);
- goto end;
-
-error:
- BT_PUT(struct_ft);
-
-end:
- return (void *) struct_ft;
-}
-
-static
-int append_named_field_type_to_container_field_type(
- struct bt_field_type_named_field_types_container *container_ft,
- const char *name, struct bt_field_type *ft)
-{
- int ret = 0;
- struct bt_named_field_type *named_ft;
- GString *name_str;
-
- BT_ASSERT(container_ft);
- BT_ASSERT_PRE_FT_HOT(container_ft, "Field type");
- BT_ASSERT_PRE_NON_NULL(name, "Name");
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE(!bt_g_hash_table_contains(container_ft->name_to_index,
- name),
- "Duplicate member/option name in structure/variant field type: "
- "%![container-ft-]+F, name=\"%s\"", container_ft, name);
- name_str = g_string_new(name);
- if (!name_str) {
- BT_LOGE_STR("Failed to allocate a GString.");
- ret = -1;
- goto end;
- }
-
- g_array_set_size(container_ft->named_fts,
- container_ft->named_fts->len + 1);
- named_ft = &g_array_index(container_ft->named_fts,
- struct bt_named_field_type, container_ft->named_fts->len - 1);
- named_ft->name = name_str;
- named_ft->ft = bt_get(ft);
- g_hash_table_insert(container_ft->name_to_index, named_ft->name->str,
- GUINT_TO_POINTER(container_ft->named_fts->len - 1));
- bt_field_type_freeze(ft);
-
-end:
- return ret;
-}
-
-int bt_field_type_structure_append_member(struct bt_field_type *ft,
- const char *name, struct bt_field_type *member_ft)
-{
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STRUCTURE, "Field type");
- return append_named_field_type_to_container_field_type((void *) ft,
- name, member_ft);
-}
-
-uint64_t bt_field_type_structure_get_member_count(struct bt_field_type *ft)
-{
- struct bt_field_type_structure *struct_ft = (void *) ft;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STRUCTURE, "Field type");
- return (uint64_t) struct_ft->common.named_fts->len;
-}
-
-static
-void borrow_named_field_type_from_container_field_type_at_index(
- struct bt_field_type_named_field_types_container *ft,
- uint64_t index, const char **name,
- struct bt_field_type **out_ft)
-{
- struct bt_named_field_type *named_ft;
-
- BT_ASSERT(ft);
- BT_ASSERT_PRE_NON_NULL(name, "Name");
- BT_ASSERT_PRE_NON_NULL(out_ft, "Field type (output)");
- BT_ASSERT_PRE_VALID_INDEX(index, ft->named_fts->len);
- named_ft = BT_FIELD_TYPE_NAMED_FT_AT_INDEX(ft, index);
- *name = named_ft->name->str;
- *out_ft = named_ft->ft;
-}
-
-void bt_field_type_structure_borrow_member_by_index(
- struct bt_field_type *ft, uint64_t index,
- const char **name, struct bt_field_type **out_ft)
-{
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STRUCTURE, "Field type");
- borrow_named_field_type_from_container_field_type_at_index((void *) ft,
- index, name, out_ft);
-}
-
-static
-struct bt_field_type *borrow_field_type_from_container_field_type_by_name(
- struct bt_field_type_named_field_types_container *ft,
- const char *name)
-{
- struct bt_field_type *ret_ft = NULL;
- struct bt_named_field_type *named_ft;
- gpointer orig_key;
- gpointer value;
-
- BT_ASSERT(ft);
- BT_ASSERT_PRE_NON_NULL(name, "Name");
- if (!g_hash_table_lookup_extended(ft->name_to_index, name, &orig_key,
- &value)) {
- goto end;
- }
-
- named_ft = BT_FIELD_TYPE_NAMED_FT_AT_INDEX(ft,
- GPOINTER_TO_UINT(value));
- ret_ft = named_ft->ft;
-
-end:
- return ret_ft;
-}
-
-struct bt_field_type *bt_field_type_structure_borrow_member_field_type_by_name(
- struct bt_field_type *ft, const char *name)
-{
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STRUCTURE, "Field type");
- return borrow_field_type_from_container_field_type_by_name((void *) ft,
- name);
-}
-
-static
-void destroy_variant_field_type(struct bt_object *obj)
-{
- struct bt_field_type_variant *ft = (void *) obj;
-
- BT_ASSERT(ft);
- BT_LIB_LOGD("Destroying variant field type object: %!+F", ft);
- finalize_named_field_types_container((void *) ft);
- BT_LOGD_STR("Putting selector field path.");
- bt_put(ft->selector_field_path);
- g_free(ft);
-}
-
-struct bt_field_type *bt_field_type_variant_create(void)
-{
- int ret;
- struct bt_field_type_variant *var_ft = NULL;
-
- BT_LOGD_STR("Creating default variant field type object.");
- var_ft = g_new0(struct bt_field_type_variant, 1);
- if (!var_ft) {
- BT_LOGE_STR("Failed to allocate one variant field type.");
- goto error;
- }
-
- ret = init_named_field_types_container((void *) var_ft,
- BT_FIELD_TYPE_ID_VARIANT, destroy_variant_field_type);
- if (ret) {
- goto error;
- }
-
- BT_LIB_LOGD("Created variant field type object: %!+F", var_ft);
- goto end;
-
-error:
- BT_PUT(var_ft);
-
-end:
- return (void *) var_ft;
-}
-
-int bt_field_type_variant_set_selector_field_type(
- struct bt_field_type *ft, struct bt_field_type *selector_ft)
-{
- struct bt_field_type_variant *var_ft = (void *) ft;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Variant field type");
- BT_ASSERT_PRE_NON_NULL(selector_ft, "Selector field type");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
- BT_ASSERT_PRE_FT_IS_ENUM(selector_ft, "Selector field type");
- BT_ASSERT_PRE_FT_HOT(ft, "Variant field type");
- var_ft->selector_ft = selector_ft;
- bt_field_type_freeze(selector_ft);
- return 0;
-}
-
-int bt_field_type_variant_append_option(struct bt_field_type *ft,
- const char *name, struct bt_field_type *option_ft)
-{
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
- return append_named_field_type_to_container_field_type((void *) ft,
- name, option_ft);
-}
-
-struct bt_field_type *bt_field_type_variant_borrow_option_field_type_by_name(
- struct bt_field_type *ft, const char *name)
-{
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
- return borrow_field_type_from_container_field_type_by_name((void *) ft,
- name);
-}
-
-uint64_t bt_field_type_variant_get_option_count(struct bt_field_type *ft)
-{
- struct bt_field_type_variant *var_ft = (void *) ft;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
- return (uint64_t) var_ft->common.named_fts->len;
-}
-
-void bt_field_type_variant_borrow_option_by_index(
- struct bt_field_type *ft, uint64_t index,
- const char **name, struct bt_field_type **out_ft)
-{
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
- borrow_named_field_type_from_container_field_type_at_index((void *) ft,
- index, name, out_ft);
-}
-
-struct bt_field_path *bt_field_type_variant_borrow_selector_field_path(
- struct bt_field_type *ft)
-{
- struct bt_field_type_variant *var_ft = (void *) ft;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT,
- "Field type");
- return var_ft->selector_field_path;
-}
-
-static
-void init_array_field_type(struct bt_field_type_array *ft,
- enum bt_field_type_id id, bt_object_release_func release_func,
- struct bt_field_type *element_ft)
-{
- BT_ASSERT(element_ft);
- init_field_type((void *) ft, id, release_func);
- ft->element_ft = bt_get(element_ft);
- bt_field_type_freeze(element_ft);
-}
-
-static
-void finalize_array_field_type(struct bt_field_type_array *array_ft)
-{
- BT_ASSERT(array_ft);
- BT_LOGD_STR("Putting element field type.");
- bt_put(array_ft->element_ft);
-}
-
-static
-void destroy_static_array_field_type(struct bt_object *obj)
-{
- BT_ASSERT(obj);
- BT_LIB_LOGD("Destroying static array field type object: %!+F", obj);
- finalize_array_field_type((void *) obj);
- g_free(obj);
-}
-
-struct bt_field_type *bt_field_type_static_array_create(
- struct bt_field_type *element_ft, uint64_t length)
-{
- struct bt_field_type_static_array *array_ft = NULL;
-
- BT_ASSERT_PRE_NON_NULL(element_ft, "Element field type");
- BT_LOGD_STR("Creating default static array field type object.");
- array_ft = g_new0(struct bt_field_type_static_array, 1);
- if (!array_ft) {
- BT_LOGE_STR("Failed to allocate one static array field type.");
- goto error;
- }
-
- init_array_field_type((void *) array_ft, BT_FIELD_TYPE_ID_STATIC_ARRAY,
- destroy_static_array_field_type, element_ft);
- array_ft->length = length;
- BT_LIB_LOGD("Created static array field type object: %!+F", array_ft);
- goto end;
-
-error:
- BT_PUT(array_ft);
-
-end:
- return (void *) array_ft;
-}
-
-struct bt_field_type *bt_field_type_array_borrow_element_field_type(
- struct bt_field_type *ft)
-{
- struct bt_field_type_array *array_ft = (void *) ft;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_IS_ARRAY(ft, "Field type");
- return array_ft->element_ft;
-}
-
-uint64_t bt_field_type_static_array_get_length(struct bt_field_type *ft)
-{
- struct bt_field_type_static_array *array_ft = (void *) ft;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STATIC_ARRAY,
- "Field type");
- return (uint64_t) array_ft->length;
-}
-
-static
-void destroy_dynamic_array_field_type(struct bt_object *obj)
-{
- struct bt_field_type_dynamic_array *ft = (void *) obj;
-
- BT_ASSERT(ft);
- BT_LIB_LOGD("Destroying dynamic array field type object: %!+F", ft);
- finalize_array_field_type((void *) ft);
- BT_LOGD_STR("Putting length field path.");
- bt_put(ft->length_field_path);
- g_free(ft);
-}
-
-struct bt_field_type *bt_field_type_dynamic_array_create(
- struct bt_field_type *element_ft)
-{
- struct bt_field_type_dynamic_array *array_ft = NULL;
-
- BT_ASSERT_PRE_NON_NULL(element_ft, "Element field type");
- BT_LOGD_STR("Creating default dynamic array field type object.");
- array_ft = g_new0(struct bt_field_type_dynamic_array, 1);
- if (!array_ft) {
- BT_LOGE_STR("Failed to allocate one dynamic array field type.");
- goto error;
- }
-
- init_array_field_type((void *) array_ft, BT_FIELD_TYPE_ID_DYNAMIC_ARRAY,
- destroy_dynamic_array_field_type, element_ft);
- BT_LIB_LOGD("Created dynamic array field type object: %!+F", array_ft);
- goto end;
-
-error:
- BT_PUT(array_ft);
-
-end:
- return (void *) array_ft;
-}
-
-int bt_field_type_dynamic_array_set_length_field_type(struct bt_field_type *ft,
- struct bt_field_type *length_ft)
-{
- struct bt_field_type_dynamic_array *array_ft = (void *) ft;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Dynamic array field type");
- BT_ASSERT_PRE_NON_NULL(length_ft, "Length field type");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_DYNAMIC_ARRAY,
- "Field type");
- BT_ASSERT_PRE_FT_IS_UNSIGNED_INT(length_ft, "Length field type");
- BT_ASSERT_PRE_FT_HOT(ft, "Dynamic array field type");
- array_ft->length_ft = length_ft;
- bt_field_type_freeze(length_ft);
- return 0;
-}
-
-struct bt_field_path *bt_field_type_dynamic_array_borrow_length_field_path(
- struct bt_field_type *ft)
-{
- struct bt_field_type_dynamic_array *seq_ft = (void *) ft;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_DYNAMIC_ARRAY,
- "Field type");
- return seq_ft->length_field_path;
-}
-
-static
-void destroy_string_field_type(struct bt_object *obj)
-{
- BT_ASSERT(obj);
- BT_LIB_LOGD("Destroying string field type object: %!+F", obj);
- g_free(obj);
-}
-
-struct bt_field_type *bt_field_type_string_create(void)
-{
- struct bt_field_type_string *string_ft = NULL;
-
- BT_LOGD_STR("Creating default string field type object.");
- string_ft = g_new0(struct bt_field_type_string, 1);
- if (!string_ft) {
- BT_LOGE_STR("Failed to allocate one string field type.");
- goto error;
- }
-
- init_field_type((void *) string_ft, BT_FIELD_TYPE_ID_STRING,
- destroy_string_field_type);
- BT_LIB_LOGD("Created string field type object: %!+F", string_ft);
- goto end;
-
-error:
- BT_PUT(string_ft);
-
-end:
- return (void *) string_ft;
-}
-
-BT_HIDDEN
-void _bt_field_type_freeze(struct bt_field_type *ft)
-{
- /*
- * Element/member/option field types are frozen when added to
- * their owner.
- */
- BT_ASSERT(ft);
- ft->frozen = true;
-}
-
-BT_HIDDEN
-void _bt_field_type_make_part_of_trace(struct bt_field_type *ft)
-{
- BT_ASSERT(ft);
- BT_ASSERT_PRE(!ft->part_of_trace,
- "Field type is already part of a trace: %!+F", ft);
- ft->part_of_trace = true;
-
- switch (ft->id) {
- case BT_FIELD_TYPE_ID_STRUCTURE:
- case BT_FIELD_TYPE_ID_VARIANT:
- {
- struct bt_field_type_named_field_types_container *container_ft =
- (void *) ft;
- uint64_t i;
-
- for (i = 0; i < container_ft->named_fts->len; i++) {
- struct bt_named_field_type *named_ft =
- BT_FIELD_TYPE_NAMED_FT_AT_INDEX(
- container_ft, i);
-
- bt_field_type_make_part_of_trace(named_ft->ft);
- }
-
- break;
- }
- case BT_FIELD_TYPE_ID_STATIC_ARRAY:
- case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
- {
- struct bt_field_type_array *array_ft = (void *) ft;
-
- bt_field_type_make_part_of_trace(array_ft->element_ft);
- break;
- }
- default:
- break;
- }
-}
+++ /dev/null
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "FIELD-WRAPPER"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/ctf-ir/field-wrapper-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/object-pool-internal.h>
-#include <babeltrace/object-internal.h>
-#include <glib.h>
-
-BT_HIDDEN
-struct bt_field_wrapper *bt_field_wrapper_new(void *data)
-{
- struct bt_field_wrapper *field_wrapper =
- g_new0(struct bt_field_wrapper, 1);
-
- BT_LOGD_STR("Creating empty field wrapper object.");
-
- if (!field_wrapper) {
- BT_LOGE("Failed to allocate one field wrapper.");
- goto end;
- }
-
- bt_object_init_unique(&field_wrapper->base);
- BT_LOGD("Created empty field wrapper object: addr=%p",
- field_wrapper);
-
-end:
- return field_wrapper;
-}
-
-BT_HIDDEN
-void bt_field_wrapper_destroy(struct bt_field_wrapper *field_wrapper)
-{
- BT_LOGD("Destroying field wrapper: addr=%p", field_wrapper);
-
- if (field_wrapper->field) {
- BT_LOGD_STR("Destroying field.");
- bt_field_destroy((void *) field_wrapper->field);
- }
-
- BT_LOGD_STR("Putting stream class.");
- g_free(field_wrapper);
-}
-
-BT_HIDDEN
-struct bt_field_wrapper *bt_field_wrapper_create(
- struct bt_object_pool *pool, struct bt_field_type *ft)
-{
- struct bt_field_wrapper *field_wrapper = NULL;
-
- BT_ASSERT(pool);
- BT_ASSERT(ft);
- field_wrapper = bt_object_pool_create_object(pool);
- if (!field_wrapper) {
- BT_LIB_LOGE("Cannot allocate one field wrapper from field wrapper pool: "
- "%![pool-]+o", pool);
- goto error;
- }
-
- if (!field_wrapper->field) {
- field_wrapper->field = (void *) bt_field_create(ft);
- if (!field_wrapper->field) {
- BT_LIB_LOGE("Cannot create field wrapper from field type: "
- "%![ft-]+F", ft);
- goto error;
- }
-
- BT_LIB_LOGD("Created initial field wrapper object: "
- "wrapper-addr=%p, %![field-]+f", field_wrapper,
- field_wrapper->field);
- }
-
- goto end;
-
-error:
- if (field_wrapper) {
- bt_field_wrapper_destroy(field_wrapper);
- field_wrapper = NULL;
- }
-
-end:
- return field_wrapper;
-}
+++ /dev/null
-/*
- * fields.c
- *
- * Babeltrace CTF IR - Event Fields
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "FIELDS"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/compat/fcntl-internal.h>
-#include <babeltrace/align-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <inttypes.h>
-
-static
-void reset_single_field(struct bt_field *field);
-
-static
-void reset_array_field(struct bt_field *field);
-
-static
-void reset_structure_field(struct bt_field *field);
-
-static
-void reset_variant_field(struct bt_field *field);
-
-static
-void set_single_field_is_frozen(struct bt_field *field, bool is_frozen);
-
-static
-void set_array_field_is_frozen(struct bt_field *field, bool is_frozen);
-
-static
-void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen);
-
-static
-void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen);
-
-static
-bool single_field_is_set(struct bt_field *field);
-
-static
-bool array_field_is_set(struct bt_field *field);
-
-static
-bool structure_field_is_set(struct bt_field *field);
-
-static
-bool variant_field_is_set(struct bt_field *field);
-
-static
-struct bt_field_methods integer_field_methods = {
- .set_is_frozen = set_single_field_is_frozen,
- .is_set = single_field_is_set,
- .reset = reset_single_field,
-};
-
-static
-struct bt_field_methods real_field_methods = {
- .set_is_frozen = set_single_field_is_frozen,
- .is_set = single_field_is_set,
- .reset = reset_single_field,
-};
-
-static
-struct bt_field_methods string_field_methods = {
- .set_is_frozen = set_single_field_is_frozen,
- .is_set = single_field_is_set,
- .reset = reset_single_field,
-};
-
-static
-struct bt_field_methods structure_field_methods = {
- .set_is_frozen = set_structure_field_is_frozen,
- .is_set = structure_field_is_set,
- .reset = reset_structure_field,
-};
-
-static
-struct bt_field_methods array_field_methods = {
- .set_is_frozen = set_array_field_is_frozen,
- .is_set = array_field_is_set,
- .reset = reset_array_field,
-};
-
-static
-struct bt_field_methods variant_field_methods = {
- .set_is_frozen = set_variant_field_is_frozen,
- .is_set = variant_field_is_set,
- .reset = reset_variant_field,
-};
-
-static
-struct bt_field *create_integer_field(struct bt_field_type *);
-
-static
-struct bt_field *create_real_field(struct bt_field_type *);
-
-static
-struct bt_field *create_string_field(struct bt_field_type *);
-
-static
-struct bt_field *create_structure_field(struct bt_field_type *);
-
-static
-struct bt_field *create_static_array_field(struct bt_field_type *);
-
-static
-struct bt_field *create_dynamic_array_field(struct bt_field_type *);
-
-static
-struct bt_field *create_variant_field(struct bt_field_type *);
-
-static
-struct bt_field *(* const field_create_funcs[])(struct bt_field_type *) = {
- [BT_FIELD_TYPE_ID_UNSIGNED_INTEGER] = create_integer_field,
- [BT_FIELD_TYPE_ID_SIGNED_INTEGER] = create_integer_field,
- [BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION] = create_integer_field,
- [BT_FIELD_TYPE_ID_SIGNED_ENUMERATION] = create_integer_field,
- [BT_FIELD_TYPE_ID_REAL] = create_real_field,
- [BT_FIELD_TYPE_ID_STRING] = create_string_field,
- [BT_FIELD_TYPE_ID_STRUCTURE] = create_structure_field,
- [BT_FIELD_TYPE_ID_STATIC_ARRAY] = create_static_array_field,
- [BT_FIELD_TYPE_ID_DYNAMIC_ARRAY] = create_dynamic_array_field,
- [BT_FIELD_TYPE_ID_VARIANT] = create_variant_field,
-};
-
-static
-void destroy_integer_field(struct bt_field *field);
-
-static
-void destroy_real_field(struct bt_field *field);
-
-static
-void destroy_string_field(struct bt_field *field);
-
-static
-void destroy_structure_field(struct bt_field *field);
-
-static
-void destroy_array_field(struct bt_field *field);
-
-static
-void destroy_variant_field(struct bt_field *field);
-
-static
-void (* const field_destroy_funcs[])(struct bt_field *) = {
- [BT_FIELD_TYPE_ID_UNSIGNED_INTEGER] = destroy_integer_field,
- [BT_FIELD_TYPE_ID_SIGNED_INTEGER] = destroy_integer_field,
- [BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION] = destroy_integer_field,
- [BT_FIELD_TYPE_ID_SIGNED_ENUMERATION] = destroy_integer_field,
- [BT_FIELD_TYPE_ID_REAL] = destroy_real_field,
- [BT_FIELD_TYPE_ID_STRING] = destroy_string_field,
- [BT_FIELD_TYPE_ID_STRUCTURE] = destroy_structure_field,
- [BT_FIELD_TYPE_ID_STATIC_ARRAY] = destroy_array_field,
- [BT_FIELD_TYPE_ID_DYNAMIC_ARRAY] = destroy_array_field,
- [BT_FIELD_TYPE_ID_VARIANT] = destroy_variant_field,
-};
-
-struct bt_field_type *bt_field_borrow_type(struct bt_field *field)
-{
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- return field->type;
-}
-
-enum bt_field_type_id bt_field_get_type_id(struct bt_field *field)
-{
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- return field->type->id;
-}
-
-BT_HIDDEN
-struct bt_field *bt_field_create(struct bt_field_type *ft)
-{
- struct bt_field *field = NULL;
-
- BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT(bt_field_type_has_known_id(ft));
- field = field_create_funcs[ft->id](ft);
- if (!field) {
- BT_LIB_LOGE("Cannot create field object from field type: "
- "%![ft-]+F", ft);
- goto end;
- }
-
-end:
- return field;
-}
-
-static inline
-void init_field(struct bt_field *field, struct bt_field_type *ft,
- struct bt_field_methods *methods)
-{
- BT_ASSERT(field);
- BT_ASSERT(ft);
- bt_object_init_unique(&field->base);
- field->methods = methods;
- field->type = bt_get(ft);
-}
-
-static
-struct bt_field *create_integer_field(struct bt_field_type *ft)
-{
- struct bt_field_integer *int_field;
-
- BT_LIB_LOGD("Creating integer field object: %![ft-]+F", ft);
- int_field = g_new0(struct bt_field_integer, 1);
- if (!int_field) {
- BT_LOGE_STR("Failed to allocate one integer field.");
- goto end;
- }
-
- init_field((void *) int_field, ft, &integer_field_methods);
- BT_LIB_LOGD("Created integer field object: %!+f", int_field);
-
-end:
- return (void *) int_field;
-}
-
-static
-struct bt_field *create_real_field(struct bt_field_type *ft)
-{
- struct bt_field_real *real_field;
-
- BT_LIB_LOGD("Creating real field object: %![ft-]+F", ft);
- real_field = g_new0(struct bt_field_real, 1);
- if (!real_field) {
- BT_LOGE_STR("Failed to allocate one real field.");
- goto end;
- }
-
- init_field((void *) real_field, ft, &real_field_methods);
- BT_LIB_LOGD("Created real field object: %!+f", real_field);
-
-end:
- return (void *) real_field;
-}
-
-static
-struct bt_field *create_string_field(struct bt_field_type *ft)
-{
- struct bt_field_string *string_field;
-
- BT_LIB_LOGD("Creating string field object: %![ft-]+F", ft);
- string_field = g_new0(struct bt_field_string, 1);
- if (!string_field) {
- BT_LOGE_STR("Failed to allocate one string field.");
- goto end;
- }
-
- init_field((void *) string_field, ft, &string_field_methods);
- string_field->buf = g_array_sized_new(FALSE, FALSE,
- sizeof(char), 1);
- if (!string_field->buf) {
- BT_LOGE_STR("Failed to allocate a GArray.");
- BT_PUT(string_field);
- goto end;
- }
-
- g_array_index(string_field->buf, char, 0) = '\0';
- BT_LIB_LOGD("Created string field object: %!+f", string_field);
-
-end:
- return (void *) string_field;
-}
-
-static inline
-int create_fields_from_named_field_types(
- struct bt_field_type_named_field_types_container *ft,
- GPtrArray **fields)
-{
- int ret = 0;
- uint64_t i;
-
- *fields = g_ptr_array_new_with_free_func(
- (GDestroyNotify) bt_field_destroy);
- if (!*fields) {
- BT_LOGE_STR("Failed to allocate a GPtrArray.");
- ret = -1;
- goto end;
- }
-
- g_ptr_array_set_size(*fields, ft->named_fts->len);
-
- for (i = 0; i < ft->named_fts->len; i++) {
- struct bt_field *field;
- struct bt_named_field_type *named_ft =
- BT_FIELD_TYPE_NAMED_FT_AT_INDEX(ft, i);
-
- field = bt_field_create(named_ft->ft);
- if (!field) {
- BT_LIB_LOGE("Failed to create structure member or variant option field: "
- "name=\"%s\", %![ft-]+F",
- named_ft->name->str, named_ft->ft);
- ret = -1;
- goto end;
- }
-
- g_ptr_array_index(*fields, i) = field;
- }
-
-end:
- return ret;
-}
-
-static
-struct bt_field *create_structure_field(struct bt_field_type *ft)
-{
- struct bt_field_structure *struct_field;
-
- BT_LIB_LOGD("Creating structure field object: %![ft-]+F", ft);
- struct_field = g_new0(struct bt_field_structure, 1);
- if (!struct_field) {
- BT_LOGE_STR("Failed to allocate one structure field.");
- goto end;
- }
-
- init_field((void *) struct_field, ft, &structure_field_methods);
-
- if (create_fields_from_named_field_types((void *) ft,
- &struct_field->fields)) {
- BT_LIB_LOGE("Cannot create structure member fields: "
- "%![ft-]+F", ft);
- BT_PUT(struct_field);
- goto end;
- }
-
- BT_LIB_LOGD("Created structure field object: %!+f", struct_field);
-
-end:
- return (void *) struct_field;
-}
-
-static
-struct bt_field *create_variant_field(struct bt_field_type *ft)
-{
- struct bt_field_variant *var_field;
-
- BT_LIB_LOGD("Creating variant field object: %![ft-]+F", ft);
- var_field = g_new0(struct bt_field_variant, 1);
- if (!var_field) {
- BT_LOGE_STR("Failed to allocate one variant field.");
- goto end;
- }
-
- init_field((void *) var_field, ft, &variant_field_methods);
-
- if (create_fields_from_named_field_types((void *) ft,
- &var_field->fields)) {
- BT_LIB_LOGE("Cannot create variant member fields: "
- "%![ft-]+F", ft);
- BT_PUT(var_field);
- goto end;
- }
-
- BT_LIB_LOGD("Created variant field object: %!+f", var_field);
-
-end:
- return (void *) var_field;
-}
-
-static inline
-int init_array_field_fields(struct bt_field_array *array_field)
-{
- int ret = 0;
- uint64_t i;
- struct bt_field_type_array *array_ft;
-
- BT_ASSERT(array_field);
- array_ft = (void *) array_field->common.type;
- array_field->fields = g_ptr_array_sized_new(array_field->length);
- if (!array_field->fields) {
- BT_LOGE_STR("Failed to allocate a GPtrArray.");
- ret = -1;
- goto end;
- }
-
- g_ptr_array_set_free_func(array_field->fields,
- (GDestroyNotify) bt_field_destroy);
- g_ptr_array_set_size(array_field->fields, array_field->length);
-
- for (i = 0; i < array_field->length; i++) {
- array_field->fields->pdata[i] = bt_field_create(
- array_ft->element_ft);
- if (!array_field->fields->pdata[i]) {
- BT_LIB_LOGE("Cannot create array field's element field: "
- "index=%" PRIu64 ", %![ft-]+F", i, array_ft);
- ret = -1;
- goto end;
- }
- }
-
-end:
- return ret;
-}
-
-static
-struct bt_field *create_static_array_field(struct bt_field_type *ft)
-{
- struct bt_field_type_static_array *array_ft = (void *) ft;
- struct bt_field_array *array_field;
-
- BT_LIB_LOGD("Creating static array field object: %![ft-]+F", ft);
- array_field = g_new0(struct bt_field_array, 1);
- if (!array_field) {
- BT_LOGE_STR("Failed to allocate one static array field.");
- goto end;
- }
-
- init_field((void *) array_field, ft, &array_field_methods);
- array_field->length = array_ft->length;
-
- if (init_array_field_fields(array_field)) {
- BT_LIB_LOGE("Cannot create static array fields: "
- "%![ft-]+F", ft);
- BT_PUT(array_field);
- goto end;
- }
-
- BT_LIB_LOGD("Created static array field object: %!+f", array_field);
-
-end:
- return (void *) array_field;
-}
-
-static
-struct bt_field *create_dynamic_array_field(struct bt_field_type *ft)
-{
- struct bt_field_array *array_field;
-
- BT_LIB_LOGD("Creating dynamic array field object: %![ft-]+F", ft);
- array_field = g_new0(struct bt_field_array, 1);
- if (!array_field) {
- BT_LOGE_STR("Failed to allocate one dynamic array field.");
- goto end;
- }
-
- init_field((void *) array_field, ft, &array_field_methods);
-
- if (init_array_field_fields(array_field)) {
- BT_LIB_LOGE("Cannot create dynamic array fields: "
- "%![ft-]+F", ft);
- BT_PUT(array_field);
- goto end;
- }
-
- BT_LIB_LOGD("Created dynamic array field object: %!+f", array_field);
-
-end:
- return (void *) array_field;
-}
-
-int64_t bt_field_signed_integer_get_value(struct bt_field *field)
-{
- struct bt_field_integer *int_field = (void *) field;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
- BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(field, "Field");
- return int_field->value.i;
-}
-
-void bt_field_signed_integer_set_value(struct bt_field *field, int64_t value)
-{
- struct bt_field_integer *int_field = (void *) field;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(field, "Field");
- BT_ASSERT_PRE_FIELD_HOT(field, "Field");
- BT_ASSERT_PRE(bt_util_value_is_in_range_signed(
- ((struct bt_field_type_integer *) field->type)->range, value),
- "Value is out of bounds: value=%" PRId64 ", %![field-]+f, "
- "%![ft-]+F", value, field, field->type);
- int_field->value.i = value;
- bt_field_set_single(field, true);
-}
-
-uint64_t bt_field_unsigned_integer_get_value(struct bt_field *field)
-{
- struct bt_field_integer *int_field = (void *) field;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
- BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(field, "Field");
- return int_field->value.u;
-}
-
-void bt_field_unsigned_integer_set_value(struct bt_field *field,
- uint64_t value)
-{
- struct bt_field_integer *int_field = (void *) field;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(field, "Field");
- BT_ASSERT_PRE_FIELD_HOT(field, "Field");
- BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(
- ((struct bt_field_type_integer *) field->type)->range, value),
- "Value is out of bounds: value=%" PRIu64 ", %![field-]+f, "
- "%![ft-]+F", value, field, field->type);
- int_field->value.u = value;
- bt_field_set_single(field, true);
-}
-
-double bt_field_real_get_value(struct bt_field *field)
-{
- struct bt_field_real *real_field = (void *) field;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
- BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_REAL, "Field");
- return real_field->value;
-}
-
-void bt_field_real_set_value(struct bt_field *field, double value)
-{
- struct bt_field_real *real_field = (void *) field;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_REAL, "Field");
- BT_ASSERT_PRE_FIELD_HOT(field, "Field");
- BT_ASSERT_PRE(
- !((struct bt_field_type_real *) field->type)->is_single_precision ||
- (double) (float) value == value,
- "Invalid value for a single-precision real number: value=%f, "
- "%![ft-]+F", value, field->type);
- real_field->value = value;
- bt_field_set_single(field, true);
-}
-
-int bt_field_unsigned_enumeration_get_mapping_labels(struct bt_field *field,
- bt_field_type_enumeration_mapping_label_array *label_array,
- uint64_t *count)
-{
- struct bt_field_integer *int_field = (void *) field;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)");
- BT_ASSERT_PRE_NON_NULL(label_array, "Count (output)");
- BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
- BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
- BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION, "Field");
- return bt_field_type_unsigned_enumeration_get_mapping_labels_by_value(
- field->type, int_field->value.u, label_array, count);
-}
-
-int bt_field_signed_enumeration_get_mapping_labels(struct bt_field *field,
- bt_field_type_enumeration_mapping_label_array *label_array,
- uint64_t *count)
-{
- struct bt_field_integer *int_field = (void *) field;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)");
- BT_ASSERT_PRE_NON_NULL(label_array, "Count (output)");
- BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
- BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
- BT_FIELD_TYPE_ID_SIGNED_ENUMERATION, "Field");
- return bt_field_type_signed_enumeration_get_mapping_labels_by_value(
- field->type, int_field->value.i, label_array, count);
-}
-
-const char *bt_field_string_get_value(struct bt_field *field)
-{
- struct bt_field_string *string_field = (void *) field;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
- BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_STRING,
- "Field");
- return (const char *) string_field->buf->data;
-}
-
-uint64_t bt_field_string_get_length(struct bt_field *field)
-{
- struct bt_field_string *string_field = (void *) field;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
- BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_STRING,
- "Field");
- return string_field->length;
-}
-
-int bt_field_string_set_value(struct bt_field *field, const char *value)
-{
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_NON_NULL(value, "Value");
- BT_ASSERT_PRE_FIELD_HOT(field, "Field");
- BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_STRING,
- "Field");
- bt_field_string_clear(field);
- return bt_field_string_append_with_length(field, value,
- (uint64_t) strlen(value));
-}
-
-int bt_field_string_append(struct bt_field *field, const char *value)
-{
- return bt_field_string_append_with_length(field, value,
- (uint64_t) strlen(value));
-}
-
-int bt_field_string_append_with_length(struct bt_field *field,
- const char *value, uint64_t length)
-{
- struct bt_field_string *string_field = (void *) field;
- char *data;
- uint64_t new_length;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_NON_NULL(value, "Value");
- BT_ASSERT_PRE_FIELD_HOT(field, "Field");
- BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
- BT_FIELD_TYPE_ID_STRING, "Field");
-
- /* Make sure no null bytes are appended */
- BT_ASSERT_PRE(memchr(value, '\0', length) == NULL,
- "String value to append contains a null character: "
- "partial-value=\"%.32s\", length=%" PRIu64, value, length);
-
- new_length = length + string_field->length;
-
- if (unlikely(new_length + 1 > string_field->buf->len)) {
- g_array_set_size(string_field->buf, new_length + 1);
- }
-
- data = string_field->buf->data;
- memcpy(data + string_field->length, value, length);
- ((char *) string_field->buf->data)[new_length] = '\0';
- string_field->length = new_length;
- bt_field_set_single(field, true);
- return 0;
-}
-
-int bt_field_string_clear(struct bt_field *field)
-{
- struct bt_field_string *string_field = (void *) field;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_FIELD_HOT(field, "Field");
- BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
- BT_FIELD_TYPE_ID_STRING, "Field");
- string_field->length = 0;
- bt_field_set_single(field, true);
- return 0;
-}
-
-uint64_t bt_field_array_get_length(struct bt_field *field)
-{
- struct bt_field_array *array_field = (void *) field;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_FIELD_IS_ARRAY(field, "Field");
- return array_field->length;
-}
-
-int bt_field_dynamic_array_set_length(struct bt_field *field,
- uint64_t length)
-{
- int ret = 0;
- struct bt_field_array *array_field = (void *) field;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
- BT_FIELD_TYPE_ID_DYNAMIC_ARRAY, "Field");
- BT_ASSERT_PRE_FIELD_HOT(field, "Field");
-
- if (unlikely(length > array_field->fields->len)) {
- /* Make more room */
- struct bt_field_type_array *array_ft;
- uint64_t cur_len = array_field->fields->len;
- uint64_t i;
-
- g_ptr_array_set_size(array_field->fields, length);
- array_ft = (void *) field->type;
-
- for (i = cur_len; i < array_field->fields->len; i++) {
- struct bt_field *elem_field = bt_field_create(
- array_ft->element_ft);
-
- if (!elem_field) {
- BT_LIB_LOGE("Cannot create element field for "
- "dynamic array field: "
- "index=%" PRIu64 ", "
- "%![array-field-]+f", i, field);
- ret = -1;
- goto end;
- }
-
- BT_ASSERT(!array_field->fields->pdata[i]);
- array_field->fields->pdata[i] = elem_field;
- }
- }
-
- array_field->length = length;
-
-end:
- return ret;
-}
-
-struct bt_field *bt_field_array_borrow_element_field_by_index(
- struct bt_field *field, uint64_t index)
-{
- struct bt_field_array *array_field = (void *) field;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_FIELD_IS_ARRAY(field, "Field");
- BT_ASSERT_PRE_VALID_INDEX(index, array_field->length);
- return array_field->fields->pdata[index];
-}
-
-struct bt_field *bt_field_structure_borrow_member_field_by_index(
- struct bt_field *field, uint64_t index)
-{
- struct bt_field_structure *struct_field = (void *) field;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
- BT_FIELD_TYPE_ID_STRUCTURE, "Field");
- BT_ASSERT_PRE_VALID_INDEX(index, struct_field->fields->len);
- return struct_field->fields->pdata[index];
-}
-
-struct bt_field *bt_field_structure_borrow_member_field_by_name(
- struct bt_field *field, const char *name)
-{
- struct bt_field *ret_field = NULL;
- struct bt_field_type_structure *struct_ft;
- struct bt_field_structure *struct_field = (void *) field;
- gpointer orig_key;
- gpointer index;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_NON_NULL(name, "Field name");
- BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
- BT_FIELD_TYPE_ID_STRUCTURE, "Field");
- struct_ft = (void *) field->type;
-
- if (!g_hash_table_lookup_extended(struct_ft->common.name_to_index, name,
- &orig_key, &index)) {
- goto end;
- }
-
- ret_field = struct_field->fields->pdata[GPOINTER_TO_UINT(index)];
- BT_ASSERT(ret_field);
-
-end:
- return ret_field;
-}
-
-struct bt_field *bt_field_variant_borrow_selected_option_field(
- struct bt_field *field)
-{
- struct bt_field_variant *var_field = (void *) field;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
- BT_FIELD_TYPE_ID_VARIANT, "Field");
- BT_ASSERT_PRE(var_field->selected_field,
- "Variant field has no selected field: %!+f", field);
- return var_field->selected_field;
-}
-
-int bt_field_variant_select_option_field(struct bt_field *field,
- uint64_t index)
-{
- struct bt_field_variant *var_field = (void *) field;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
- BT_FIELD_TYPE_ID_VARIANT, "Field");
- BT_ASSERT_PRE_FIELD_HOT(field, "Field");
- BT_ASSERT_PRE_VALID_INDEX(index, var_field->fields->len);
- var_field->selected_field = var_field->fields->pdata[index];
- var_field->selected_index = index;
- return 0;
-}
-
-uint64_t bt_field_variant_get_selected_option_field_index(
- struct bt_field *field)
-{
- struct bt_field_variant *var_field = (void *) field;
-
- BT_ASSERT_PRE_NON_NULL(field, "Field");
- BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
- BT_FIELD_TYPE_ID_VARIANT, "Field");
- BT_ASSERT_PRE(var_field->selected_field,
- "Variant field has no selected field: %!+f", field);
- return var_field->selected_index;
-}
-
-static inline
-void bt_field_finalize(struct bt_field *field)
-{
- BT_ASSERT(field);
- BT_LOGD_STR("Putting field's type.");
- bt_put(field->type);
-}
-
-static
-void destroy_integer_field(struct bt_field *field)
-{
- BT_ASSERT(field);
- BT_LIB_LOGD("Destroying integer field object: %!+f", field);
- bt_field_finalize(field);
- g_free(field);
-}
-
-static
-void destroy_real_field(struct bt_field *field)
-{
- BT_ASSERT(field);
- BT_LIB_LOGD("Destroying real field object: %!+f", field);
- bt_field_finalize(field);
- g_free(field);
-}
-
-static
-void destroy_structure_field(struct bt_field *field)
-{
- struct bt_field_structure *struct_field = (void *) field;
-
- BT_ASSERT(field);
- BT_LIB_LOGD("Destroying structure field object: %!+f", field);
- bt_field_finalize(field);
-
- if (struct_field->fields) {
- g_ptr_array_free(struct_field->fields, TRUE);
- }
-
- g_free(field);
-}
-
-static
-void destroy_variant_field(struct bt_field *field)
-{
- struct bt_field_variant *var_field = (void *) field;
-
- BT_ASSERT(field);
- BT_LIB_LOGD("Destroying variant field object: %!+f", field);
- bt_field_finalize(field);
-
- if (var_field->fields) {
- g_ptr_array_free(var_field->fields, TRUE);
- }
-
- g_free(field);
-}
-
-static
-void destroy_array_field(struct bt_field *field)
-{
- struct bt_field_array *array_field = (void *) field;
-
- BT_ASSERT(field);
- BT_LIB_LOGD("Destroying array field object: %!+f", field);
- bt_field_finalize(field);
-
- if (array_field->fields) {
- g_ptr_array_free(array_field->fields, TRUE);
- }
-
- g_free(field);
-}
-
-static
-void destroy_string_field(struct bt_field *field)
-{
- struct bt_field_string *string_field = (void *) field;
-
- BT_ASSERT(field);
- BT_LIB_LOGD("Destroying string field object: %!+f", field);
- bt_field_finalize(field);
-
- if (string_field->buf) {
- g_array_free(string_field->buf, TRUE);
- }
-
- g_free(field);
-}
-
-BT_HIDDEN
-void bt_field_destroy(struct bt_field *field)
-{
- BT_ASSERT(field);
- BT_ASSERT(bt_field_type_has_known_id(field->type));
- field_destroy_funcs[field->type->id](field);
-}
-
-static
-void reset_single_field(struct bt_field *field)
-{
- BT_ASSERT(field);
- field->is_set = false;
-}
-
-static
-void reset_structure_field(struct bt_field *field)
-{
- uint64_t i;
- struct bt_field_structure *struct_field = (void *) field;
-
- BT_ASSERT(field);
-
- for (i = 0; i < struct_field->fields->len; i++) {
- bt_field_reset(struct_field->fields->pdata[i]);
- }
-}
-
-static
-void reset_variant_field(struct bt_field *field)
-{
- uint64_t i;
- struct bt_field_variant *var_field = (void *) field;
-
- BT_ASSERT(field);
-
- for (i = 0; i < var_field->fields->len; i++) {
- bt_field_reset(var_field->fields->pdata[i]);
- }
-}
-
-static
-void reset_array_field(struct bt_field *field)
-{
- uint64_t i;
- struct bt_field_array *array_field = (void *) field;
-
- BT_ASSERT(field);
-
- for (i = 0; i < array_field->fields->len; i++) {
- bt_field_reset(array_field->fields->pdata[i]);
- }
-}
-
-static
-void set_single_field_is_frozen(struct bt_field *field, bool is_frozen)
-{
- field->frozen = is_frozen;
-}
-
-static
-void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen)
-{
- uint64_t i;
- struct bt_field_structure *struct_field = (void *) field;
-
- BT_LIB_LOGD("Setting structure field's frozen state: "
- "%![field-]+f, is-frozen=%d", field, is_frozen);
-
- for (i = 0; i < struct_field->fields->len; i++) {
- struct bt_field *member_field = struct_field->fields->pdata[i];
-
- BT_LIB_LOGD("Setting structure field's member field's "
- "frozen state: %![field-]+f, index=%" PRIu64,
- member_field, i);
- bt_field_set_is_frozen(member_field, is_frozen);
- }
-
- set_single_field_is_frozen(field, is_frozen);
-}
-
-static
-void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen)
-{
- uint64_t i;
- struct bt_field_variant *var_field = (void *) field;
-
- BT_LIB_LOGD("Setting variant field's frozen state: "
- "%![field-]+f, is-frozen=%d", field, is_frozen);
-
- for (i = 0; i < var_field->fields->len; i++) {
- struct bt_field *option_field = var_field->fields->pdata[i];
-
- BT_LIB_LOGD("Setting variant field's option field's "
- "frozen state: %![field-]+f, index=%" PRIu64,
- option_field, i);
- bt_field_set_is_frozen(option_field, is_frozen);
- }
-
- set_single_field_is_frozen(field, is_frozen);
-}
-
-static
-void set_array_field_is_frozen(struct bt_field *field, bool is_frozen)
-{
- uint64_t i;
- struct bt_field_array *array_field = (void *) field;
-
- BT_LIB_LOGD("Setting array field's frozen state: "
- "%![field-]+f, is-frozen=%d", field, is_frozen);
-
- for (i = 0; i < array_field->fields->len; i++) {
- struct bt_field *elem_field = array_field->fields->pdata[i];
-
- BT_LIB_LOGD("Setting array field's element field's "
- "frozen state: %![field-]+f, index=%" PRIu64,
- elem_field, i);
- bt_field_set_is_frozen(elem_field, is_frozen);
- }
-
- set_single_field_is_frozen(field, is_frozen);
-}
-
-BT_HIDDEN
-void _bt_field_set_is_frozen(struct bt_field *field,
- bool is_frozen)
-{
- BT_ASSERT(field);
- BT_LIB_LOGD("Setting field object's frozen state: %!+f, is-frozen=%d",
- field, is_frozen);
- BT_ASSERT(field->methods->set_is_frozen);
- field->methods->set_is_frozen(field, is_frozen);
-}
-
-static
-bool single_field_is_set(struct bt_field *field)
-{
- BT_ASSERT(field);
- return field->is_set;
-}
-
-static
-bool structure_field_is_set(struct bt_field *field)
-{
- bool is_set = true;
- uint64_t i;
- struct bt_field_structure *struct_field = (void *) field;
-
- BT_ASSERT(field);
-
- for (i = 0; i < struct_field->fields->len; i++) {
- is_set = bt_field_is_set(struct_field->fields->pdata[i]);
- if (!is_set) {
- goto end;
- }
- }
-
-end:
- return is_set;
-}
-
-static
-bool variant_field_is_set(struct bt_field *field)
-{
- struct bt_field_variant *var_field = (void *) field;
- bool is_set = false;
-
- BT_ASSERT(field);
-
- if (var_field->selected_field) {
- is_set = bt_field_is_set(var_field->selected_field);
- }
-
- return is_set;
-}
-
-static
-bool array_field_is_set(struct bt_field *field)
-{
- bool is_set = true;
- uint64_t i;
- struct bt_field_array *array_field = (void *) field;
-
- BT_ASSERT(field);
-
- for (i = 0; i < array_field->length; i++) {
- is_set = bt_field_is_set(array_field->fields->pdata[i]);
- if (!is_set) {
- goto end;
- }
- }
-
-end:
- return is_set;
-}
+++ /dev/null
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "PACKET-CONTEXT-FIELD"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/packet-context-field.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/field-wrapper-internal.h>
-#include <glib.h>
-
-struct bt_field *bt_packet_context_field_borrow_field(
- struct bt_packet_context_field *context_field)
-{
- struct bt_field_wrapper *field_wrapper = (void *) context_field;
-
- BT_ASSERT_PRE_NON_NULL(field_wrapper, "Packet context field");
- return field_wrapper->field;
-}
-
-void bt_packet_context_field_release(struct bt_packet_context_field *context_field)
-{
- struct bt_field_wrapper *field_wrapper = (void *) context_field;
-
- BT_ASSERT_PRE_NON_NULL(field_wrapper, "Packet context field");
-
- /*
- * Do not recycle because the pool could be destroyed at this
- * point. This function is only called when there's an error
- * anyway because the goal of a packet context field wrapper is
- * to eventually move it to a packet with
- * bt_packet_move_context() after creating it.
- */
- bt_field_wrapper_destroy(field_wrapper);
-}
-
-struct bt_packet_context_field *bt_packet_context_field_create(
- struct bt_stream_class *stream_class)
-{
- struct bt_field_wrapper *field_wrapper;
-
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- BT_ASSERT_PRE(stream_class->frozen,
- "Stream class is not part of a trace: %!+S", stream_class);
- BT_ASSERT_PRE(stream_class->packet_context_ft,
- "Stream class has no packet context field type: %!+S",
- stream_class);
- field_wrapper = bt_field_wrapper_create(
- &stream_class->packet_context_field_pool,
- (void *) stream_class->packet_context_ft);
- if (!field_wrapper) {
- BT_LIB_LOGE("Cannot allocate one packet context field from stream class: "
- "%![sc-]+S", stream_class);
- goto error;
- }
-
- BT_ASSERT(field_wrapper->field);
- bt_stream_class_freeze(stream_class);
- goto end;
-
-error:
- if (field_wrapper) {
- bt_field_wrapper_destroy(field_wrapper);
- field_wrapper = NULL;
- }
-
-end:
- return (void *) field_wrapper;
-}
+++ /dev/null
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "PACKET-HEADER-FIELD"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/ctf-ir/packet-header-field.h>
-#include <babeltrace/ctf-ir/field-wrapper-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <glib.h>
-
-struct bt_field *bt_packet_header_field_borrow_field(
- struct bt_packet_header_field *header_field)
-{
- struct bt_field_wrapper *field_wrapper = (void *) header_field;
-
- BT_ASSERT_PRE_NON_NULL(field_wrapper, "Packet header field");
- return (void *) field_wrapper->field;
-}
-
-void bt_packet_header_field_release(struct bt_packet_header_field *header_field)
-{
- struct bt_field_wrapper *field_wrapper = (void *) header_field;
-
- BT_ASSERT_PRE_NON_NULL(field_wrapper, "Packet header field");
-
- /*
- * Do not recycle because the pool could be destroyed at this
- * point. This function is only called when there's an error
- * anyway because the goal of a packet header field wrapper is
- * to eventually move it to a packet with
- * bt_packet_move_header() after creating it.
- */
- bt_field_wrapper_destroy(field_wrapper);
-}
-
-struct bt_packet_header_field *bt_packet_header_field_create(
- struct bt_trace *trace)
-{
- struct bt_field_wrapper *field_wrapper;
-
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- BT_ASSERT_PRE(trace->packet_header_ft,
- "Trace has no packet header field type: %!+t", trace);
- field_wrapper = bt_field_wrapper_create(
- &trace->packet_header_field_pool,
- (void *) trace->packet_header_ft);
- if (!field_wrapper) {
- BT_LIB_LOGE("Cannot allocate one packet header field from trace: "
- "%![trace-]+t", trace);
- goto error;
- }
-
- BT_ASSERT(field_wrapper->field);
- bt_trace_freeze(trace);
- goto end;
-
-error:
- if (field_wrapper) {
- bt_field_wrapper_destroy(field_wrapper);
- field_wrapper = NULL;
- }
-
-end:
- return (void *) field_wrapper;
-}
+++ /dev/null
-/*
- * packet.c
- *
- * Babeltrace CTF IR - Stream packet
- *
- * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "PACKET"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/packet.h>
-#include <babeltrace/ctf-ir/packet-internal.h>
-#include <babeltrace/ctf-ir/field-wrapper-internal.h>
-#include <babeltrace/ctf-ir/trace.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/assert-internal.h>
-#include <inttypes.h>
-
-#define BT_ASSERT_PRE_PACKET_HOT(_packet) \
- BT_ASSERT_PRE_HOT((_packet), "Packet", ": %!+a", (_packet))
-
-struct bt_stream *bt_packet_borrow_stream(struct bt_packet *packet)
-{
- BT_ASSERT_PRE_NON_NULL(packet, "Packet");
- return packet->stream;
-}
-
-struct bt_field *bt_packet_borrow_header_field(struct bt_packet *packet)
-{
- BT_ASSERT_PRE_NON_NULL(packet, "Packet");
- return packet->header_field ? packet->header_field->field : NULL;
-}
-
-struct bt_field *bt_packet_borrow_context_field(struct bt_packet *packet)
-{
- BT_ASSERT_PRE_NON_NULL(packet, "Packet");
- return packet->context_field ? packet->context_field->field : NULL;
-}
-
-BT_HIDDEN
-void _bt_packet_set_is_frozen(struct bt_packet *packet, bool is_frozen)
-{
- if (!packet) {
- return;
- }
-
- BT_LIB_LOGD("Setting packet's frozen state: %![packet-]+a, "
- "is-frozen=%d", packet, is_frozen);
-
- if (packet->header_field) {
- BT_LOGD_STR("Setting packet's header field's frozen state.");
- bt_field_set_is_frozen(packet->header_field->field,
- is_frozen);
- }
-
- if (packet->context_field) {
- BT_LOGD_STR("Setting packet's context field's frozen state.");
- bt_field_set_is_frozen(packet->context_field->field,
- is_frozen);
- }
-
- packet->frozen = is_frozen;
-}
-
-static inline
-void reset_counter_snapshots(struct bt_packet *packet)
-{
- packet->discarded_event_counter_snapshot.base.avail =
- BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE;
- packet->packet_counter_snapshot.base.avail =
- BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE;
-}
-
-static inline
-void reset_packet(struct bt_packet *packet)
-{
- BT_ASSERT(packet);
- BT_LIB_LOGD("Resetting packet: %!+a", packet);
- bt_packet_set_is_frozen(packet, false);
-
- if (packet->header_field) {
- bt_field_set_is_frozen(packet->header_field->field, false);
- bt_field_reset(packet->header_field->field);
- }
-
- if (packet->context_field) {
- bt_field_set_is_frozen(packet->context_field->field, false);
- bt_field_reset(packet->context_field->field);
- }
-
- if (packet->default_beginning_cv) {
- bt_clock_value_reset(packet->default_beginning_cv);
- }
-
- if (packet->default_end_cv) {
- bt_clock_value_reset(packet->default_end_cv);
- }
-
- reset_counter_snapshots(packet);
-}
-
-static
-void recycle_header_field(struct bt_field_wrapper *header_field,
- struct bt_trace *trace)
-{
- BT_ASSERT(header_field);
- BT_LIB_LOGD("Recycling packet header field: "
- "addr=%p, %![trace-]+t, %![field-]+f", header_field,
- trace, header_field->field);
- bt_object_pool_recycle_object(&trace->packet_header_field_pool,
- header_field);
-}
-
-static
-void recycle_context_field(struct bt_field_wrapper *context_field,
- struct bt_stream_class *stream_class)
-{
- BT_ASSERT(context_field);
- BT_LIB_LOGD("Recycling packet context field: "
- "addr=%p, %![sc-]+S, %![field-]+f", context_field,
- stream_class, context_field->field);
- bt_object_pool_recycle_object(&stream_class->packet_context_field_pool,
- context_field);
-}
-
-BT_HIDDEN
-void bt_packet_recycle(struct bt_packet *packet)
-{
- struct bt_stream *stream;
-
- BT_ASSERT(packet);
- BT_LIB_LOGD("Recycling packet: %!+a", packet);
-
- /*
- * Those are the important ordered steps:
- *
- * 1. Reset the packet object (put any permanent reference it
- * has, unfreeze it and its fields in developer mode, etc.),
- * but do NOT put its stream's reference. This stream
- * contains the pool to which we're about to recycle this
- * packet object, so we must guarantee its existence thanks
- * to this existing reference.
- *
- * 2. Move the stream reference to our `stream`
- * variable so that we can set the packet's stream member
- * to NULL before recycling it. We CANNOT do this after
- * we put the stream reference because this bt_put()
- * could destroy the stream, also destroying its
- * packet pool, thus also destroying our packet object (this
- * would result in an invalid write access).
- *
- * 3. Recycle the packet object.
- *
- * 4. Put our stream reference.
- */
- reset_packet(packet);
- stream = packet->stream;
- BT_ASSERT(stream);
- packet->stream = NULL;
- bt_object_pool_recycle_object(&stream->packet_pool, packet);
- bt_object_put_no_null_check(&stream->base);
-}
-
-BT_HIDDEN
-void bt_packet_destroy(struct bt_packet *packet)
-{
- BT_LIB_LOGD("Destroying packet: %!+a", packet);
-
- if (packet->header_field) {
- if (packet->stream) {
- BT_LOGD_STR("Recycling packet's header field.");
- recycle_header_field(packet->header_field,
- bt_stream_class_borrow_trace_inline(
- packet->stream->class));
- } else {
- bt_field_wrapper_destroy(packet->header_field);
- }
- }
-
- if (packet->context_field) {
- if (packet->stream) {
- BT_LOGD_STR("Recycling packet's context field.");
- recycle_context_field(packet->context_field,
- packet->stream->class);
- } else {
- bt_field_wrapper_destroy(packet->context_field);
- }
- }
-
- if (packet->default_beginning_cv) {
- BT_LOGD_STR("Recycling beginning clock value.");
- bt_clock_value_recycle(packet->default_beginning_cv);
- }
-
- if (packet->default_end_cv) {
- BT_LOGD_STR("Recycling end clock value.");
- bt_clock_value_recycle(packet->default_end_cv);
- }
-
- BT_LOGD_STR("Putting packet's stream.");
- bt_put(packet->stream);
- g_free(packet);
-}
-
-BT_HIDDEN
-struct bt_packet *bt_packet_new(struct bt_stream *stream)
-{
- struct bt_packet *packet = NULL;
- struct bt_trace *trace = NULL;
-
- BT_ASSERT(stream);
- BT_LIB_LOGD("Creating packet object: %![stream-]+s", stream);
- packet = g_new0(struct bt_packet, 1);
- if (!packet) {
- BT_LOGE_STR("Failed to allocate one packet object.");
- goto error;
- }
-
- bt_object_init_shared(&packet->base,
- (bt_object_release_func) bt_packet_recycle);
- packet->stream = bt_get(stream);
- trace = bt_stream_class_borrow_trace_inline(stream->class);
- BT_ASSERT(trace);
-
- if (trace->packet_header_ft) {
- BT_LOGD_STR("Creating initial packet header field.");
- packet->header_field = bt_field_wrapper_create(
- &trace->packet_header_field_pool,
- trace->packet_header_ft);
- if (!packet->header_field) {
- BT_LOGE_STR("Cannot create packet header field wrapper.");
- goto error;
- }
- }
-
- if (stream->class->packet_context_ft) {
- BT_LOGD_STR("Creating initial packet context field.");
- packet->context_field = bt_field_wrapper_create(
- &stream->class->packet_context_field_pool,
- stream->class->packet_context_ft);
- if (!packet->context_field) {
- BT_LOGE_STR("Cannot create packet context field wrapper.");
- goto error;
- }
- }
-
- if (stream->class->default_clock_class) {
- if (stream->class->packets_have_default_beginning_cv) {
- packet->default_beginning_cv = bt_clock_value_create(
- stream->class->default_clock_class);
- if (!packet->default_beginning_cv) {
- /* bt_clock_value_create() logs errors */
- goto error;
- }
- }
-
- if (stream->class->packets_have_default_end_cv) {
- packet->default_end_cv = bt_clock_value_create(
- stream->class->default_clock_class);
- if (!packet->default_end_cv) {
- /* bt_clock_value_create() logs errors */
- goto error;
- }
- }
- }
-
- reset_counter_snapshots(packet);
- BT_LIB_LOGD("Created packet object: %!+a", packet);
- goto end;
-
-error:
- BT_PUT(packet);
-
-end:
- return packet;
-}
-
-struct bt_packet *bt_packet_create(struct bt_stream *stream)
-{
- struct bt_packet *packet = NULL;
-
- BT_ASSERT_PRE_NON_NULL(stream, "Stream");
- packet = bt_object_pool_create_object(&stream->packet_pool);
- if (unlikely(!packet)) {
- BT_LIB_LOGE("Cannot allocate one packet from stream's packet pool: "
- "%![stream-]+s", stream);
- goto end;
- }
-
- if (likely(!packet->stream)) {
- packet->stream = stream;
- bt_object_get_no_null_check_no_parent_check(
- &packet->stream->base);
- }
-
-end:
- return packet;
-}
-
-int bt_packet_move_header_field(struct bt_packet *packet,
- struct bt_packet_header_field *header_field)
-{
- struct bt_trace *trace;
- struct bt_field_wrapper *field_wrapper = (void *) header_field;
-
- BT_ASSERT_PRE_NON_NULL(packet, "Packet");
- BT_ASSERT_PRE_NON_NULL(field_wrapper, "Header field");
- BT_ASSERT_PRE_PACKET_HOT(packet);
- trace = bt_stream_class_borrow_trace_inline(packet->stream->class);
- BT_ASSERT_PRE(trace->packet_header_ft,
- "Trace has no packet header field type: %!+t",
- trace);
- BT_ASSERT_PRE(field_wrapper->field->type ==
- trace->packet_header_ft,
- "Unexpected packet header field's type: "
- "%![ft-]+F, %![expected-ft-]+F", field_wrapper->field->type,
- trace->packet_header_ft);
-
- /* Recycle current header field: always exists */
- BT_ASSERT(packet->header_field);
- recycle_header_field(packet->header_field, trace);
-
- /* Move new field */
- packet->header_field = field_wrapper;
- return 0;
-}
-
-int bt_packet_move_context_field(struct bt_packet *packet,
- struct bt_packet_context_field *context_field)
-{
- struct bt_stream_class *stream_class;
- struct bt_field_wrapper *field_wrapper = (void *) context_field;
-
- BT_ASSERT_PRE_NON_NULL(packet, "Packet");
- BT_ASSERT_PRE_NON_NULL(field_wrapper, "Context field");
- BT_ASSERT_PRE_HOT(packet, "Packet", ": %!+a", packet);
- stream_class = packet->stream->class;
- BT_ASSERT_PRE(stream_class->packet_context_ft,
- "Stream class has no packet context field type: %!+S",
- stream_class);
- BT_ASSERT_PRE(field_wrapper->field->type ==
- stream_class->packet_context_ft,
- "Unexpected packet header field's type: "
- "%![ft-]+F, %![expected-ft-]+F", field_wrapper->field->type,
- stream_class->packet_context_ft);
-
- /* Recycle current context field: always exists */
- BT_ASSERT(packet->context_field);
- recycle_context_field(packet->context_field, stream_class);
-
- /* Move new field */
- packet->context_field = field_wrapper;
- return 0;
-}
-
-int bt_packet_set_default_beginning_clock_value(struct bt_packet *packet,
- uint64_t value_cycles)
-{
- struct bt_stream_class *sc;
-
- BT_ASSERT_PRE_NON_NULL(packet, "Packet");
- BT_ASSERT_PRE_PACKET_HOT(packet);
- sc = packet->stream->class;
- BT_ASSERT(sc);
- BT_ASSERT_PRE(sc->default_clock_class,
- "Packet's stream class has no default clock class: "
- "%![packet-]+a, %![sc-]+S", packet, sc);
- BT_ASSERT_PRE(sc->packets_have_default_beginning_cv,
- "Packet's stream class indicates that its packets have "
- "no default beginning clock value: %![packet-]+a, %![sc-]+S",
- packet, sc);
- BT_ASSERT(packet->default_beginning_cv);
- bt_clock_value_set_value_inline(packet->default_beginning_cv, value_cycles);
- BT_LIB_LOGV("Set packet's default beginning clock value: "
- "%![packet-]+a, value=%" PRIu64, value_cycles);
- return 0;
-}
-
-enum bt_clock_value_status bt_packet_borrow_default_beginning_clock_value(
- struct bt_packet *packet, struct bt_clock_value **clock_value)
-{
- BT_ASSERT_PRE_NON_NULL(packet, "Packet");
- BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value (output)");
- *clock_value = packet->default_beginning_cv;
- return BT_CLOCK_VALUE_STATUS_KNOWN;
-}
-
-int bt_packet_set_default_end_clock_value(struct bt_packet *packet,
- uint64_t value_cycles)
-{
- struct bt_stream_class *sc;
-
- BT_ASSERT_PRE_NON_NULL(packet, "Packet");
- BT_ASSERT_PRE_PACKET_HOT(packet);
- sc = packet->stream->class;
- BT_ASSERT(sc);
- BT_ASSERT_PRE(sc->default_clock_class,
- "Packet's stream class has no default clock class: "
- "%![packet-]+a, %![sc-]+S", packet, sc);
- BT_ASSERT_PRE(sc->packets_have_default_end_cv,
- "Packet's stream class indicates that its packets have "
- "no default end clock value: %![packet-]+a, %![sc-]+S",
- packet, sc);
- BT_ASSERT(packet->default_end_cv);
- bt_clock_value_set_value_inline(packet->default_end_cv, value_cycles);
- BT_LIB_LOGV("Set packet's default end clock value: "
- "%![packet-]+a, value=%" PRIu64, value_cycles);
- return 0;
-}
-
-enum bt_clock_value_status bt_packet_borrow_default_end_clock_value(
- struct bt_packet *packet, struct bt_clock_value **clock_value)
-{
- BT_ASSERT_PRE_NON_NULL(packet, "Packet");
- BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value (output)");
- *clock_value = packet->default_end_cv;
- return BT_CLOCK_VALUE_STATUS_KNOWN;
-}
-
-enum bt_property_availability bt_packet_get_discarded_event_counter_snapshot(
- struct bt_packet *packet, uint64_t *value)
-{
- BT_ASSERT_PRE_NON_NULL(packet, "Packet");
- BT_ASSERT_PRE_NON_NULL(value, "Value (output)");
- *value = packet->discarded_event_counter_snapshot.value;
- return packet->discarded_event_counter_snapshot.base.avail;
-}
-
-int bt_packet_set_discarded_event_counter_snapshot(struct bt_packet *packet,
- uint64_t value)
-{
- BT_ASSERT_PRE_NON_NULL(packet, "Packet");
- BT_ASSERT_PRE_PACKET_HOT(packet);
- BT_ASSERT_PRE(packet->stream->class->packets_have_discarded_event_counter_snapshot,
- "Packet's stream's discarded event counter is not enabled: "
- "%![packet-]+a", packet);
- bt_property_uint_set(&packet->discarded_event_counter_snapshot, value);
- return 0;
-}
-
-enum bt_property_availability bt_packet_get_packet_counter_snapshot(
- struct bt_packet *packet, uint64_t *value)
-{
- BT_ASSERT_PRE_NON_NULL(packet, "Packet");
- BT_ASSERT_PRE_NON_NULL(value, "Value (output)");
- *value = packet->packet_counter_snapshot.value;
- return packet->packet_counter_snapshot.base.avail;
-}
-
-int bt_packet_set_packet_counter_snapshot(struct bt_packet *packet,
- uint64_t value)
-{
- BT_ASSERT_PRE_NON_NULL(packet, "Packet");
- BT_ASSERT_PRE_PACKET_HOT(packet);
- BT_ASSERT_PRE(packet->stream->class->packets_have_packet_counter_snapshot,
- "Packet's stream's packet counter is not enabled: "
- "%![packet-]+a", packet);
- bt_property_uint_set(&packet->packet_counter_snapshot, value);
- return 0;
-}
+++ /dev/null
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "RESOLVE-FIELD-PATH"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/field-path-internal.h>
-#include <babeltrace/ctf-ir/field-path.h>
-#include <babeltrace/ctf-ir/resolve-field-path-internal.h>
-#include <limits.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <glib.h>
-
-static
-bool find_field_type_recursive(struct bt_field_type *ft,
- struct bt_field_type *tgt_ft, struct bt_field_path *field_path)
-{
- bool found = false;
-
- if (tgt_ft == ft) {
- found = true;
- goto end;
- }
-
- switch (ft->id) {
- case BT_FIELD_TYPE_ID_STRUCTURE:
- case BT_FIELD_TYPE_ID_VARIANT:
- {
- struct bt_field_type_named_field_types_container *container_ft =
- (void *) ft;
- uint64_t i;
-
- for (i = 0; i < container_ft->named_fts->len; i++) {
- struct bt_named_field_type *named_ft =
- BT_FIELD_TYPE_NAMED_FT_AT_INDEX(
- container_ft, i);
-
- g_array_append_val(field_path->indexes, i);
- found = find_field_type_recursive(named_ft->ft,
- tgt_ft, field_path);
- if (found) {
- goto end;
- }
-
- g_array_set_size(field_path->indexes,
- field_path->indexes->len - 1);
- }
-
- break;
- }
- case BT_FIELD_TYPE_ID_STATIC_ARRAY:
- case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
- {
- struct bt_field_type_array *array_ft = (void *) ft;
-
- found = find_field_type_recursive(array_ft->element_ft,
- tgt_ft, field_path);
- break;
- }
- default:
- break;
- }
-
-end:
- return found;
-}
-
-static
-int find_field_type(struct bt_field_type *root_ft,
- enum bt_scope root_scope, struct bt_field_type *tgt_ft,
- struct bt_field_path **ret_field_path)
-{
- int ret = 0;
- struct bt_field_path *field_path = NULL;
-
- if (!root_ft) {
- goto end;
- }
-
- field_path = bt_field_path_create();
- if (!field_path) {
- ret = -1;
- goto end;
- }
-
- field_path->root = root_scope;
- if (!find_field_type_recursive(root_ft, tgt_ft, field_path)) {
- /* Not found here */
- BT_PUT(field_path);
- }
-
-end:
- *ret_field_path = field_path;
- return ret;
-}
-
-static
-struct bt_field_path *find_field_type_in_ctx(struct bt_field_type *ft,
- struct bt_resolve_field_path_context *ctx)
-{
- struct bt_field_path *field_path = NULL;
- int ret;
-
- ret = find_field_type(ctx->packet_header, BT_SCOPE_PACKET_HEADER,
- ft, &field_path);
- if (ret || field_path) {
- goto end;
- }
-
- ret = find_field_type(ctx->packet_context, BT_SCOPE_PACKET_CONTEXT,
- ft, &field_path);
- if (ret || field_path) {
- goto end;
- }
-
- ret = find_field_type(ctx->event_header, BT_SCOPE_EVENT_HEADER,
- ft, &field_path);
- if (ret || field_path) {
- goto end;
- }
-
- ret = find_field_type(ctx->event_common_context,
- BT_SCOPE_EVENT_COMMON_CONTEXT, ft, &field_path);
- if (ret || field_path) {
- goto end;
- }
-
- ret = find_field_type(ctx->event_specific_context,
- BT_SCOPE_EVENT_SPECIFIC_CONTEXT, ft, &field_path);
- if (ret || field_path) {
- goto end;
- }
-
- ret = find_field_type(ctx->event_payload, BT_SCOPE_EVENT_PAYLOAD,
- ft, &field_path);
- if (ret || field_path) {
- goto end;
- }
-
-end:
- return field_path;
-}
-
-BT_ASSERT_PRE_FUNC
-static inline
-bool target_is_before_source(struct bt_field_path *src_field_path,
- struct bt_field_path *tgt_field_path)
-{
- bool is_valid = true;
- uint64_t src_i = 0, tgt_i = 0;
-
- if (tgt_field_path->root < src_field_path->root) {
- goto end;
- }
-
- if (tgt_field_path->root > src_field_path->root) {
- is_valid = false;
- goto end;
- }
-
- BT_ASSERT(tgt_field_path->root == src_field_path->root);
-
- while (src_i < src_field_path->indexes->len &&
- tgt_i < tgt_field_path->indexes->len) {
- uint64_t src_index = bt_field_path_get_index_by_index_inline(
- src_field_path, src_i);
- uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
- tgt_field_path, tgt_i);
-
- if (tgt_index > src_index) {
- is_valid = false;
- goto end;
- }
-
- src_i++;
- tgt_i++;
- }
-
-end:
- return is_valid;
-}
-
-BT_ASSERT_PRE_FUNC
-static inline
-struct bt_field_type *borrow_root_field_type(
- struct bt_resolve_field_path_context *ctx, enum bt_scope scope)
-{
- switch (scope) {
- case BT_SCOPE_PACKET_HEADER:
- return ctx->packet_header;
- case BT_SCOPE_PACKET_CONTEXT:
- return ctx->packet_context;
- case BT_SCOPE_EVENT_HEADER:
- return ctx->event_header;
- case BT_SCOPE_EVENT_COMMON_CONTEXT:
- return ctx->event_common_context;
- case BT_SCOPE_EVENT_SPECIFIC_CONTEXT:
- return ctx->event_specific_context;
- case BT_SCOPE_EVENT_PAYLOAD:
- return ctx->event_payload;
- default:
- abort();
- }
-
- return NULL;
-}
-
-BT_ASSERT_PRE_FUNC
-static inline
-struct bt_field_type *borrow_child_field_type(struct bt_field_type *parent_ft,
- uint64_t index, bool *advance)
-{
- struct bt_field_type *child_ft = NULL;
-
- switch (parent_ft->id) {
- case BT_FIELD_TYPE_ID_STRUCTURE:
- case BT_FIELD_TYPE_ID_VARIANT:
- {
- struct bt_named_field_type *named_ft =
- BT_FIELD_TYPE_NAMED_FT_AT_INDEX(parent_ft, index);
-
- child_ft = named_ft->ft;
- *advance = true;
- break;
- }
- case BT_FIELD_TYPE_ID_STATIC_ARRAY:
- case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
- {
- struct bt_field_type_array *array_ft = (void *) parent_ft;
-
- child_ft = array_ft->element_ft;
- *advance = false;
- break;
- }
- default:
- break;
- }
-
- return child_ft;
-}
-
-BT_ASSERT_PRE_FUNC
-static inline
-bool target_field_path_in_different_scope_has_struct_ft_only(
- struct bt_field_path *src_field_path,
- struct bt_field_path *tgt_field_path,
- struct bt_resolve_field_path_context *ctx)
-{
- bool is_valid = true;
- uint64_t i = 0;
- struct bt_field_type *ft;
-
- if (src_field_path->root == tgt_field_path->root) {
- goto end;
- }
-
- ft = borrow_root_field_type(ctx, tgt_field_path->root);
-
- while (i < tgt_field_path->indexes->len) {
- uint64_t index = bt_field_path_get_index_by_index_inline(
- tgt_field_path, i);
- bool advance;
-
- if (ft->id == BT_FIELD_TYPE_ID_STATIC_ARRAY ||
- ft->id == BT_FIELD_TYPE_ID_DYNAMIC_ARRAY ||
- ft->id == BT_FIELD_TYPE_ID_VARIANT) {
- is_valid = false;
- goto end;
- }
-
- ft = borrow_child_field_type(ft, index, &advance);
-
- if (advance) {
- i++;
- }
- }
-
-end:
- return is_valid;
-}
-
-BT_ASSERT_PRE_FUNC
-static inline
-bool lca_is_structure_field_type(struct bt_field_path *src_field_path,
- struct bt_field_path *tgt_field_path,
- struct bt_resolve_field_path_context *ctx)
-{
- bool is_valid = true;
- struct bt_field_type *src_ft;
- struct bt_field_type *tgt_ft;
- struct bt_field_type *prev_ft = NULL;
- uint64_t src_i = 0, tgt_i = 0;
-
- if (src_field_path->root != tgt_field_path->root) {
- goto end;
- }
-
- src_ft = borrow_root_field_type(ctx, src_field_path->root);
- tgt_ft = borrow_root_field_type(ctx, tgt_field_path->root);
- BT_ASSERT(src_ft);
- BT_ASSERT(tgt_ft);
-
- while (src_i < src_field_path->indexes->len &&
- tgt_i < tgt_field_path->indexes->len) {
- bool advance;
- uint64_t src_index = bt_field_path_get_index_by_index_inline(
- src_field_path, src_i);
- uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
- tgt_field_path, tgt_i);
-
- if (src_ft != tgt_ft) {
- if (!prev_ft) {
- /*
- * This is correct: the LCA is the root
- * scope field type, which must be a
- * structure field type.
- */
- break;
- }
-
- if (prev_ft->id != BT_FIELD_TYPE_ID_STRUCTURE) {
- is_valid = false;
- }
-
- break;
- }
-
- prev_ft = src_ft;
- src_ft = borrow_child_field_type(src_ft, src_index, &advance);
-
- if (advance) {
- src_i++;
- }
-
- tgt_ft = borrow_child_field_type(tgt_ft, tgt_index, &advance);
-
- if (advance) {
- tgt_i++;
- }
- }
-
-end:
- return is_valid;
-}
-
-BT_ASSERT_PRE_FUNC
-static inline
-bool lca_to_target_has_struct_ft_only(struct bt_field_path *src_field_path,
- struct bt_field_path *tgt_field_path,
- struct bt_resolve_field_path_context *ctx)
-{
- bool is_valid = true;
- struct bt_field_type *src_ft;
- struct bt_field_type *tgt_ft;
- uint64_t src_i = 0, tgt_i = 0;
-
- if (src_field_path->root != tgt_field_path->root) {
- goto end;
- }
-
- src_ft = borrow_root_field_type(ctx, src_field_path->root);
- tgt_ft = borrow_root_field_type(ctx, tgt_field_path->root);
- BT_ASSERT(src_ft);
- BT_ASSERT(tgt_ft);
- BT_ASSERT(src_ft == tgt_ft);
-
- /* Find LCA */
- while (src_i < src_field_path->indexes->len &&
- tgt_i < tgt_field_path->indexes->len) {
- bool advance;
- uint64_t src_index = bt_field_path_get_index_by_index_inline(
- src_field_path, src_i);
- uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
- tgt_field_path, tgt_i);
-
- if (src_i != tgt_i) {
- /* Next FT is different: LCA is `tgt_ft` */
- break;
- }
-
- src_ft = borrow_child_field_type(src_ft, src_index, &advance);
-
- if (advance) {
- src_i++;
- }
-
- tgt_ft = borrow_child_field_type(tgt_ft, tgt_index, &advance);
-
- if (advance) {
- tgt_i++;
- }
- }
-
- /* Only structure field types to the target */
- while (tgt_i < tgt_field_path->indexes->len) {
- bool advance;
- uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
- tgt_field_path, tgt_i);
-
- if (tgt_ft->id == BT_FIELD_TYPE_ID_STATIC_ARRAY ||
- tgt_ft->id == BT_FIELD_TYPE_ID_DYNAMIC_ARRAY ||
- tgt_ft->id == BT_FIELD_TYPE_ID_VARIANT) {
- is_valid = false;
- goto end;
- }
-
- tgt_ft = borrow_child_field_type(tgt_ft, tgt_index, &advance);
-
- if (advance) {
- tgt_i++;
- }
- }
-
-end:
- return is_valid;
-}
-
-BT_ASSERT_PRE_FUNC
-static inline
-bool field_path_is_valid(struct bt_field_type *src_ft,
- struct bt_field_type *tgt_ft,
- struct bt_resolve_field_path_context *ctx)
-{
- bool is_valid = true;
- struct bt_field_path *src_field_path = find_field_type_in_ctx(
- src_ft, ctx);
- struct bt_field_path *tgt_field_path = find_field_type_in_ctx(
- tgt_ft, ctx);
-
- if (!src_field_path) {
- BT_ASSERT_PRE_MSG("Cannot find requesting field type in "
- "resolving context: %!+F", src_ft);
- is_valid = false;
- goto end;
- }
-
- if (!tgt_field_path) {
- BT_ASSERT_PRE_MSG("Cannot find target field type in "
- "resolving context: %!+F", tgt_ft);
- is_valid = false;
- goto end;
- }
-
- /* Target must be before source */
- if (!target_is_before_source(src_field_path, tgt_field_path)) {
- BT_ASSERT_PRE_MSG("Target field type is located after "
- "requesting field type: %![req-ft-]+F, %![tgt-ft-]+F",
- src_ft, tgt_ft);
- is_valid = false;
- goto end;
- }
-
- /*
- * If target is in a different scope than source, there are no
- * array or variant field types on the way to the target.
- */
- if (!target_field_path_in_different_scope_has_struct_ft_only(
- src_field_path, tgt_field_path, ctx)) {
- BT_ASSERT_PRE_MSG("Target field type is located in a "
- "different scope than requesting field type, "
- "but within an array or a variant field type: "
- "%![req-ft-]+F, %![tgt-ft-]+F",
- src_ft, tgt_ft);
- is_valid = false;
- goto end;
- }
-
- /* Same scope: LCA must be a structure field type */
- if (!lca_is_structure_field_type(src_field_path, tgt_field_path, ctx)) {
- BT_ASSERT_PRE_MSG("Lowest common ancestor of target and "
- "requesting field types is not a structure field type: "
- "%![req-ft-]+F, %![tgt-ft-]+F",
- src_ft, tgt_ft);
- is_valid = false;
- goto end;
- }
-
- /* Same scope: path from LCA to target has no array/variant FTs */
- if (!lca_to_target_has_struct_ft_only(src_field_path, tgt_field_path,
- ctx)) {
- BT_ASSERT_PRE_MSG("Path from lowest common ancestor of target "
- "and requesting field types to target field type "
- "contains an array or a variant field type: "
- "%![req-ft-]+F, %![tgt-ft-]+F", src_ft, tgt_ft);
- is_valid = false;
- goto end;
- }
-
-end:
- bt_put(src_field_path);
- bt_put(tgt_field_path);
- return is_valid;
-}
-
-static
-struct bt_field_path *resolve_field_path(struct bt_field_type *src_ft,
- struct bt_field_type *tgt_ft,
- struct bt_resolve_field_path_context *ctx)
-{
- BT_ASSERT_PRE(field_path_is_valid(src_ft, tgt_ft, ctx),
- "Invalid target field type: %![req-ft-]+F, %![tgt-ft-]+F",
- src_ft, tgt_ft);
- return find_field_type_in_ctx(tgt_ft, ctx);
-}
-
-BT_HIDDEN
-int bt_resolve_field_paths(struct bt_field_type *ft,
- struct bt_resolve_field_path_context *ctx)
-{
- int ret = 0;
-
- BT_ASSERT(ft);
-
- /* Resolving part for dynamic array and variant field types */
- switch (ft->id) {
- case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
- {
- struct bt_field_type_dynamic_array *dyn_array_ft = (void *) ft;
-
- if (dyn_array_ft->length_ft) {
- BT_ASSERT(!dyn_array_ft->length_field_path);
- dyn_array_ft->length_field_path = resolve_field_path(
- ft, dyn_array_ft->length_ft, ctx);
- if (!dyn_array_ft->length_field_path) {
- ret = -1;
- goto end;
- }
- }
-
- break;
- }
- case BT_FIELD_TYPE_ID_VARIANT:
- {
- struct bt_field_type_variant *var_ft = (void *) ft;
-
- if (var_ft->selector_ft) {
- BT_ASSERT(!var_ft->selector_field_path);
- var_ft->selector_field_path =
- resolve_field_path(ft,
- var_ft->selector_ft, ctx);
- if (!var_ft->selector_field_path) {
- ret = -1;
- goto end;
- }
- }
- }
- default:
- break;
- }
-
- /* Recursive part */
- switch (ft->id) {
- case BT_FIELD_TYPE_ID_STRUCTURE:
- case BT_FIELD_TYPE_ID_VARIANT:
- {
- struct bt_field_type_named_field_types_container *container_ft =
- (void *) ft;
- uint64_t i;
-
- for (i = 0; i < container_ft->named_fts->len; i++) {
- struct bt_named_field_type *named_ft =
- BT_FIELD_TYPE_NAMED_FT_AT_INDEX(
- container_ft, i);
-
- ret = bt_resolve_field_paths(named_ft->ft, ctx);
- if (ret) {
- goto end;
- }
- }
-
- break;
- }
- case BT_FIELD_TYPE_ID_STATIC_ARRAY:
- case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
- {
- struct bt_field_type_array *array_ft = (void *) ft;
-
- ret = bt_resolve_field_paths(array_ft->element_ft, ctx);
- break;
- }
- default:
- break;
- }
-
-end:
- return ret;
-}
+++ /dev/null
-/*
- * stream-class.c
- *
- * Babeltrace CTF IR - Stream Class
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "STREAM-CLASS"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/ctf-ir/field-wrapper-internal.h>
-#include <babeltrace/ctf-ir/resolve-field-path-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/align-internal.h>
-#include <babeltrace/endian-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/property-internal.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-#define BT_ASSERT_PRE_STREAM_CLASS_HOT(_sc) \
- BT_ASSERT_PRE_HOT((_sc), "Stream class", ": %!+S", (_sc))
-
-static
-void destroy_stream_class(struct bt_object *obj)
-{
- struct bt_stream_class *stream_class = (void *) obj;
-
- BT_LIB_LOGD("Destroying stream class: %!+S", stream_class);
- BT_LOGD_STR("Putting default clock class.");
- bt_put(stream_class->default_clock_class);
-
- if (stream_class->event_classes) {
- BT_LOGD_STR("Destroying event classes.");
- g_ptr_array_free(stream_class->event_classes, TRUE);
- }
-
- if (stream_class->name.str) {
- g_string_free(stream_class->name.str, TRUE);
- }
-
- BT_LOGD_STR("Putting event header field type.");
- bt_put(stream_class->event_header_ft);
- BT_LOGD_STR("Putting packet context field type.");
- bt_put(stream_class->packet_context_ft);
- BT_LOGD_STR("Putting event common context field type.");
- bt_put(stream_class->event_common_context_ft);
- bt_object_pool_finalize(&stream_class->event_header_field_pool);
- bt_object_pool_finalize(&stream_class->packet_context_field_pool);
- g_free(stream_class);
-}
-
-static
-void free_field_wrapper(struct bt_field_wrapper *field_wrapper,
- struct bt_stream_class *stream_class)
-{
- bt_field_wrapper_destroy((void *) field_wrapper);
-}
-
-BT_ASSERT_PRE_FUNC
-static
-bool stream_class_id_is_unique(struct bt_trace *trace, uint64_t id)
-{
- uint64_t i;
- bool is_unique = true;
-
- for (i = 0; i < trace->stream_classes->len; i++) {
- struct bt_stream_class *sc =
- trace->stream_classes->pdata[i];
-
- if (sc->id == id) {
- is_unique = false;
- goto end;
- }
- }
-
-end:
- return is_unique;
-}
-
-static
-struct bt_stream_class *create_stream_class_with_id(struct bt_trace *trace,
- uint64_t id)
-{
- struct bt_stream_class *stream_class = NULL;
- int ret;
-
- BT_ASSERT(trace);
- BT_ASSERT_PRE(stream_class_id_is_unique(trace, id),
- "Duplicate stream class ID: %![trace-]+t, id=%" PRIu64,
- trace, id);
- BT_LIB_LOGD("Creating stream class object: %![trace-]+t, id=%" PRIu64,
- trace, id);
- stream_class = g_new0(struct bt_stream_class, 1);
- if (!stream_class) {
- BT_LOGE_STR("Failed to allocate one stream class.");
- goto error;
- }
-
- bt_object_init_shared_with_parent(&stream_class->base,
- destroy_stream_class);
-
- stream_class->name.str = g_string_new(NULL);
- if (!stream_class->name.str) {
- BT_LOGE_STR("Failed to allocate a GString.");
- ret = -1;
- goto end;
- }
-
- stream_class->id = id;
- stream_class->assigns_automatic_event_class_id = true;
- stream_class->assigns_automatic_stream_id = true;
- stream_class->event_classes = g_ptr_array_new_with_free_func(
- (GDestroyNotify) bt_object_try_spec_release);
- if (!stream_class->event_classes) {
- BT_LOGE_STR("Failed to allocate a GPtrArray.");
- goto error;
- }
-
- ret = bt_object_pool_initialize(&stream_class->event_header_field_pool,
- (bt_object_pool_new_object_func) bt_field_wrapper_new,
- (bt_object_pool_destroy_object_func) free_field_wrapper,
- stream_class);
- if (ret) {
- BT_LOGE("Failed to initialize event header field pool: ret=%d",
- ret);
- goto error;
- }
-
- ret = bt_object_pool_initialize(&stream_class->packet_context_field_pool,
- (bt_object_pool_new_object_func) bt_field_wrapper_new,
- (bt_object_pool_destroy_object_func) free_field_wrapper,
- stream_class);
- if (ret) {
- BT_LOGE("Failed to initialize packet context field pool: ret=%d",
- ret);
- goto error;
- }
-
- bt_object_set_parent(&stream_class->base, &trace->base);
- g_ptr_array_add(trace->stream_classes, stream_class);
- bt_trace_freeze(trace);
- BT_LIB_LOGD("Created stream class object: %!+S", stream_class);
- goto end;
-
-error:
- BT_PUT(stream_class);
-
-end:
- return stream_class;
-}
-
-struct bt_stream_class *bt_stream_class_create(struct bt_trace *trace)
-{
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- BT_ASSERT_PRE(trace->assigns_automatic_stream_class_id,
- "Trace does not automatically assigns stream class IDs: "
- "%![sc-]+t", trace);
- return create_stream_class_with_id(trace,
- (uint64_t) trace->stream_classes->len);
-}
-
-struct bt_stream_class *bt_stream_class_create_with_id(
- struct bt_trace *trace, uint64_t id)
-{
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- BT_ASSERT_PRE(!trace->assigns_automatic_stream_class_id,
- "Trace automatically assigns stream class IDs: "
- "%![sc-]+t", trace);
- return create_stream_class_with_id(trace, id);
-}
-
-struct bt_trace *bt_stream_class_borrow_trace(struct bt_stream_class *stream_class)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- return bt_stream_class_borrow_trace_inline(stream_class);
-}
-
-const char *bt_stream_class_get_name(struct bt_stream_class *stream_class)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- return stream_class->name.value;
-}
-
-int bt_stream_class_set_name(struct bt_stream_class *stream_class,
- const char *name)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- BT_ASSERT_PRE_NON_NULL(name, "Name");
- BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
- g_string_assign(stream_class->name.str, name);
- stream_class->name.value = stream_class->name.str->str;
- BT_LIB_LOGV("Set stream class's name: %!+S", stream_class);
- return 0;
-}
-
-uint64_t bt_stream_class_get_id(struct bt_stream_class *stream_class)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- return stream_class->id;
-}
-
-uint64_t bt_stream_class_get_event_class_count(
- struct bt_stream_class *stream_class)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- return (uint64_t) stream_class->event_classes->len;
-}
-
-struct bt_event_class *bt_stream_class_borrow_event_class_by_index(
- struct bt_stream_class *stream_class, uint64_t index)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- BT_ASSERT_PRE_VALID_INDEX(index, stream_class->event_classes->len);
- return g_ptr_array_index(stream_class->event_classes, index);
-}
-
-struct bt_event_class *bt_stream_class_borrow_event_class_by_id(
- struct bt_stream_class *trace, uint64_t id)
-{
- struct bt_event_class *event_class = NULL;
- uint64_t i;
-
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-
- for (i = 0; i < trace->event_classes->len; i++) {
- struct bt_event_class *event_class_candidate =
- g_ptr_array_index(trace->event_classes, i);
-
- if (event_class_candidate->id == id) {
- event_class = event_class_candidate;
- goto end;
- }
- }
-
-end:
- return event_class;
-}
-
-struct bt_field_type *bt_stream_class_borrow_packet_context_field_type(
- struct bt_stream_class *stream_class)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- return stream_class->packet_context_ft;
-}
-
-int bt_stream_class_set_packet_context_field_type(
- struct bt_stream_class *stream_class,
- struct bt_field_type *field_type)
-{
- int ret;
- struct bt_resolve_field_path_context resolve_ctx = {
- .packet_header = NULL,
- .packet_context = field_type,
- .event_header = NULL,
- .event_common_context = NULL,
- .event_specific_context = NULL,
- .event_payload = NULL,
- };
-
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
- BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
- BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
- BT_FIELD_TYPE_ID_STRUCTURE,
- "Packet context field type is not a structure field type: %!+F",
- field_type);
- resolve_ctx.packet_header =
- bt_stream_class_borrow_trace_inline(stream_class)->packet_header_ft;
- ret = bt_resolve_field_paths(field_type, &resolve_ctx);
- if (ret) {
- goto end;
- }
-
- bt_field_type_make_part_of_trace(field_type);
- bt_put(stream_class->packet_context_ft);
- stream_class->packet_context_ft = bt_get(field_type);
- bt_field_type_freeze(field_type);
- BT_LIB_LOGV("Set stream class's packet context field type: %!+S",
- stream_class);
-
-end:
- return ret;
-}
-
-struct bt_field_type *bt_stream_class_borrow_event_header_field_type(
- struct bt_stream_class *stream_class)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- return stream_class->event_header_ft;
-}
-
-int bt_stream_class_set_event_header_field_type(
- struct bt_stream_class *stream_class,
- struct bt_field_type *field_type)
-{
- int ret;
- struct bt_resolve_field_path_context resolve_ctx = {
- .packet_header = NULL,
- .packet_context = NULL,
- .event_header = field_type,
- .event_common_context = NULL,
- .event_specific_context = NULL,
- .event_payload = NULL,
- };
-
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
- BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
- BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
- BT_FIELD_TYPE_ID_STRUCTURE,
- "Event header field type is not a structure field type: %!+F",
- field_type);
- resolve_ctx.packet_header =
- bt_stream_class_borrow_trace_inline(stream_class)->packet_header_ft;
- resolve_ctx.packet_context = stream_class->packet_context_ft;
- ret = bt_resolve_field_paths(field_type, &resolve_ctx);
- if (ret) {
- goto end;
- }
-
- bt_field_type_make_part_of_trace(field_type);
- bt_put(stream_class->event_header_ft);
- stream_class->event_header_ft = bt_get(field_type);
- bt_field_type_freeze(field_type);
- BT_LIB_LOGV("Set stream class's event header field type: %!+S",
- stream_class);
-
-end:
- return ret;
-}
-
-struct bt_field_type *bt_stream_class_borrow_event_common_context_field_type(
- struct bt_stream_class *stream_class)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- return stream_class->event_common_context_ft;
-}
-
-int bt_stream_class_set_event_common_context_field_type(
- struct bt_stream_class *stream_class,
- struct bt_field_type *field_type)
-{
- int ret;
- struct bt_resolve_field_path_context resolve_ctx = {
- .packet_header = NULL,
- .packet_context = NULL,
- .event_header = NULL,
- .event_common_context = field_type,
- .event_specific_context = NULL,
- .event_payload = NULL,
- };
-
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
- BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
- BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
- BT_FIELD_TYPE_ID_STRUCTURE,
- "Event common context field type is not a structure field type: %!+F",
- field_type);
- resolve_ctx.packet_header =
- bt_stream_class_borrow_trace_inline(stream_class)->packet_header_ft;
- resolve_ctx.packet_context = stream_class->packet_context_ft;
- resolve_ctx.event_header = stream_class->event_header_ft;
- ret = bt_resolve_field_paths(field_type, &resolve_ctx);
- if (ret) {
- goto end;
- }
-
- bt_field_type_make_part_of_trace(field_type);
- bt_put(stream_class->event_common_context_ft);
- stream_class->event_common_context_ft = bt_get(field_type);
- bt_field_type_freeze(field_type);
- BT_LIB_LOGV("Set stream class's event common context field type: %!+S",
- stream_class);
-
-end:
- return ret;
-}
-
-BT_HIDDEN
-void _bt_stream_class_freeze(struct bt_stream_class *stream_class)
-{
- /* The field types and default clock class are already frozen */
- BT_ASSERT(stream_class);
- BT_LIB_LOGD("Freezing stream class: %!+S", stream_class);
- stream_class->frozen = true;
-}
-
-int bt_stream_class_set_default_clock_class(
- struct bt_stream_class *stream_class,
- struct bt_clock_class *clock_class)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
- BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
- bt_put(stream_class->default_clock_class);
- stream_class->default_clock_class = bt_get(clock_class);
- bt_clock_class_freeze(clock_class);
- BT_LIB_LOGV("Set stream class's default clock class: %!+S",
- stream_class);
- return 0;
-}
-
-struct bt_clock_class *bt_stream_class_borrow_default_clock_class(
- struct bt_stream_class *stream_class)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- return stream_class->default_clock_class;
-}
-
-bt_bool bt_stream_class_assigns_automatic_event_class_id(
- struct bt_stream_class *stream_class)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- return (bt_bool) stream_class->assigns_automatic_event_class_id;
-}
-
-int bt_stream_class_set_assigns_automatic_event_class_id(
- struct bt_stream_class *stream_class, bt_bool value)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
- stream_class->assigns_automatic_event_class_id = (bool) value;
- BT_LIB_LOGV("Set stream class's automatic event class ID "
- "assignment property: %!+S", stream_class);
- return 0;
-}
-
-bt_bool bt_stream_class_assigns_automatic_stream_id(
- struct bt_stream_class *stream_class)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- return (bt_bool) stream_class->assigns_automatic_stream_id;
-}
-
-int bt_stream_class_set_assigns_automatic_stream_id(
- struct bt_stream_class *stream_class, bt_bool value)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
- stream_class->assigns_automatic_stream_id = (bool) value;
- BT_LIB_LOGV("Set stream class's automatic stream ID "
- "assignment property: %!+S", stream_class);
- return 0;
-}
-
-bt_bool bt_stream_class_packets_have_discarded_event_counter_snapshot(
- struct bt_stream_class *stream_class)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- return (bt_bool) stream_class->packets_have_discarded_event_counter_snapshot;
-}
-
-int bt_stream_class_set_packets_have_discarded_event_counter_snapshot(
- struct bt_stream_class *stream_class, bt_bool value)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
- stream_class->packets_have_discarded_event_counter_snapshot =
- (bool) value;
- BT_LIB_LOGV("Set stream class's "
- "\"packets have discarded event counter snapshot\" property: "
- "%!+S", stream_class);
- return 0;
-}
-
-bt_bool bt_stream_class_packets_have_packet_counter_snapshot(
- struct bt_stream_class *stream_class)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- return (bt_bool) stream_class->packets_have_packet_counter_snapshot;
-}
-
-int bt_stream_class_set_packets_have_packet_counter_snapshot(
- struct bt_stream_class *stream_class, bt_bool value)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
- stream_class->packets_have_packet_counter_snapshot =
- (bool) value;
- BT_LIB_LOGV("Set stream class's "
- "\"packets have packet counter snapshot\" property: "
- "%!+S", stream_class);
- return 0;
-}
-
-bt_bool bt_stream_class_packets_have_default_beginning_clock_value(
- struct bt_stream_class *stream_class)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- return (bt_bool) stream_class->packets_have_default_beginning_cv;
-}
-
-int bt_stream_class_set_packets_have_default_beginning_clock_value(
- struct bt_stream_class *stream_class, bt_bool value)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
- BT_ASSERT_PRE(!value || stream_class->default_clock_class,
- "Stream class does not have a default clock class: %!+S",
- stream_class);
- stream_class->packets_have_default_beginning_cv = (bool) value;
- BT_LIB_LOGV("Set stream class's "
- "\"packets have default beginning clock value\" property: "
- "%!+S", stream_class);
- return 0;
-}
-
-bt_bool bt_stream_class_packets_have_default_end_clock_value(
- struct bt_stream_class *stream_class)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- return (bt_bool) stream_class->packets_have_default_end_cv;
-}
-
-int bt_stream_class_set_packets_have_default_end_clock_value(
- struct bt_stream_class *stream_class, bt_bool value)
-{
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
- BT_ASSERT_PRE(!value || stream_class->default_clock_class,
- "Stream class does not have a default clock class: %!+S",
- stream_class);
- stream_class->packets_have_default_end_cv = (bool) value;
- BT_LIB_LOGV("Set stream class's "
- "\"packets have default end clock value\" property: "
- "%!+S", stream_class);
- return 0;
-}
-
-bt_bool bt_stream_class_default_clock_is_always_known(
- struct bt_stream_class *stream_class)
-{
- /* BT_CLOCK_VALUE_STATUS_UNKNOWN is not supported as of 2.0 */
- return BT_TRUE;
-}
+++ /dev/null
-/*
- * stream.c
- *
- * Babeltrace CTF IR - Stream
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "STREAM"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/trace.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/ctf-ir/packet-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/align-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/property-internal.h>
-#include <inttypes.h>
-#include <unistd.h>
-
-#define BT_ASSERT_PRE_STREAM_HOT(_stream) \
- BT_ASSERT_PRE_HOT((_stream), "Stream", ": %!+s", (_stream))
-
-static
-void destroy_stream(struct bt_object *obj)
-{
- struct bt_stream *stream = (void *) obj;
-
- BT_LIB_LOGD("Destroying stream object: %!+s", stream);
-
- if (stream->name.str) {
- g_string_free(stream->name.str, TRUE);
- }
-
- bt_object_pool_finalize(&stream->packet_pool);
- g_free(stream);
-}
-
-static
-void bt_stream_free_packet(struct bt_packet *packet, struct bt_stream *stream)
-{
- bt_packet_destroy(packet);
-}
-
-BT_ASSERT_PRE_FUNC
-static inline
-bool stream_id_is_unique(struct bt_trace *trace,
- struct bt_stream_class *stream_class, uint64_t id)
-{
- uint64_t i;
- bool is_unique = true;
-
- for (i = 0; i < trace->streams->len; i++) {
- struct bt_stream *stream = trace->streams->pdata[i];
-
- if (stream->class != stream_class) {
- continue;
- }
-
- if (stream->id == id) {
- is_unique = false;
- goto end;
- }
- }
-
-end:
- return is_unique;
-}
-
-static
-struct bt_stream *create_stream_with_id(struct bt_stream_class *stream_class,
- uint64_t id)
-{
- int ret;
- struct bt_stream *stream;
- struct bt_trace *trace;
-
- BT_ASSERT(stream_class);
- trace = bt_stream_class_borrow_trace_inline(stream_class);
- BT_ASSERT_PRE(stream_id_is_unique(trace, stream_class, id),
- "Duplicate stream ID: %![trace-]+t, id=%" PRIu64, trace, id);
- BT_ASSERT_PRE(!trace->is_static,
- "Trace is static: %![trace-]+t", trace);
- BT_LIB_LOGD("Creating stream object: %![trace-]+t, id=%" PRIu64,
- trace, id);
- stream = g_new0(struct bt_stream, 1);
- if (!stream) {
- BT_LOGE_STR("Failed to allocate one stream.");
- goto error;
- }
-
- bt_object_init_shared_with_parent(&stream->base, destroy_stream);
- stream->name.str = g_string_new(NULL);
- if (!stream->name.str) {
- BT_LOGE_STR("Failed to allocate a GString.");
- goto error;
- }
-
- stream->id = id;
- ret = bt_object_pool_initialize(&stream->packet_pool,
- (bt_object_pool_new_object_func) bt_packet_new,
- (bt_object_pool_destroy_object_func) bt_stream_free_packet,
- stream);
- if (ret) {
- BT_LOGE("Failed to initialize packet pool: ret=%d", ret);
- goto error;
- }
-
- stream->class = stream_class;
- bt_trace_add_stream(trace, stream);
- bt_stream_class_freeze(stream_class);
- BT_LIB_LOGD("Created stream object: %!+s", stream);
- goto end;
-
-error:
- BT_PUT(stream);
-
-end:
- return stream;
-}
-
-struct bt_stream *bt_stream_create(struct bt_stream_class *stream_class)
-{
- uint64_t id;
-
- BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
- BT_ASSERT_PRE(stream_class->assigns_automatic_stream_id,
- "Stream class does not automatically assigns stream IDs: "
- "%![sc-]+S", stream_class);
- id = bt_trace_get_automatic_stream_id(
- bt_stream_class_borrow_trace_inline(stream_class),
- stream_class);
- return create_stream_with_id(stream_class, id);
-}
-
-struct bt_stream *bt_stream_create_with_id(struct bt_stream_class *stream_class,
- uint64_t id)
-{
- BT_ASSERT_PRE(!stream_class->assigns_automatic_stream_id,
- "Stream class automatically assigns stream IDs: "
- "%![sc-]+S", stream_class);
- return create_stream_with_id(stream_class, id);
-}
-
-struct bt_stream_class *bt_stream_borrow_class(struct bt_stream *stream)
-{
- BT_ASSERT_PRE_NON_NULL(stream, "Stream");
- return stream->class;
-}
-
-const char *bt_stream_get_name(struct bt_stream *stream)
-{
- BT_ASSERT_PRE_NON_NULL(stream, "Stream class");
- return stream->name.value;
-}
-
-int bt_stream_set_name(struct bt_stream *stream, const char *name)
-{
- BT_ASSERT_PRE_NON_NULL(stream, "Clock class");
- BT_ASSERT_PRE_NON_NULL(name, "Name");
- BT_ASSERT_PRE_STREAM_HOT(stream);
- g_string_assign(stream->name.str, name);
- stream->name.value = stream->name.str->str;
- BT_LIB_LOGV("Set stream class's name: %!+S", stream);
- return 0;
-}
-
-uint64_t bt_stream_get_id(struct bt_stream *stream)
-{
- BT_ASSERT_PRE_NON_NULL(stream, "Stream class");
- return stream->id;
-}
-
-BT_HIDDEN
-void _bt_stream_freeze(struct bt_stream *stream)
-{
- /* The field types and default clock class are already frozen */
- BT_ASSERT(stream);
- BT_LIB_LOGD("Freezing stream: %!+s", stream);
- stream->frozen = true;
-}
+++ /dev/null
-/*
- * trace.c
- *
- * Babeltrace CTF IR - Trace
- *
- * Copyright 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "TRACE"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/event-internal.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/ctf-writer/functor-internal.h>
-#include <babeltrace/ctf-writer/clock-internal.h>
-#include <babeltrace/ctf-ir/field-wrapper-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/attributes-internal.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/ctf-ir/resolve-field-path-internal.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/values.h>
-#include <babeltrace/values-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/types.h>
-#include <babeltrace/endian-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/compat/glib-internal.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdlib.h>
-
-struct bt_trace_is_static_listener_elem {
- bt_trace_is_static_listener func;
- bt_trace_listener_removed removed;
- void *data;
-};
-
-#define BT_ASSERT_PRE_TRACE_HOT(_trace) \
- BT_ASSERT_PRE_HOT((_trace), "Trace", ": %!+t", (_trace))
-
-static
-void destroy_trace(struct bt_object *obj)
-{
- struct bt_trace *trace = (void *) obj;
-
- BT_LIB_LOGD("Destroying trace object: %!+t", trace);
-
- /*
- * Call remove listeners first so that everything else still
- * exists in the trace.
- */
- if (trace->is_static_listeners) {
- size_t i;
-
- for (i = 0; i < trace->is_static_listeners->len; i++) {
- struct bt_trace_is_static_listener_elem elem =
- g_array_index(trace->is_static_listeners,
- struct bt_trace_is_static_listener_elem, i);
-
- if (elem.removed) {
- elem.removed(trace, elem.data);
- }
- }
-
- g_array_free(trace->is_static_listeners, TRUE);
- }
-
- bt_object_pool_finalize(&trace->packet_header_field_pool);
-
- if (trace->environment) {
- BT_LOGD_STR("Destroying environment attributes.");
- bt_attributes_destroy(trace->environment);
- }
-
- if (trace->name.str) {
- g_string_free(trace->name.str, TRUE);
- }
-
- if (trace->streams) {
- BT_LOGD_STR("Destroying streams.");
- g_ptr_array_free(trace->streams, TRUE);
- }
-
- if (trace->stream_classes) {
- BT_LOGD_STR("Destroying stream classes.");
- g_ptr_array_free(trace->stream_classes, TRUE);
- }
-
- if (trace->stream_classes_stream_count) {
- g_hash_table_destroy(trace->stream_classes_stream_count);
- }
-
- BT_LOGD_STR("Putting packet header field type.");
- bt_put(trace->packet_header_ft);
- g_free(trace);
-}
-
-static
-void free_packet_header_field(struct bt_field_wrapper *field_wrapper,
- struct bt_trace *trace)
-{
- bt_field_wrapper_destroy(field_wrapper);
-}
-
-struct bt_trace *bt_trace_create(void)
-{
- struct bt_trace *trace = NULL;
- int ret;
-
- BT_LOGD_STR("Creating default trace object.");
- trace = g_new0(struct bt_trace, 1);
- if (!trace) {
- BT_LOGE_STR("Failed to allocate one trace.");
- goto error;
- }
-
- bt_object_init_shared_with_parent(&trace->base, destroy_trace);
- trace->streams = g_ptr_array_new_with_free_func(
- (GDestroyNotify) bt_object_try_spec_release);
- if (!trace->streams) {
- BT_LOGE_STR("Failed to allocate one GPtrArray.");
- goto error;
- }
-
- trace->stream_classes = g_ptr_array_new_with_free_func(
- (GDestroyNotify) bt_object_try_spec_release);
- if (!trace->stream_classes) {
- BT_LOGE_STR("Failed to allocate one GPtrArray.");
- goto error;
- }
-
- trace->stream_classes_stream_count = g_hash_table_new(g_direct_hash,
- g_direct_equal);
- if (!trace->stream_classes_stream_count) {
- BT_LOGE_STR("Failed to allocate one GHashTable.");
- goto error;
- }
-
- trace->name.str = g_string_new(NULL);
- if (!trace->name.str) {
- BT_LOGE_STR("Failed to allocate one GString.");
- goto error;
- }
-
- trace->environment = bt_attributes_create();
- if (!trace->environment) {
- BT_LOGE_STR("Cannot create empty attributes object.");
- goto error;
- }
-
- trace->is_static_listeners = g_array_new(FALSE, TRUE,
- sizeof(struct bt_trace_is_static_listener_elem));
- if (!trace->is_static_listeners) {
- BT_LOGE_STR("Failed to allocate one GArray.");
- goto error;
- }
-
- trace->assigns_automatic_stream_class_id = true;
- ret = bt_object_pool_initialize(&trace->packet_header_field_pool,
- (bt_object_pool_new_object_func) bt_field_wrapper_new,
- (bt_object_pool_destroy_object_func) free_packet_header_field,
- trace);
- if (ret) {
- BT_LOGE("Failed to initialize packet header field pool: ret=%d",
- ret);
- goto error;
- }
-
- BT_LIB_LOGD("Created trace object: %!+t", trace);
- goto end;
-
-error:
- BT_PUT(trace);
-
-end:
- return trace;
-}
-
-const char *bt_trace_get_name(struct bt_trace *trace)
-{
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- return trace->name.value;
-}
-
-int bt_trace_set_name(struct bt_trace *trace, const char *name)
-{
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- BT_ASSERT_PRE_NON_NULL(name, "Name");
- BT_ASSERT_PRE_TRACE_HOT(trace);
- g_string_assign(trace->name.str, name);
- trace->name.value = trace->name.str->str;
- BT_LIB_LOGV("Set trace's name: %!+t", trace);
- return 0;
-}
-
-bt_uuid bt_trace_get_uuid(struct bt_trace *trace)
-{
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- return trace->uuid.value;
-}
-
-int bt_trace_set_uuid(struct bt_trace *trace, bt_uuid uuid)
-{
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- BT_ASSERT_PRE_NON_NULL(uuid, "UUID");
- BT_ASSERT_PRE_TRACE_HOT(trace);
- memcpy(trace->uuid.uuid, uuid, BABELTRACE_UUID_LEN);
- trace->uuid.value = trace->uuid.uuid;
- BT_LIB_LOGV("Set trace's UUID: %!+t", trace);
- return 0;
-}
-
-BT_ASSERT_FUNC
-static
-bool trace_has_environment_entry(struct bt_trace *trace, const char *name)
-{
- struct bt_value *attribute;
-
- BT_ASSERT(trace);
-
- attribute = bt_attributes_borrow_field_value_by_name(
- trace->environment, name);
- return attribute != NULL;
-}
-
-static
-int set_environment_entry(struct bt_trace *trace, const char *name,
- struct bt_value *value)
-{
- int ret;
-
- BT_ASSERT(trace);
- BT_ASSERT(name);
- BT_ASSERT(value);
- BT_ASSERT_PRE(!trace->frozen ||
- !trace_has_environment_entry(trace, name),
- "Trace is frozen: cannot replace environment entry: "
- "%![trace-]+t, entry-name=\"%s\"", trace, name);
- ret = bt_attributes_set_field_value(trace->environment, name,
- value);
- bt_value_freeze(value);
- if (ret) {
- BT_LIB_LOGE("Cannot set trace's environment entry: "
- "%![trace-]+t, entry-name=\"%s\"", trace, name);
- } else {
- BT_LIB_LOGV("Set trace's environment entry: "
- "%![trace-]+t, entry-name=\"%s\"", trace, name);
- }
-
- return ret;
-}
-
-int bt_trace_set_environment_entry_string(struct bt_trace *trace,
- const char *name, const char *value)
-{
- int ret;
- struct bt_value *value_obj;
-
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- BT_ASSERT_PRE_NON_NULL(name, "Name");
- BT_ASSERT_PRE_NON_NULL(value, "Value");
- value_obj = bt_value_string_create_init(value);
- if (!value_obj) {
- BT_LOGE_STR("Cannot create a string value object.");
- ret = -1;
- goto end;
- }
-
- /* set_environment_entry() logs errors */
- ret = set_environment_entry(trace, name, value_obj);
-
-end:
- bt_put(value_obj);
- return ret;
-}
-
-int bt_trace_set_environment_entry_integer(
- struct bt_trace *trace, const char *name, int64_t value)
-{
- int ret;
- struct bt_value *value_obj;
-
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- BT_ASSERT_PRE_NON_NULL(name, "Name");
- value_obj = bt_value_integer_create_init(value);
- if (!value_obj) {
- BT_LOGE_STR("Cannot create an integer value object.");
- ret = -1;
- goto end;
- }
-
- /* set_environment_entry() logs errors */
- ret = set_environment_entry(trace, name, value_obj);
-
-end:
- bt_put(value_obj);
- return ret;
-}
-
-uint64_t bt_trace_get_environment_entry_count(struct bt_trace *trace)
-{
- int64_t ret;
-
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- ret = bt_attributes_get_count(trace->environment);
- BT_ASSERT(ret >= 0);
- return (uint64_t) ret;
-}
-
-void bt_trace_borrow_environment_entry_by_index(
- struct bt_trace *trace, uint64_t index,
- const char **name, struct bt_value **value)
-{
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- BT_ASSERT_PRE_NON_NULL(name, "Name");
- BT_ASSERT_PRE_NON_NULL(value, "Value");
- BT_ASSERT_PRE_VALID_INDEX(index,
- bt_attributes_get_count(trace->environment));
- *value = bt_attributes_borrow_field_value(trace->environment, index);
- BT_ASSERT(*value);
- *name = bt_attributes_get_field_name(trace->environment, index);
- BT_ASSERT(*name);
-}
-
-struct bt_value *bt_trace_borrow_environment_entry_value_by_name(
- struct bt_trace *trace, const char *name)
-{
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- BT_ASSERT_PRE_NON_NULL(name, "Name");
- return bt_attributes_borrow_field_value_by_name(trace->environment,
- name);
-}
-
-uint64_t bt_trace_get_stream_count(struct bt_trace *trace)
-{
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- return (uint64_t) trace->streams->len;
-}
-
-struct bt_stream *bt_trace_borrow_stream_by_index(
- struct bt_trace *trace, uint64_t index)
-{
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- BT_ASSERT_PRE_VALID_INDEX(index, trace->streams->len);
- return g_ptr_array_index(trace->streams, index);
-}
-
-struct bt_stream *bt_trace_borrow_stream_by_id(
- struct bt_trace *trace, uint64_t id)
-{
- struct bt_stream *stream = NULL;
- uint64_t i;
-
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-
- for (i = 0; i < trace->streams->len; i++) {
- struct bt_stream *stream_candidate =
- g_ptr_array_index(trace->streams, i);
-
- if (stream_candidate->id == id) {
- stream = stream_candidate;
- goto end;
- }
- }
-
-end:
- return stream;
-}
-
-uint64_t bt_trace_get_stream_class_count(struct bt_trace *trace)
-{
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- return (uint64_t) trace->stream_classes->len;
-}
-
-struct bt_stream_class *bt_trace_borrow_stream_class_by_index(
- struct bt_trace *trace, uint64_t index)
-{
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- BT_ASSERT_PRE_VALID_INDEX(index, trace->stream_classes->len);
- return g_ptr_array_index(trace->stream_classes, index);
-}
-
-struct bt_stream_class *bt_trace_borrow_stream_class_by_id(
- struct bt_trace *trace, uint64_t id)
-{
- struct bt_stream_class *stream_class = NULL;
- uint64_t i;
-
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-
- for (i = 0; i < trace->stream_classes->len; i++) {
- struct bt_stream_class *stream_class_candidate =
- g_ptr_array_index(trace->stream_classes, i);
-
- if (stream_class_candidate->id == id) {
- stream_class = stream_class_candidate;
- goto end;
- }
- }
-
-end:
- return stream_class;
-}
-
-struct bt_field_type *bt_trace_borrow_packet_header_field_type(
- struct bt_trace *trace)
-{
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- return trace->packet_header_ft;
-}
-
-int bt_trace_set_packet_header_field_type(struct bt_trace *trace,
- struct bt_field_type *field_type)
-{
- int ret;
- struct bt_resolve_field_path_context resolve_ctx = {
- .packet_header = field_type,
- .packet_context = NULL,
- .event_header = NULL,
- .event_common_context = NULL,
- .event_specific_context = NULL,
- .event_payload = NULL,
- };
-
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
- BT_ASSERT_PRE_TRACE_HOT(trace);
- BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
- BT_FIELD_TYPE_ID_STRUCTURE,
- "Packet header field type is not a structure field type: %!+F",
- field_type);
- ret = bt_resolve_field_paths(field_type, &resolve_ctx);
- if (ret) {
- goto end;
- }
-
- bt_field_type_make_part_of_trace(field_type);
- bt_put(trace->packet_header_ft);
- trace->packet_header_ft = bt_get(field_type);
- bt_field_type_freeze(field_type);
- BT_LIB_LOGV("Set trace's packet header field type: %!+t", trace);
-
-end:
- return ret;
-}
-
-bt_bool bt_trace_is_static(struct bt_trace *trace)
-{
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- return (bt_bool) trace->is_static;
-}
-
-int bt_trace_make_static(struct bt_trace *trace)
-{
- uint64_t i;
-
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- trace->is_static = true;
- bt_trace_freeze(trace);
- BT_LIB_LOGV("Trace is now static: %!+t", trace);
-
- /* Call all the "trace is static" listeners */
- for (i = 0; i < trace->is_static_listeners->len; i++) {
- struct bt_trace_is_static_listener_elem elem =
- g_array_index(trace->is_static_listeners,
- struct bt_trace_is_static_listener_elem, i);
-
- if (elem.func) {
- elem.func(trace, elem.data);
- }
- }
-
- return 0;
-}
-
-int bt_trace_add_is_static_listener(struct bt_trace *trace,
- bt_trace_is_static_listener listener,
- bt_trace_listener_removed listener_removed, void *data,
- uint64_t *listener_id)
-{
- uint64_t i;
- struct bt_trace_is_static_listener_elem new_elem = {
- .func = listener,
- .removed = listener_removed,
- .data = data,
- };
-
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- BT_ASSERT_PRE_NON_NULL(listener, "Listener");
- BT_ASSERT_PRE(!trace->is_static,
- "Trace is already static: %!+t", trace);
- BT_ASSERT_PRE(trace->in_remove_listener,
- "Cannot call this function while executing a "
- "remove listener: %!+t", trace);
-
- /* Find the next available spot */
- for (i = 0; i < trace->is_static_listeners->len; i++) {
- struct bt_trace_is_static_listener_elem elem =
- g_array_index(trace->is_static_listeners,
- struct bt_trace_is_static_listener_elem, i);
-
- if (!elem.func) {
- break;
- }
- }
-
- if (i == trace->is_static_listeners->len) {
- g_array_append_val(trace->is_static_listeners, new_elem);
- } else {
- g_array_insert_val(trace->is_static_listeners, i, new_elem);
- }
-
- if (listener_id) {
- *listener_id = i;
- }
-
- BT_LIB_LOGV("Added \"trace is static\" listener: "
- "%![trace-]+t, listener-id=%" PRIu64, trace, i);
- return 0;
-}
-
-BT_ASSERT_PRE_FUNC
-static
-bool has_listener_id(struct bt_trace *trace, uint64_t listener_id)
-{
- BT_ASSERT(listener_id < trace->is_static_listeners->len);
- return (&g_array_index(trace->is_static_listeners,
- struct bt_trace_is_static_listener_elem,
- listener_id))->func != NULL;
-}
-
-int bt_trace_remove_is_static_listener(
- struct bt_trace *trace, uint64_t listener_id)
-{
- struct bt_trace_is_static_listener_elem *elem;
-
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- BT_ASSERT_PRE(!trace->is_static,
- "Trace is already static: %!+t", trace);
- BT_ASSERT_PRE(trace->in_remove_listener,
- "Cannot call this function while executing a "
- "remove listener: %!+t", trace);
- BT_ASSERT_PRE(has_listener_id(trace, listener_id),
- "Trace has no such \"trace is static\" listener ID: "
- "%![trace-]+t, %" PRIu64, trace, listener_id);
- elem = &g_array_index(trace->is_static_listeners,
- struct bt_trace_is_static_listener_elem,
- listener_id);
- BT_ASSERT(elem->func);
-
- if (elem->removed) {
- /* Call remove listener */
- BT_LIB_LOGV("Calling remove listener: "
- "%![trace-]+t, listener-id=%" PRIu64,
- trace, listener_id);
- trace->in_remove_listener = true;
- elem->removed(trace, elem->data);
- trace->in_remove_listener = false;
- }
-
- elem->func = NULL;
- elem->removed = NULL;
- elem->data = NULL;
- BT_LIB_LOGV("Removed \"trace is static\" listener: "
- "%![trace-]+t, listener-id=%" PRIu64,
- trace, listener_id);
- return 0;
-}
-
-BT_HIDDEN
-void _bt_trace_freeze(struct bt_trace *trace)
-{
- /* The packet header field type is already frozen */
- BT_ASSERT(trace);
- BT_LIB_LOGD("Freezing trace: %!+t", trace);
- trace->frozen = true;
-}
-
-bt_bool bt_trace_assigns_automatic_stream_class_id(struct bt_trace *trace)
-{
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- return (bt_bool) trace->assigns_automatic_stream_class_id;
-}
-
-int bt_trace_set_assigns_automatic_stream_class_id(
- struct bt_trace *trace, bt_bool value)
-{
- BT_ASSERT_PRE_NON_NULL(trace, "Trace");
- BT_ASSERT_PRE_TRACE_HOT(trace);
- trace->assigns_automatic_stream_class_id = (bool) value;
- BT_LIB_LOGV("Set trace's automatic stream class ID "
- "assignment property: %!+t", trace);
- return 0;
-}
-
-BT_HIDDEN
-void bt_trace_add_stream(struct bt_trace *trace, struct bt_stream *stream)
-{
- guint count = 0;
-
- bt_object_set_parent(&stream->base, &trace->base);
- g_ptr_array_add(trace->streams, stream);
- bt_trace_freeze(trace);
-
- if (bt_g_hash_table_contains(trace->stream_classes_stream_count,
- stream->class)) {
- count = GPOINTER_TO_UINT(g_hash_table_lookup(
- trace->stream_classes_stream_count, stream->class));
- }
-
- g_hash_table_insert(trace->stream_classes_stream_count,
- stream->class, GUINT_TO_POINTER(count + 1));
-}
-
-BT_HIDDEN
-uint64_t bt_trace_get_automatic_stream_id(struct bt_trace *trace,
- struct bt_stream_class *stream_class)
-{
- gpointer orig_key;
- gpointer value;
- uint64_t id = 0;
-
- BT_ASSERT(stream_class);
- BT_ASSERT(trace);
- if (g_hash_table_lookup_extended(trace->stream_classes_stream_count,
- stream_class, &orig_key, &value)) {
- id = (uint64_t) GPOINTER_TO_UINT(value);
- }
-
- return id;
-}
+++ /dev/null
-/*
- * utils.c
- *
- * Babeltrace CTF IR - Utilities
- *
- * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "CTF-IR-UTILS"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <stdlib.h>
-#include <glib.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/assert-internal.h>
#include <babeltrace/compiler-internal.h>
#include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/event-internal.h>
-#include <babeltrace/ctf-ir/packet-internal.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/event-internal.h>
+#include <babeltrace/trace-ir/packet-internal.h>
+#include <babeltrace/trace-ir/stream-internal.h>
#include <babeltrace/graph/connection.h>
#include <babeltrace/graph/connection-internal.h>
#include <babeltrace/graph/component.h>
#include <babeltrace/compiler-internal.h>
#include <babeltrace/object-internal.h>
-#include <babeltrace/ctf-ir/event.h>
-#include <babeltrace/ctf-ir/event-internal.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/trace.h>
+#include <babeltrace/trace-ir/event.h>
+#include <babeltrace/trace-ir/event-internal.h>
+#include <babeltrace/trace-ir/event-class-internal.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/trace.h>
#include <babeltrace/graph/graph-internal.h>
#include <babeltrace/graph/notification-event-internal.h>
#include <babeltrace/graph/private-connection-private-notification-iterator.h>
#include <babeltrace/object-internal.h>
#include <babeltrace/compiler-internal.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/clock-class.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
#include <babeltrace/graph/notification-internal.h>
#include <babeltrace/graph/notification-inactivity-internal.h>
#include <babeltrace/graph/private-connection-private-notification-iterator.h>
#include <babeltrace/lib-logging-internal.h>
#include <babeltrace/compiler-internal.h>
-#include <babeltrace/ctf-ir/packet.h>
-#include <babeltrace/ctf-ir/packet-internal.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
+#include <babeltrace/trace-ir/packet.h>
+#include <babeltrace/trace-ir/packet-internal.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/stream-internal.h>
#include <babeltrace/graph/graph-internal.h>
#include <babeltrace/graph/notification-packet-internal.h>
#include <babeltrace/graph/private-connection-private-notification-iterator.h>
#include <babeltrace/assert-pre-internal.h>
#include <babeltrace/compiler-internal.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/stream-internal.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
#include <babeltrace/graph/notification-stream-internal.h>
#include <babeltrace/graph/private-connection-private-notification-iterator.h>
#include <babeltrace/assert-internal.h>
#include <babeltrace/lib-logging-internal.h>
#include <babeltrace/values-internal.h>
#include <babeltrace/object-pool-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/ctf-ir/event-internal.h>
-#include <babeltrace/ctf-ir/packet-internal.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
-#include <babeltrace/ctf-ir/field-path-internal.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/event-class-internal.h>
+#include <babeltrace/trace-ir/event-internal.h>
+#include <babeltrace/trace-ir/packet-internal.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/stream-internal.h>
+#include <babeltrace/trace-ir/trace-internal.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/field-path-internal.h>
+#include <babeltrace/trace-ir/utils-internal.h>
#include <babeltrace/graph/component-class-internal.h>
#include <babeltrace/graph/component-class-sink-colander-internal.h>
#include <babeltrace/graph/component-filter-internal.h>
--- /dev/null
+noinst_LTLIBRARIES = libtrace-ir.la
+
+libtrace_ir_la_SOURCES = \
+ attributes.c \
+ clock-class.c \
+ clock-value.c \
+ event.c \
+ event-class.c \
+ event-header-field.c \
+ field-wrapper.c \
+ fields.c \
+ field-types.c \
+ field-path.c \
+ packet.c \
+ packet-context-field.c \
+ packet-header-field.c \
+ resolve-field-path.c \
+ stream.c \
+ stream-class.c \
+ trace.c \
+ utils.c
+
+libtrace_ir_la_LIBADD = $(UUID_LIBS)
--- /dev/null
+/*
+ * attributes.c
+ *
+ * Babeltrace trace IR - Attributes
+ *
+ * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
+ * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "ATTRS"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/ref.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/values.h>
+#include <babeltrace/values-internal.h>
+#include <inttypes.h>
+#include <babeltrace/compat/string-internal.h>
+#include <babeltrace/assert-internal.h>
+
+#define BT_ATTR_NAME_INDEX 0
+#define BT_ATTR_VALUE_INDEX 1
+
+BT_HIDDEN
+struct bt_value *bt_attributes_create(void)
+{
+ struct bt_value *attr_obj;
+
+ /*
+ * Attributes: array value object of array value objects, each one
+ * containing two entries: a string value object (attributes
+ * field name), and a value object (attributes field value).
+ *
+ * Example (JSON representation):
+ *
+ * [
+ * ["hostname", "eeppdesk"],
+ * ["sysname", "Linux"],
+ * ["tracer_major", 2],
+ * ["tracer_minor", 5]
+ * ]
+ */
+ BT_LOGD_STR("Creating attributes object.");
+ attr_obj = bt_value_array_create();
+ if (!attr_obj) {
+ BT_LOGE_STR("Failed to create array value.");
+ } else {
+ BT_LOGD("Created attributes object: addr=%p",
+ attr_obj);
+ }
+
+ return attr_obj;
+}
+
+BT_HIDDEN
+void bt_attributes_destroy(struct bt_value *attr_obj)
+{
+ BT_LOGD("Destroying attributes object: addr=%p", attr_obj);
+ bt_put(attr_obj);
+}
+
+BT_HIDDEN
+int64_t bt_attributes_get_count(struct bt_value *attr_obj)
+{
+ return bt_value_array_size(attr_obj);
+}
+
+BT_HIDDEN
+const char *bt_attributes_get_field_name(struct bt_value *attr_obj,
+ uint64_t index)
+{
+ int rc;
+ const char *ret = NULL;
+ struct bt_value *attr_field_obj = NULL;
+ struct bt_value *attr_field_name_obj = NULL;
+
+ if (!attr_obj) {
+ BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
+ goto end;
+ }
+
+ if (index >= bt_value_array_size(attr_obj)) {
+ BT_LOGW("Invalid parameter: index is out of bounds: "
+ "index=%" PRIu64 ", count=%" PRId64,
+ index, bt_value_array_size(attr_obj));
+ goto end;
+ }
+
+ attr_field_obj = bt_value_array_borrow(attr_obj, index);
+ if (!attr_field_obj) {
+ BT_LOGE("Cannot get attributes object's array value's element by index: "
+ "value-addr=%p, index=%" PRIu64, attr_obj, index);
+ goto end;
+ }
+
+ attr_field_name_obj = bt_value_array_borrow(attr_field_obj,
+ BT_ATTR_NAME_INDEX);
+ if (!attr_field_name_obj) {
+ BT_LOGE("Cannot get attribute array value's element by index: "
+ "value-addr=%p, index=%" PRIu64, attr_field_obj,
+ (uint64_t) BT_ATTR_NAME_INDEX);
+ goto end;
+ }
+
+ rc = bt_value_string_get(attr_field_name_obj, &ret);
+ if (rc) {
+ BT_LOGE("Cannot get raw value from string value: value-addr=%p",
+ attr_field_name_obj);
+ ret = NULL;
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+struct bt_value *bt_attributes_borrow_field_value(struct bt_value *attr_obj,
+ uint64_t index)
+{
+ struct bt_value *value_obj = NULL;
+ struct bt_value *attr_field_obj = NULL;
+
+ if (!attr_obj) {
+ BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
+ goto end;
+ }
+
+ if (index >= bt_value_array_size(attr_obj)) {
+ BT_LOGW("Invalid parameter: index is out of bounds: "
+ "index=%" PRIu64 ", count=%" PRId64,
+ index, bt_value_array_size(attr_obj));
+ goto end;
+ }
+
+ attr_field_obj = bt_value_array_borrow(attr_obj, index);
+ if (!attr_field_obj) {
+ BT_LOGE("Cannot get attributes object's array value's element by index: "
+ "value-addr=%p, index=%" PRIu64, attr_obj, index);
+ goto end;
+ }
+
+ value_obj = bt_value_array_borrow(attr_field_obj,
+ BT_ATTR_VALUE_INDEX);
+ if (!value_obj) {
+ BT_LOGE("Cannot get attribute array value's element by index: "
+ "value-addr=%p, index=%" PRIu64, attr_field_obj,
+ (uint64_t) BT_ATTR_VALUE_INDEX);
+ }
+
+end:
+ return value_obj;
+}
+
+static
+struct bt_value *bt_attributes_borrow_field_by_name(
+ struct bt_value *attr_obj, const char *name)
+{
+ uint64_t i;
+ int64_t attr_size;
+ struct bt_value *value_obj = NULL;
+ struct bt_value *attr_field_name_obj = NULL;
+
+ attr_size = bt_value_array_size(attr_obj);
+ if (attr_size < 0) {
+ BT_LOGE("Cannot get array value's size: value-addr=%p",
+ attr_obj);
+ goto error;
+ }
+
+ for (i = 0; i < attr_size; ++i) {
+ int ret;
+ const char *field_name;
+
+ value_obj = bt_value_array_borrow(attr_obj, i);
+ if (!value_obj) {
+ BT_LOGE("Cannot get attributes object's array value's element by index: "
+ "value-addr=%p, index=%" PRIu64, attr_obj, i);
+ goto error;
+ }
+
+ attr_field_name_obj = bt_value_array_borrow(value_obj,
+ BT_ATTR_NAME_INDEX);
+ if (!attr_field_name_obj) {
+ BT_LOGE("Cannot get attribute array value's element by index: "
+ "value-addr=%p, index=%" PRIu64,
+ value_obj, (int64_t) BT_ATTR_NAME_INDEX);
+ goto error;
+ }
+
+ ret = bt_value_string_get(attr_field_name_obj, &field_name);
+ if (ret) {
+ BT_LOGE("Cannot get raw value from string value: value-addr=%p",
+ attr_field_name_obj);
+ goto error;
+ }
+
+ if (!strcmp(field_name, name)) {
+ break;
+ }
+
+ value_obj = NULL;
+ }
+
+ return value_obj;
+
+error:
+ value_obj = NULL;
+ return value_obj;
+}
+
+BT_HIDDEN
+int bt_attributes_set_field_value(struct bt_value *attr_obj,
+ const char *name, struct bt_value *value_obj)
+{
+ int ret = 0;
+ struct bt_value *attr_field_obj = NULL;
+
+ if (!attr_obj || !name || !value_obj) {
+ BT_LOGW("Invalid parameter: attributes object, name, or value object is NULL: "
+ "attr-value-addr=%p, name-addr=%p, value-addr=%p",
+ attr_obj, name, value_obj);
+ ret = -1;
+ goto end;
+ }
+
+ attr_field_obj = bt_attributes_borrow_field_by_name(attr_obj, name);
+ if (attr_field_obj) {
+ ret = bt_value_array_set(attr_field_obj,
+ BT_ATTR_VALUE_INDEX, value_obj);
+ attr_field_obj = NULL;
+ goto end;
+ }
+
+ attr_field_obj = bt_value_array_create();
+ if (!attr_field_obj) {
+ BT_LOGE_STR("Failed to create empty array value.");
+ ret = -1;
+ goto end;
+ }
+
+ ret = bt_value_array_append_string(attr_field_obj, name);
+ ret |= bt_value_array_append(attr_field_obj, value_obj);
+ if (ret) {
+ BT_LOGE("Cannot append elements to array value: addr=%p",
+ attr_field_obj);
+ goto end;
+ }
+
+ ret = bt_value_array_append(attr_obj, attr_field_obj);
+ if (ret) {
+ BT_LOGE("Cannot append element to array value: "
+ "array-value-addr=%p, element-value-addr=%p",
+ attr_obj, attr_field_obj);
+ }
+
+end:
+ bt_put(attr_field_obj);
+ return ret;
+}
+
+BT_HIDDEN
+struct bt_value *bt_attributes_borrow_field_value_by_name(
+ struct bt_value *attr_obj, const char *name)
+{
+ struct bt_value *value_obj = NULL;
+ struct bt_value *attr_field_obj = NULL;
+
+ if (!attr_obj || !name) {
+ BT_LOGW("Invalid parameter: attributes object or name is NULL: "
+ "value-addr=%p, name-addr=%p", attr_obj, name);
+ goto end;
+ }
+
+ attr_field_obj = bt_attributes_borrow_field_by_name(attr_obj, name);
+ if (!attr_field_obj) {
+ BT_LOGD("Cannot find attributes object's field by name: "
+ "value-addr=%p, name=\"%s\"", attr_obj, name);
+ goto end;
+ }
+
+ value_obj = bt_value_array_borrow(attr_field_obj,
+ BT_ATTR_VALUE_INDEX);
+ if (!value_obj) {
+ BT_LOGE("Cannot get attribute array value's element by index: "
+ "value-addr=%p, index=%" PRIu64, attr_field_obj,
+ (uint64_t) BT_ATTR_VALUE_INDEX);
+ }
+
+end:
+ return value_obj;
+}
+
+BT_HIDDEN
+int bt_attributes_freeze(struct bt_value *attr_obj)
+{
+ uint64_t i;
+ int64_t count;
+ int ret = 0;
+
+ if (!attr_obj) {
+ BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ BT_LOGD("Freezing attributes object: value-addr=%p", attr_obj);
+ count = bt_value_array_size(attr_obj);
+ BT_ASSERT(count >= 0);
+
+ /*
+ * We do not freeze the array value object itself here, since
+ * internal stuff could need to modify/add attributes. Each
+ * attribute is frozen one by one.
+ */
+ for (i = 0; i < count; ++i) {
+ struct bt_value *obj = NULL;
+
+ obj = bt_attributes_borrow_field_value(attr_obj, i);
+ if (!obj) {
+ BT_LOGE("Cannot get attributes object's field value by index: "
+ "value-addr=%p, index=%" PRIu64,
+ attr_obj, i);
+ ret = -1;
+ goto end;
+ }
+
+ bt_value_freeze(obj);
+ }
+
+end:
+ return ret;
+}
--- /dev/null
+/*
+ * clock-class.c
+ *
+ * Babeltrace trace IR - Clock class
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "CLOCK-CLASS"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/compat/uuid-internal.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/utils-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/types.h>
+#include <babeltrace/compat/string-internal.h>
+#include <inttypes.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/assert-internal.h>
+
+#define BT_ASSERT_PRE_CLOCK_CLASS_HOT(_cc) \
+ BT_ASSERT_PRE_HOT((_cc), "Clock class", ": %!+K", (_cc))
+
+static
+void destroy_clock_class(struct bt_object *obj)
+{
+ struct bt_clock_class *clock_class = (void *) obj;
+
+ BT_LIB_LOGD("Destroying clock class: %!+K", clock_class);
+
+ if (clock_class->name.str) {
+ g_string_free(clock_class->name.str, TRUE);
+ }
+
+ if (clock_class->description.str) {
+ g_string_free(clock_class->description.str, TRUE);
+ }
+
+ bt_object_pool_finalize(&clock_class->cv_pool);
+ g_free(clock_class);
+}
+
+static
+void free_clock_value(struct bt_clock_value *clock_value,
+ struct bt_clock_class *clock_class)
+{
+ bt_clock_value_destroy(clock_value);
+}
+
+static inline
+void set_base_offset(struct bt_clock_class *clock_class)
+{
+ uint64_t offset_cycles_ns;
+
+ /* Initialize nanosecond timestamp to clock's offset in seconds */
+ if (clock_class->offset_seconds <= (INT64_MIN / INT64_C(1000000000) - 1) ||
+ clock_class->offset_seconds >= (INT64_MAX / INT64_C(1000000000)) - 1) {
+ /*
+ * Overflow: offset in seconds converted to nanoseconds
+ * is outside the int64_t range. We also subtract 1 here
+ * to leave "space" for the offset in cycles converted
+ * to nanoseconds (which is always less than 1 second by
+ * contract).
+ */
+ clock_class->base_offset.overflows = true;
+ goto end;
+ }
+
+ /* Offset (seconds) to nanoseconds */
+ clock_class->base_offset.value_ns = clock_class->offset_seconds *
+ INT64_C(1000000000);
+
+ /* Add offset in cycles */
+ BT_ASSERT(clock_class->offset_cycles < clock_class->frequency);
+ offset_cycles_ns = bt_util_ns_from_value(clock_class->frequency,
+ clock_class->offset_cycles);
+ BT_ASSERT(offset_cycles_ns < 1000000000);
+ clock_class->base_offset.value_ns += (int64_t) offset_cycles_ns;
+ clock_class->base_offset.overflows = false;
+
+end:
+ return;
+}
+
+struct bt_clock_class *bt_clock_class_create(void)
+{
+ int ret;
+ struct bt_clock_class *clock_class = NULL;
+
+ BT_LOGD_STR("Creating default clock class object");
+
+ clock_class = g_new0(struct bt_clock_class, 1);
+ if (!clock_class) {
+ BT_LOGE_STR("Failed to allocate one clock class.");
+ goto error;
+ }
+
+ bt_object_init_shared(&clock_class->base, destroy_clock_class);
+ clock_class->name.str = g_string_new(NULL);
+ if (!clock_class->name.str) {
+ BT_LOGE_STR("Failed to allocate a GString.");
+ goto error;
+ }
+
+ clock_class->description.str = g_string_new(NULL);
+ if (!clock_class->description.str) {
+ BT_LOGE_STR("Failed to allocate a GString.");
+ goto error;
+ }
+
+ clock_class->frequency = UINT64_C(1000000000);
+ clock_class->is_absolute = BT_TRUE;
+ set_base_offset(clock_class);
+ ret = bt_object_pool_initialize(&clock_class->cv_pool,
+ (bt_object_pool_new_object_func) bt_clock_value_new,
+ (bt_object_pool_destroy_object_func)
+ free_clock_value,
+ clock_class);
+ if (ret) {
+ BT_LOGE("Failed to initialize clock value pool: ret=%d",
+ ret);
+ goto error;
+ }
+
+ BT_LIB_LOGD("Created clock class object: %!+K", clock_class);
+ goto end;
+
+error:
+ BT_PUT(clock_class);
+
+end:
+ return clock_class;
+}
+
+const char *bt_clock_class_get_name(
+ struct bt_clock_class *clock_class)
+{
+ BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+ return clock_class->name.value;
+}
+
+int bt_clock_class_set_name(struct bt_clock_class *clock_class,
+ const char *name)
+{
+ BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
+ g_string_assign(clock_class->name.str, name);
+ clock_class->name.value = clock_class->name.str->str;
+ BT_LIB_LOGV("Set clock class's name: %!+K", clock_class);
+ return 0;
+}
+
+const char *bt_clock_class_get_description(struct bt_clock_class *clock_class)
+{
+ BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+ return clock_class->description.value;
+}
+
+int bt_clock_class_set_description(struct bt_clock_class *clock_class,
+ const char *descr)
+{
+ BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+ BT_ASSERT_PRE_NON_NULL(descr, "Description");
+ BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
+ g_string_assign(clock_class->description.str, descr);
+ clock_class->description.value = clock_class->description.str->str;
+ BT_LIB_LOGV("Set clock class's description: %!+K",
+ clock_class);
+ return 0;
+}
+
+uint64_t bt_clock_class_get_frequency(struct bt_clock_class *clock_class)
+{
+ BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+ return clock_class->frequency;
+}
+
+int bt_clock_class_set_frequency(struct bt_clock_class *clock_class,
+ uint64_t frequency)
+{
+ BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+ BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
+ BT_ASSERT_PRE(frequency != UINT64_C(-1) && frequency != 0,
+ "Invalid frequency: %![cc-]+K, new-freq=%" PRIu64,
+ clock_class, frequency);
+ BT_ASSERT_PRE(clock_class->offset_cycles < frequency,
+ "Offset (cycles) is greater than clock class's frequency: "
+ "%![cc-]+K, new-freq=%" PRIu64, clock_class, frequency);
+ clock_class->frequency = frequency;
+ set_base_offset(clock_class);
+ BT_LIB_LOGV("Set clock class's frequency: %!+K", clock_class);
+ return 0;
+}
+
+uint64_t bt_clock_class_get_precision(struct bt_clock_class *clock_class)
+{
+ BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+ return clock_class->precision;
+}
+
+int bt_clock_class_set_precision(struct bt_clock_class *clock_class,
+ uint64_t precision)
+{
+ BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+ BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
+ BT_ASSERT_PRE(precision != UINT64_C(-1),
+ "Invalid precision: %![cc-]+K, new-precision=%" PRIu64,
+ clock_class, precision);
+ clock_class->precision = precision;
+ BT_LIB_LOGV("Set clock class's precision: %!+K", clock_class);
+ return 0;
+}
+
+void bt_clock_class_get_offset(struct bt_clock_class *clock_class,
+ int64_t *seconds, uint64_t *cycles)
+{
+ BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+ BT_ASSERT_PRE_NON_NULL(seconds, "Seconds (output)");
+ BT_ASSERT_PRE_NON_NULL(cycles, "Cycles (output)");
+ *seconds = clock_class->offset_seconds;
+ *cycles = clock_class->offset_cycles;
+}
+
+int bt_clock_class_set_offset(struct bt_clock_class *clock_class,
+ int64_t seconds, uint64_t cycles)
+{
+ BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+ BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
+ BT_ASSERT_PRE(cycles < clock_class->frequency,
+ "Offset (cycles) is greater than clock class's frequency: "
+ "%![cc-]+K, new-offset-cycles=%" PRIu64, clock_class, cycles);
+ clock_class->offset_seconds = seconds;
+ clock_class->offset_cycles = cycles;
+ set_base_offset(clock_class);
+ BT_LIB_LOGV("Set clock class's offset: %!+K", clock_class);
+ return 0;
+}
+
+bt_bool bt_clock_class_is_absolute(struct bt_clock_class *clock_class)
+{
+ BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+ return (bool) clock_class->is_absolute;
+}
+
+int bt_clock_class_set_is_absolute(struct bt_clock_class *clock_class,
+ bt_bool is_absolute)
+{
+ BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+ BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
+ clock_class->is_absolute = (bool) is_absolute;
+ BT_LIB_LOGV("Set clock class's absolute property: %!+K",
+ clock_class);
+ return 0;
+}
+
+bt_uuid bt_clock_class_get_uuid(struct bt_clock_class *clock_class)
+{
+ BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+ return clock_class->uuid.value;
+}
+
+int bt_clock_class_set_uuid(struct bt_clock_class *clock_class,
+ bt_uuid uuid)
+{
+ BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+ BT_ASSERT_PRE_NON_NULL(uuid, "UUID");
+ BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
+ memcpy(clock_class->uuid.uuid, uuid, BABELTRACE_UUID_LEN);
+ clock_class->uuid.value = clock_class->uuid.uuid;
+ BT_LIB_LOGV("Set clock class's UUID: %!+K", clock_class);
+ return 0;
+}
+
+BT_HIDDEN
+void _bt_clock_class_freeze(struct bt_clock_class *clock_class)
+{
+ BT_ASSERT(clock_class);
+
+ if (clock_class->frozen) {
+ return;
+ }
+
+ BT_LIB_LOGD("Freezing clock class: %!+K", clock_class);
+ clock_class->frozen = 1;
+}
+
+int bt_clock_class_cycles_to_ns_from_origin(struct bt_clock_class *clock_class,
+ uint64_t cycles, int64_t *ns)
+{
+ int ret;
+
+ BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+ BT_ASSERT_PRE_NON_NULL(ns, "Nanoseconds (output)");
+ ret = bt_util_ns_from_origin(clock_class, cycles, ns);
+ if (ret) {
+ BT_LIB_LOGW("Cannot convert cycles to nanoseconds "
+ "from origin for given clock class: "
+ "value overflows the signed 64-bit integer range: "
+ "%![cc-]+K, cycles=%" PRIu64,
+ clock_class, cycles);
+ }
+
+ return ret;
+}
--- /dev/null
+/*
+ * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "CLOCK-VALUE"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/compat/uuid-internal.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/types.h>
+#include <babeltrace/compat/string-internal.h>
+#include <inttypes.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/assert-internal.h>
+
+BT_HIDDEN
+void bt_clock_value_destroy(struct bt_clock_value *clock_value)
+{
+ BT_LIB_LOGD("Destroying clock value: %!+k", clock_value);
+ bt_put(clock_value->clock_class);
+ g_free(clock_value);
+}
+
+BT_HIDDEN
+struct bt_clock_value *bt_clock_value_new(struct bt_clock_class *clock_class)
+{
+ struct bt_clock_value *ret = NULL;
+
+ BT_ASSERT(clock_class);
+ BT_LIB_LOGD("Creating clock value object: %![cc-]+K=",
+ clock_class);
+ ret = g_new0(struct bt_clock_value, 1);
+ if (!ret) {
+ BT_LOGE_STR("Failed to allocate one clock value.");
+ goto end;
+ }
+
+ bt_object_init_unique(&ret->base);
+ ret->clock_class = bt_get(clock_class);
+ bt_clock_class_freeze(clock_class);
+ BT_LIB_LOGD("Created clock value object: %!+k", ret);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+struct bt_clock_value *bt_clock_value_create(struct bt_clock_class *clock_class)
+{
+ struct bt_clock_value *clock_value = NULL;
+
+ BT_ASSERT(clock_class);
+ clock_value = bt_object_pool_create_object(&clock_class->cv_pool);
+ if (!clock_value) {
+ BT_LIB_LOGE("Cannot allocate one clock value from clock class's clock value pool: "
+ "%![cc-]+K", clock_class);
+ goto error;
+ }
+
+ if (likely(!clock_value->clock_class)) {
+ clock_value->clock_class = bt_get(clock_class);
+ }
+
+ goto end;
+
+error:
+ if (clock_value) {
+ bt_clock_value_recycle(clock_value);
+ clock_value = NULL;
+ }
+
+end:
+ return clock_value;
+}
+
+BT_HIDDEN
+void bt_clock_value_recycle(struct bt_clock_value *clock_value)
+{
+ struct bt_clock_class *clock_class;
+
+ BT_ASSERT(clock_value);
+ BT_LIB_LOGD("Recycling clock value: %!+k", clock_value);
+
+ /*
+ * Those are the important ordered steps:
+ *
+ * 1. Reset the clock value object, but do NOT put its clock
+ * class's reference. This clock class contains the pool to
+ * which we're about to recycle this clock value object, so
+ * we must guarantee its existence thanks to this existing
+ * reference.
+ *
+ * 2. Move the clock class reference to our `clock_class`
+ * variable so that we can set the clock value's clock class
+ * member to NULL before recycling it. We CANNOT do this
+ * after we put the clock class reference because this
+ * bt_put() could destroy the clock class, also destroying
+ * its clock value pool, thus also destroying our clock value
+ * object (this would result in an invalid write access).
+ *
+ * 3. Recycle the clock value object.
+ *
+ * 4. Put our clock class reference.
+ */
+ bt_clock_value_reset(clock_value);
+ clock_class = clock_value->clock_class;
+ BT_ASSERT(clock_class);
+ clock_value->clock_class = NULL;
+ bt_object_pool_recycle_object(&clock_class->cv_pool, clock_value);
+ bt_put(clock_class);
+}
+
+uint64_t bt_clock_value_get_value(struct bt_clock_value *clock_value)
+{
+ BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value");
+ BT_ASSERT_PRE(clock_value->is_set,
+ "Clock value is not set: %!+k", clock_value);
+ return clock_value->value_cycles;
+}
+
+int bt_clock_value_get_ns_from_origin(struct bt_clock_value *clock_value,
+ int64_t *ret_value_ns)
+{
+ int ret = 0;
+ BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value");
+ BT_ASSERT_PRE_NON_NULL(ret_value_ns, "Value (ns) (output)");
+ BT_ASSERT_PRE(clock_value->is_set,
+ "Clock value is not set: %!+k", clock_value);
+
+ if (clock_value->ns_from_origin_overflows) {
+ BT_LIB_LOGD("Clock value, once converted to nanoseconds from origin, "
+ "overflows the signed 64-bit integer range: "
+ "%![cv-]+k", clock_value);
+ ret = -1;
+ goto end;
+ }
+
+ *ret_value_ns = clock_value->ns_from_origin;
+
+end:
+ return ret;
+}
+
+struct bt_clock_class *bt_clock_value_borrow_clock_class(
+ struct bt_clock_value *clock_value)
+{
+ BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value");
+ return clock_value->clock_class;
+}
--- /dev/null
+/*
+ * event-class.c
+ *
+ * Babeltrace trace IR - Event class
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "EVENT-CLASS"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/event-class.h>
+#include <babeltrace/trace-ir/event-class-internal.h>
+#include <babeltrace/trace-ir/event-internal.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/trace-internal.h>
+#include <babeltrace/trace-ir/utils-internal.h>
+#include <babeltrace/trace-ir/resolve-field-path-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/trace-ir/attributes-internal.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/endian-internal.h>
+#include <babeltrace/types.h>
+#include <babeltrace/values-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <inttypes.h>
+#include <stdlib.h>
+
+#define BT_ASSERT_PRE_EVENT_CLASS_HOT(_ec) \
+ BT_ASSERT_PRE_HOT((_ec), "Event class", ": %!+E", (_ec))
+
+static
+void destroy_event_class(struct bt_object *obj)
+{
+ struct bt_event_class *event_class = (void *) obj;
+
+ BT_LIB_LOGD("Destroying event class: %!+E", event_class);
+
+ if (event_class->name.str) {
+ g_string_free(event_class->name.str, TRUE);
+ }
+
+ if (event_class->emf_uri.str) {
+ g_string_free(event_class->emf_uri.str, TRUE);
+ }
+
+ BT_LOGD_STR("Putting context field type.");
+ bt_put(event_class->specific_context_ft);
+ BT_LOGD_STR("Putting payload field type.");
+ bt_put(event_class->payload_ft);
+ bt_object_pool_finalize(&event_class->event_pool);
+ g_free(obj);
+}
+
+static
+void free_event(struct bt_event *event,
+ struct bt_event_class *event_class)
+{
+ bt_event_destroy(event);
+}
+
+BT_ASSERT_PRE_FUNC
+static
+bool event_class_id_is_unique(struct bt_stream_class *stream_class, uint64_t id)
+{
+ uint64_t i;
+ bool is_unique = true;
+
+ for (i = 0; i < stream_class->event_classes->len; i++) {
+ struct bt_event_class *ec =
+ stream_class->event_classes->pdata[i];
+
+ if (ec->id == id) {
+ is_unique = false;
+ goto end;
+ }
+ }
+
+end:
+ return is_unique;
+}
+
+static
+struct bt_event_class *create_event_class_with_id(
+ struct bt_stream_class *stream_class, uint64_t id)
+{
+ int ret;
+ struct bt_event_class *event_class;
+
+ BT_ASSERT(stream_class);
+ BT_ASSERT_PRE(event_class_id_is_unique(stream_class, id),
+ "Duplicate event class ID: %![sc-]+S, id=%" PRIu64,
+ stream_class, id);
+ BT_LIB_LOGD("Creating event class object: %![sc-]+S, id=%" PRIu64,
+ stream_class, id);
+ event_class = g_new0(struct bt_event_class, 1);
+ if (!event_class) {
+ BT_LOGE_STR("Failed to allocate one event class.");
+ goto error;
+ }
+
+ bt_object_init_shared_with_parent(&event_class->base,
+ destroy_event_class);
+ event_class->id = id;
+ bt_property_uint_init(&event_class->log_level,
+ BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE, 0);
+ event_class->name.str = g_string_new(NULL);
+ if (!event_class->name.str) {
+ BT_LOGE_STR("Failed to allocate a GString.");
+ ret = -1;
+ goto end;
+ }
+
+ event_class->emf_uri.str = g_string_new(NULL);
+ if (!event_class->emf_uri.str) {
+ BT_LOGE_STR("Failed to allocate a GString.");
+ ret = -1;
+ goto end;
+ }
+
+ ret = bt_object_pool_initialize(&event_class->event_pool,
+ (bt_object_pool_new_object_func) bt_event_new,
+ (bt_object_pool_destroy_object_func) free_event,
+ event_class);
+ if (ret) {
+ BT_LOGE("Failed to initialize event pool: ret=%d",
+ ret);
+ goto error;
+ }
+
+ bt_object_set_parent(&event_class->base, &stream_class->base);
+ g_ptr_array_add(stream_class->event_classes, event_class);
+ bt_stream_class_freeze(stream_class);
+ BT_LIB_LOGD("Created event class object: %!+E", event_class);
+ goto end;
+
+error:
+ BT_PUT(event_class);
+
+end:
+ return event_class;
+}
+
+struct bt_event_class *bt_event_class_create(
+ struct bt_stream_class *stream_class)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ BT_ASSERT_PRE(stream_class->assigns_automatic_event_class_id,
+ "Stream class does not automatically assigns event class IDs: "
+ "%![sc-]+S", stream_class);
+ return create_event_class_with_id(stream_class,
+ (uint64_t) stream_class->event_classes->len);
+}
+
+struct bt_event_class *bt_event_class_create_with_id(
+ struct bt_stream_class *stream_class, uint64_t id)
+{
+ BT_ASSERT_PRE(!stream_class->assigns_automatic_event_class_id,
+ "Stream class automatically assigns event class IDs: "
+ "%![sc-]+S", stream_class);
+ return create_event_class_with_id(stream_class, id);
+}
+
+const char *bt_event_class_get_name(struct bt_event_class *event_class)
+{
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+ return event_class->name.value;
+}
+
+int bt_event_class_set_name(struct bt_event_class *event_class,
+ const char *name)
+{
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
+ g_string_assign(event_class->name.str, name);
+ event_class->name.value = event_class->name.str->str;
+ BT_LIB_LOGV("Set event class's name: %!+E", event_class);
+ return 0;
+}
+
+uint64_t bt_event_class_get_id(struct bt_event_class *event_class)
+{
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+ return event_class->id;
+}
+
+enum bt_property_availability bt_event_class_get_log_level(
+ struct bt_event_class *event_class,
+ enum bt_event_class_log_level *log_level)
+{
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+ BT_ASSERT_PRE_NON_NULL(log_level, "Log level (output)");
+ *log_level = (enum bt_event_class_log_level)
+ event_class->log_level.value;
+ return event_class->log_level.base.avail;
+}
+
+int bt_event_class_set_log_level(struct bt_event_class *event_class,
+ enum bt_event_class_log_level log_level)
+{
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+ BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
+ bt_property_uint_set(&event_class->log_level,
+ (uint64_t) log_level);
+ BT_LIB_LOGV("Set event class's log level: %!+E", event_class);
+ return 0;
+}
+
+const char *bt_event_class_get_emf_uri(struct bt_event_class *event_class)
+{
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+ return event_class->emf_uri.value;
+}
+
+int bt_event_class_set_emf_uri(struct bt_event_class *event_class,
+ const char *emf_uri)
+{
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+ BT_ASSERT_PRE_NON_NULL(emf_uri, "EMF URI");
+ BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
+ g_string_assign(event_class->emf_uri.str, emf_uri);
+ event_class->emf_uri.value = event_class->emf_uri.str->str;
+ BT_LIB_LOGV("Set event class's EMF URI: %!+E", event_class);
+ return 0;
+}
+
+struct bt_stream_class *bt_event_class_borrow_stream_class(
+ struct bt_event_class *event_class)
+{
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+ return bt_event_class_borrow_stream_class_inline(event_class);
+}
+
+struct bt_field_type *bt_event_class_borrow_specific_context_field_type(
+ struct bt_event_class *event_class)
+{
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+ return event_class->specific_context_ft;
+}
+
+int bt_event_class_set_specific_context_field_type(
+ struct bt_event_class *event_class,
+ struct bt_field_type *field_type)
+{
+ int ret;
+ struct bt_stream_class *stream_class;
+ struct bt_trace *trace;
+ struct bt_resolve_field_path_context resolve_ctx = {
+ .packet_header = NULL,
+ .packet_context = NULL,
+ .event_header = NULL,
+ .event_common_context = NULL,
+ .event_specific_context = field_type,
+ .event_payload = NULL,
+ };
+
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+ BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
+ BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
+ BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
+ BT_FIELD_TYPE_ID_STRUCTURE,
+ "Specific context field type is not a structure field type: "
+ "%!+F", field_type);
+ stream_class = bt_event_class_borrow_stream_class_inline(
+ event_class);
+ trace = bt_stream_class_borrow_trace_inline(stream_class);
+ resolve_ctx.packet_header = trace->packet_header_ft;
+ resolve_ctx.packet_context = stream_class->packet_context_ft;
+ resolve_ctx.event_header = stream_class->event_header_ft;
+ resolve_ctx.event_common_context =
+ stream_class->event_common_context_ft;
+
+ ret = bt_resolve_field_paths(field_type, &resolve_ctx);
+ if (ret) {
+ goto end;
+ }
+
+ bt_field_type_make_part_of_trace(field_type);
+ bt_put(event_class->specific_context_ft);
+ event_class->specific_context_ft = bt_get(field_type);
+ bt_field_type_freeze(field_type);
+ BT_LIB_LOGV("Set event class's specific context field type: %!+E",
+ event_class);
+
+end:
+ return ret;
+}
+
+struct bt_field_type *bt_event_class_borrow_payload_field_type(
+ struct bt_event_class *event_class)
+{
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+ return event_class->payload_ft;
+}
+
+int bt_event_class_set_payload_field_type(struct bt_event_class *event_class,
+ struct bt_field_type *field_type)
+{
+ int ret;
+ struct bt_stream_class *stream_class;
+ struct bt_trace *trace;
+ struct bt_resolve_field_path_context resolve_ctx = {
+ .packet_header = NULL,
+ .packet_context = NULL,
+ .event_header = NULL,
+ .event_common_context = NULL,
+ .event_specific_context = NULL,
+ .event_payload = field_type,
+ };
+
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+ BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
+ BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
+ BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
+ BT_FIELD_TYPE_ID_STRUCTURE,
+ "Payload field type is not a structure field type: %!+F",
+ field_type);
+ stream_class = bt_event_class_borrow_stream_class_inline(
+ event_class);
+ trace = bt_stream_class_borrow_trace_inline(stream_class);
+ resolve_ctx.packet_header = trace->packet_header_ft;
+ resolve_ctx.packet_context = stream_class->packet_context_ft;
+ resolve_ctx.event_header = stream_class->event_header_ft;
+ resolve_ctx.event_common_context =
+ stream_class->event_common_context_ft;
+ resolve_ctx.event_specific_context = event_class->specific_context_ft;
+
+ ret = bt_resolve_field_paths(field_type, &resolve_ctx);
+ if (ret) {
+ goto end;
+ }
+
+ bt_field_type_make_part_of_trace(field_type);
+ bt_put(event_class->payload_ft);
+ event_class->payload_ft = bt_get(field_type);
+ bt_field_type_freeze(field_type);
+ BT_LIB_LOGV("Set event class's payload field type: %!+E", event_class);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+void _bt_event_class_freeze(struct bt_event_class *event_class)
+{
+ /* The field types are already frozen */
+ BT_ASSERT(event_class);
+ BT_LIB_LOGD("Freezing event class: %!+E", event_class);
+ event_class->frozen = true;
+}
--- /dev/null
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "EVENT-HEADER-FIELD"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/event-header-field.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/field-wrapper-internal.h>
+#include <glib.h>
+
+struct bt_field *bt_event_header_field_borrow_field(
+ struct bt_event_header_field *header_field)
+{
+ struct bt_field_wrapper *field_wrapper = (void *) header_field;
+
+ BT_ASSERT_PRE_NON_NULL(field_wrapper, "Event header field");
+ return (void *) field_wrapper->field;
+}
+
+void bt_event_header_field_release(struct bt_event_header_field *header_field)
+{
+ struct bt_field_wrapper *field_wrapper = (void *) header_field;
+
+ BT_ASSERT_PRE_NON_NULL(field_wrapper, "Event header field");
+
+ /*
+ * Do not recycle because the pool could be destroyed at this
+ * point. This function is only called when there's an error
+ * anyway because the goal of an event header field wrapper is
+ * to eventually move it to an event with bt_event_move_header()
+ * after creating it.
+ */
+ bt_field_wrapper_destroy(field_wrapper);
+}
+
+struct bt_event_header_field *bt_event_header_field_create(
+ struct bt_stream_class *stream_class)
+{
+ struct bt_field_wrapper *field_wrapper;
+
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ BT_ASSERT_PRE(bt_stream_class_borrow_trace_inline(stream_class),
+ "Stream class is not part of a trace: %!+S", stream_class);
+ BT_ASSERT_PRE(stream_class->event_header_ft,
+ "Stream class has no event header field type: %!+S",
+ stream_class);
+ field_wrapper = bt_field_wrapper_create(
+ &stream_class->event_header_field_pool,
+ (void *) stream_class->event_header_ft);
+ if (!field_wrapper) {
+ BT_LIB_LOGE("Cannot allocate one event header field from stream class: "
+ "%![sc-]+S", stream_class);
+ goto error;
+ }
+
+ BT_ASSERT(field_wrapper->field);
+ bt_stream_class_freeze(stream_class);
+ goto end;
+
+error:
+ if (field_wrapper) {
+ bt_field_wrapper_destroy(field_wrapper);
+ field_wrapper = NULL;
+ }
+
+end:
+ return (void *) field_wrapper;
+}
--- /dev/null
+/*
+ * event.c
+ *
+ * Babeltrace trace IR - Event
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "EVENT"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/clock-class.h>
+#include <babeltrace/trace-ir/clock-value.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/trace-ir/event-internal.h>
+#include <babeltrace/trace-ir/event-class.h>
+#include <babeltrace/trace-ir/event-class-internal.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/stream-internal.h>
+#include <babeltrace/trace-ir/packet.h>
+#include <babeltrace/trace-ir/packet-internal.h>
+#include <babeltrace/trace-ir/trace.h>
+#include <babeltrace/trace-ir/trace-internal.h>
+#include <babeltrace/trace-ir/packet-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/trace-ir/attributes-internal.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <inttypes.h>
+
+BT_HIDDEN
+void _bt_event_set_is_frozen(struct bt_event *event, bool is_frozen)
+{
+ BT_ASSERT(event);
+ BT_LIB_LOGD("Setting event's frozen state: %!+e, is-frozen=%d",
+ event, is_frozen);
+
+ if (event->header_field) {
+ BT_LOGD_STR("Setting event's header field's frozen state.");
+ bt_field_set_is_frozen(
+ event->header_field->field, is_frozen);
+ }
+
+ if (event->common_context_field) {
+ BT_LOGD_STR("Setting event's common context field's frozen state.");
+ bt_field_set_is_frozen(
+ event->common_context_field, is_frozen);
+ }
+
+ if (event->specific_context_field) {
+ BT_LOGD_STR("Setting event's specific context field's frozen state.");
+ bt_field_set_is_frozen(event->specific_context_field,
+ is_frozen);
+ }
+
+ if (event->payload_field) {
+ BT_LOGD_STR("Setting event's payload field's frozen state.");
+ bt_field_set_is_frozen(event->payload_field,
+ is_frozen);
+ }
+
+ event->frozen = is_frozen;
+ BT_LOGD_STR("Setting event's packet's frozen state.");
+ bt_packet_set_is_frozen(event->packet, is_frozen);
+}
+
+static
+void recycle_event_header_field(struct bt_field_wrapper *field_wrapper,
+ struct bt_stream_class *stream_class)
+{
+ BT_ASSERT(field_wrapper);
+ BT_LIB_LOGD("Recycling event header field: "
+ "addr=%p, %![sc-]+S, %![field-]+f", field_wrapper,
+ stream_class, field_wrapper->field);
+ bt_object_pool_recycle_object(
+ &stream_class->event_header_field_pool,
+ field_wrapper);
+}
+
+static inline
+struct bt_field_wrapper *create_event_header_field(
+ struct bt_stream_class *stream_class)
+{
+ struct bt_field_wrapper *field_wrapper = NULL;
+
+ field_wrapper = bt_field_wrapper_create(
+ &stream_class->event_header_field_pool,
+ bt_stream_class_borrow_event_header_field_type(stream_class));
+ if (!field_wrapper) {
+ goto error;
+ }
+
+ goto end;
+
+error:
+ if (field_wrapper) {
+ recycle_event_header_field(field_wrapper, stream_class);
+ field_wrapper = NULL;
+ }
+
+end:
+ return field_wrapper;
+}
+
+BT_HIDDEN
+struct bt_event *bt_event_new(struct bt_event_class *event_class)
+{
+ struct bt_event *event = NULL;
+ struct bt_stream_class *stream_class;
+ struct bt_field_type *ft;
+
+ BT_ASSERT(event_class);
+ event = g_new0(struct bt_event, 1);
+ if (!event) {
+ BT_LOGE_STR("Failed to allocate one event.");
+ goto error;
+ }
+
+ bt_object_init_unique(&event->base);
+ stream_class = bt_event_class_borrow_stream_class(event_class);
+ BT_ASSERT(stream_class);
+
+ if (bt_stream_class_borrow_event_header_field_type(stream_class)) {
+ event->header_field = create_event_header_field(stream_class);
+ if (!event->header_field) {
+ BT_LOGE_STR("Cannot create event header field.");
+ goto error;
+ }
+ }
+
+ ft = bt_stream_class_borrow_event_common_context_field_type(
+ stream_class);
+ if (ft) {
+ event->common_context_field = bt_field_create(ft);
+ if (!event->common_context_field) {
+ /* bt_field_create() logs errors */
+ goto error;
+ }
+ }
+
+ ft = bt_event_class_borrow_specific_context_field_type(event_class);
+ if (ft) {
+ event->specific_context_field = bt_field_create(ft);
+ if (!event->specific_context_field) {
+ /* bt_field_create() logs errors */
+ goto error;
+ }
+ }
+
+ ft = bt_event_class_borrow_payload_field_type(event_class);
+ if (ft) {
+ event->payload_field = bt_field_create(ft);
+ if (!event->payload_field) {
+ /* bt_field_create() logs errors */
+ goto error;
+ }
+ }
+
+ if (stream_class->default_clock_class) {
+ event->default_cv = bt_clock_value_create(
+ stream_class->default_clock_class);
+ if (!event->default_cv) {
+ /* bt_clock_value_create() logs errors */
+ goto error;
+ }
+ }
+
+ goto end;
+
+error:
+ if (event) {
+ bt_event_destroy(event);
+ event = NULL;
+ }
+
+end:
+ return event;
+}
+
+struct bt_event_class *bt_event_borrow_class(struct bt_event *event)
+{
+ BT_ASSERT_PRE_NON_NULL(event, "Event");
+ return event->class;
+}
+
+struct bt_stream *bt_event_borrow_stream(struct bt_event *event)
+{
+ BT_ASSERT_PRE_NON_NULL(event, "Event");
+ return event->packet ? event->packet->stream : NULL;
+}
+
+struct bt_field *bt_event_borrow_header_field(struct bt_event *event)
+{
+ BT_ASSERT_PRE_NON_NULL(event, "Event");
+ return event->header_field ? event->header_field->field : NULL;
+}
+
+struct bt_field *bt_event_borrow_common_context_field(struct bt_event *event)
+{
+ BT_ASSERT_PRE_NON_NULL(event, "Event");
+ return event->common_context_field;
+}
+
+struct bt_field *bt_event_borrow_specific_context_field(struct bt_event *event)
+{
+ BT_ASSERT_PRE_NON_NULL(event, "Event");
+ return event->specific_context_field;
+}
+
+struct bt_field *bt_event_borrow_payload_field(struct bt_event *event)
+{
+ BT_ASSERT_PRE_NON_NULL(event, "Event");
+ return event->payload_field;
+}
+
+static
+void release_event_header_field(struct bt_field_wrapper *field_wrapper,
+ struct bt_event *event)
+{
+ if (!event->class) {
+ bt_field_wrapper_destroy(field_wrapper);
+ } else {
+ struct bt_stream_class *stream_class =
+ bt_event_class_borrow_stream_class(event->class);
+
+ BT_ASSERT(stream_class);
+ recycle_event_header_field(field_wrapper, stream_class);
+ }
+}
+
+BT_HIDDEN
+void bt_event_destroy(struct bt_event *event)
+{
+ BT_ASSERT(event);
+ BT_LIB_LOGD("Destroying event: %!+e", event);
+
+ if (event->header_field) {
+ BT_LOGD_STR("Releasing event's header field.");
+ release_event_header_field(event->header_field, event);
+ }
+
+ if (event->common_context_field) {
+ BT_LOGD_STR("Destroying event's stream event context field.");
+ bt_field_destroy(event->common_context_field);
+ }
+
+ if (event->specific_context_field) {
+ BT_LOGD_STR("Destroying event's context field.");
+ bt_field_destroy(event->specific_context_field);
+ }
+
+ if (event->payload_field) {
+ BT_LOGD_STR("Destroying event's payload field.");
+ bt_field_destroy(event->payload_field);
+ }
+
+ BT_LOGD_STR("Putting event's class.");
+ bt_put(event->class);
+
+ if (event->default_cv) {
+ bt_clock_value_recycle(event->default_cv);
+ }
+
+ BT_LOGD_STR("Putting event's packet.");
+ bt_put(event->packet);
+ g_free(event);
+}
+
+int bt_event_set_default_clock_value(struct bt_event *event,
+ uint64_t value_cycles)
+{
+ struct bt_stream_class *sc;
+
+ BT_ASSERT_PRE_NON_NULL(event, "Event");
+ BT_ASSERT_PRE_EVENT_HOT(event);
+ sc = bt_event_class_borrow_stream_class_inline(event->class);
+ BT_ASSERT(sc);
+ BT_ASSERT_PRE(sc->default_clock_class,
+ "Event's stream class has no default clock class: "
+ "%![ev-]+e, %![sc-]+S", event, sc);
+ BT_ASSERT(event->default_cv);
+ bt_clock_value_set_value_inline(event->default_cv, value_cycles);
+ BT_LIB_LOGV("Set event's default clock value: %![event-]+e, "
+ "value=%" PRIu64, event, value_cycles);
+ return 0;
+}
+
+enum bt_clock_value_status bt_event_borrow_default_clock_value(
+ struct bt_event *event, struct bt_clock_value **clock_value)
+{
+ BT_ASSERT_PRE_NON_NULL(event, "Event");
+ BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value (output)");
+ *clock_value = event->default_cv;
+ return BT_CLOCK_VALUE_STATUS_KNOWN;
+}
+
+struct bt_packet *bt_event_borrow_packet(struct bt_event *event)
+{
+ BT_ASSERT_PRE_NON_NULL(event, "Event");
+ return event->packet;
+}
+
+int bt_event_move_header(struct bt_event *event,
+ struct bt_event_header_field *header_field)
+{
+ struct bt_stream_class *stream_class;
+ struct bt_field_wrapper *field_wrapper = (void *) header_field;
+
+ BT_ASSERT_PRE_NON_NULL(event, "Event");
+ BT_ASSERT_PRE_NON_NULL(field_wrapper, "Header field");
+ BT_ASSERT_PRE_EVENT_HOT(event);
+ stream_class = bt_event_class_borrow_stream_class_inline(event->class);
+ BT_ASSERT_PRE(stream_class->event_header_ft,
+ "Stream class has no event header field type: %!+S",
+ stream_class);
+
+ /* Recycle current header field: always exists */
+ BT_ASSERT(event->header_field);
+ recycle_event_header_field(event->header_field, stream_class);
+
+ /* Move new field */
+ event->header_field = field_wrapper;
+ return 0;
+}
--- /dev/null
+/*
+ * field-path.c
+ *
+ * Babeltrace trace IR - Field path
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "FIELD-PATH"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/field-path-internal.h>
+#include <babeltrace/trace-ir/field-path.h>
+#include <limits.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <babeltrace/assert-internal.h>
+#include <glib.h>
+
+static
+void destroy_field_path(struct bt_object *obj)
+{
+ struct bt_field_path *field_path = (struct bt_field_path *) obj;
+
+ BT_ASSERT(field_path);
+ BT_LIB_LOGD("Destroying field path: %!+P", field_path);
+ g_array_free(field_path->indexes, TRUE);
+ g_free(field_path);
+}
+
+BT_HIDDEN
+struct bt_field_path *bt_field_path_create(void)
+{
+ struct bt_field_path *field_path = NULL;
+
+ BT_LOGD_STR("Creating empty field path object.");
+
+ field_path = g_new0(struct bt_field_path, 1);
+ if (!field_path) {
+ BT_LOGE_STR("Failed to allocate one field path.");
+ goto error;
+ }
+
+ bt_object_init_shared(&field_path->base, destroy_field_path);
+ field_path->indexes = g_array_new(FALSE, FALSE, sizeof(uint64_t));
+ if (!field_path->indexes) {
+ BT_LOGE_STR("Failed to allocate a GArray.");
+ goto error;
+ }
+
+ BT_LIB_LOGD("Created empty field path object: %!+P", field_path);
+ goto end;
+
+error:
+ BT_PUT(field_path);
+
+end:
+ return field_path;
+}
+
+enum bt_scope bt_field_path_get_root_scope(struct bt_field_path *field_path)
+{
+ BT_ASSERT_PRE_NON_NULL(field_path, "Field path");
+ return field_path->root;
+}
+
+uint64_t bt_field_path_get_index_count(struct bt_field_path *field_path)
+{
+ BT_ASSERT_PRE_NON_NULL(field_path, "Field path");
+ return (uint64_t) field_path->indexes->len;
+}
+
+uint64_t bt_field_path_get_index_by_index(struct bt_field_path *field_path,
+ uint64_t index)
+{
+ BT_ASSERT_PRE_NON_NULL(field_path, "Field path");
+ BT_ASSERT_PRE_VALID_INDEX(index, field_path->indexes->len);
+ return bt_field_path_get_index_by_index_inline(field_path, index);
+}
--- /dev/null
+/*
+ * field-types.c
+ *
+ * Babeltrace trace IR - Event Types
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "FIELD-TYPES"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/field-path-internal.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/trace-ir/utils-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/trace-ir/clock-class.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/endian-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/compat/glib-internal.h>
+#include <float.h>
+#include <inttypes.h>
+#include <stdlib.h>
+
+enum bt_field_type_id bt_field_type_get_type_id(struct bt_field_type *ft)
+{
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ return ft->id;
+}
+
+static
+void init_field_type(struct bt_field_type *ft, enum bt_field_type_id id,
+ bt_object_release_func release_func)
+{
+ BT_ASSERT(ft);
+ BT_ASSERT(bt_field_type_has_known_id(ft));
+ BT_ASSERT(release_func);
+ bt_object_init_shared(&ft->base, release_func);
+ ft->id = id;
+}
+
+static
+void init_integer_field_type(struct bt_field_type_integer *ft, enum bt_field_type_id id,
+ bt_object_release_func release_func)
+{
+ init_field_type((void *) ft, id, release_func);
+ ft->range = 64;
+ ft->base = BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
+}
+
+static
+void destroy_integer_field_type(struct bt_object *obj)
+{
+ BT_ASSERT(obj);
+ BT_LIB_LOGD("Destroying integer field type object: %!+F", obj);
+ g_free(obj);
+}
+
+static inline
+struct bt_field_type *create_integer_field_type(enum bt_field_type_id id)
+{
+ struct bt_field_type_integer *int_ft = NULL;
+
+ BT_LOGD("Creating default integer field type object: id=%s",
+ bt_common_field_type_id_string(id));
+ int_ft = g_new0(struct bt_field_type_integer, 1);
+ if (!int_ft) {
+ BT_LOGE_STR("Failed to allocate one integer field type.");
+ goto error;
+ }
+
+ init_integer_field_type(int_ft, id, destroy_integer_field_type);
+ BT_LIB_LOGD("Created integer field type object: %!+F", int_ft);
+ goto end;
+
+error:
+ BT_PUT(int_ft);
+
+end:
+ return (void *) int_ft;
+}
+
+struct bt_field_type *bt_field_type_unsigned_integer_create(void)
+{
+ return create_integer_field_type(BT_FIELD_TYPE_ID_UNSIGNED_INTEGER);
+}
+
+struct bt_field_type *bt_field_type_signed_integer_create(void)
+{
+ return create_integer_field_type(BT_FIELD_TYPE_ID_SIGNED_INTEGER);
+}
+
+uint64_t bt_field_type_integer_get_field_value_range(
+ struct bt_field_type *ft)
+{
+ struct bt_field_type_integer *int_ft = (void *) ft;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_IS_INT(ft, "Field type");
+ return int_ft->range;
+}
+
+BT_ASSERT_PRE_FUNC
+static
+bool size_is_valid_for_enumeration_field_type(struct bt_field_type *ft,
+ uint64_t size)
+{
+ // TODO
+ return true;
+}
+
+int bt_field_type_integer_set_field_value_range(
+ struct bt_field_type *ft, uint64_t size)
+{
+ struct bt_field_type_integer *int_ft = (void *) ft;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_IS_INT(ft, "Field type");
+ BT_ASSERT_PRE_FT_HOT(ft, "Field type");
+ BT_ASSERT_PRE(size <= 64,
+ "Unsupported size for integer field type's field value range "
+ "(maximum is 64): size=%" PRIu64, size);
+ BT_ASSERT_PRE(int_ft->common.id == BT_FIELD_TYPE_ID_UNSIGNED_INTEGER ||
+ int_ft->common.id == BT_FIELD_TYPE_ID_SIGNED_INTEGER ||
+ size_is_valid_for_enumeration_field_type(ft, size),
+ "Invalid field value range for enumeration field type: "
+ "at least one of the current mapping ranges contains values "
+ "which are outside this range: %!+F, size=%" PRIu64, ft, size);
+ int_ft->range = size;
+ BT_LIB_LOGV("Set integer field type's field value range: %!+F", ft);
+ return 0;
+}
+
+enum bt_field_type_integer_preferred_display_base
+bt_field_type_integer_get_preferred_display_base(struct bt_field_type *ft)
+{
+ struct bt_field_type_integer *int_ft = (void *) ft;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_IS_INT(ft, "Field type");
+ return int_ft->base;
+}
+
+int bt_field_type_integer_set_preferred_display_base(struct bt_field_type *ft,
+ enum bt_field_type_integer_preferred_display_base base)
+{
+ struct bt_field_type_integer *int_ft = (void *) ft;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_IS_INT(ft, "Field type");
+ BT_ASSERT_PRE_FT_HOT(ft, "Field type");
+ int_ft->base = base;
+ BT_LIB_LOGV("Set integer field type's preferred display base: %!+F", ft);
+ return 0;
+}
+
+static
+void finalize_enumeration_field_type_mapping(
+ struct bt_field_type_enumeration_mapping *mapping)
+{
+ BT_ASSERT(mapping);
+
+ if (mapping->label) {
+ g_string_free(mapping->label, TRUE);
+ }
+
+ if (mapping->ranges) {
+ g_array_free(mapping->ranges, TRUE);
+ }
+}
+
+static
+void destroy_enumeration_field_type(struct bt_object *obj)
+{
+ struct bt_field_type_enumeration *ft = (void *) obj;
+
+ BT_ASSERT(ft);
+ BT_LIB_LOGD("Destroying enumeration field type object: %!+F", ft);
+
+ if (ft->mappings) {
+ uint64_t i;
+
+ for (i = 0; i < ft->mappings->len; i++) {
+ finalize_enumeration_field_type_mapping(
+ BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(ft, i));
+ }
+
+ g_array_free(ft->mappings, TRUE);
+ }
+
+ if (ft->label_buf) {
+ g_ptr_array_free(ft->label_buf, TRUE);
+ }
+
+ g_free(ft);
+}
+
+static
+struct bt_field_type *create_enumeration_field_type(enum bt_field_type_id id)
+{
+ struct bt_field_type_enumeration *enum_ft = NULL;
+
+ BT_LOGD("Creating default enumeration field type object: id=%s",
+ bt_common_field_type_id_string(id));
+ enum_ft = g_new0(struct bt_field_type_enumeration, 1);
+ if (!enum_ft) {
+ BT_LOGE_STR("Failed to allocate one enumeration field type.");
+ goto error;
+ }
+
+ init_integer_field_type((void *) enum_ft, id,
+ destroy_enumeration_field_type);
+ enum_ft->mappings = g_array_new(FALSE, TRUE,
+ sizeof(struct bt_field_type_enumeration_mapping));
+ if (!enum_ft->mappings) {
+ BT_LOGE_STR("Failed to allocate a GArray.");
+ goto error;
+ }
+
+ enum_ft->label_buf = g_ptr_array_new();
+ if (!enum_ft->label_buf) {
+ BT_LOGE_STR("Failed to allocate a GArray.");
+ goto error;
+ }
+
+ BT_LIB_LOGD("Created enumeration field type object: %!+F", enum_ft);
+ goto end;
+
+error:
+ BT_PUT(enum_ft);
+
+end:
+ return (void *) enum_ft;
+}
+
+struct bt_field_type *bt_field_type_unsigned_enumeration_create(void)
+{
+ return create_enumeration_field_type(
+ BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION);
+}
+
+struct bt_field_type *bt_field_type_signed_enumeration_create(void)
+{
+ return create_enumeration_field_type(
+ BT_FIELD_TYPE_ID_SIGNED_ENUMERATION);
+}
+
+uint64_t bt_field_type_enumeration_get_mapping_count(struct bt_field_type *ft)
+{
+ struct bt_field_type_enumeration *enum_ft = (void *) ft;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_IS_ENUM(ft, "Field type");
+ return (uint64_t) enum_ft->mappings->len;
+}
+
+void bt_field_type_unsigned_enumeration_borrow_mapping_by_index(
+ struct bt_field_type *ft, uint64_t index,
+ const char **name,
+ struct bt_field_type_unsigned_enumeration_mapping_ranges **ranges)
+{
+ struct bt_field_type_enumeration *enum_ft = (void *) ft;
+ struct bt_field_type_enumeration_mapping *mapping;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_NON_NULL(name, "Name (output)");
+ BT_ASSERT_PRE_NON_NULL(ranges, "Ranges (output)");
+ BT_ASSERT_PRE_VALID_INDEX(index, enum_ft->mappings->len);
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION,
+ "Field type");
+ mapping = BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(ft, index);
+ *name = mapping->label->str;
+ *ranges = (void *) mapping;
+}
+
+void bt_field_type_signed_enumeration_borrow_mapping_by_index(
+ struct bt_field_type *ft, uint64_t index,
+ const char **name,
+ struct bt_field_type_signed_enumeration_mapping_ranges **ranges)
+{
+ struct bt_field_type_enumeration *enum_ft = (void *) ft;
+ struct bt_field_type_enumeration_mapping *mapping;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_NON_NULL(name, "Name (output)");
+ BT_ASSERT_PRE_NON_NULL(ranges, "Ranges (output)");
+ BT_ASSERT_PRE_VALID_INDEX(index, enum_ft->mappings->len);
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_SIGNED_ENUMERATION,
+ "Field type");
+ mapping = BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(ft, index);
+ *name = mapping->label->str;
+ *ranges = (void *) mapping;
+}
+
+static inline
+uint64_t get_enumeration_field_type_mapping_range_count(
+ struct bt_field_type_enumeration_mapping *mapping)
+{
+ BT_ASSERT_PRE_NON_NULL(mapping, "Ranges");
+ return (uint64_t) mapping->ranges->len;
+}
+
+uint64_t bt_field_type_unsigned_enumeration_mapping_ranges_get_range_count(
+ struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges)
+{
+ return get_enumeration_field_type_mapping_range_count((void *) ranges);
+}
+
+uint64_t bt_field_type_signed_enumeration_mapping_ranges_get_range_count(
+ struct bt_field_type_signed_enumeration_mapping_ranges *ranges)
+{
+ return get_enumeration_field_type_mapping_range_count((void *) ranges);
+}
+
+static inline
+void get_enumeration_field_type_mapping_range_at_index(
+ struct bt_field_type_enumeration_mapping *mapping,
+ uint64_t index, uint64_t *lower, uint64_t *upper)
+{
+ struct bt_field_type_enumeration_mapping_range *range;
+
+ BT_ASSERT_PRE_NON_NULL(mapping, "Ranges");
+ BT_ASSERT_PRE_NON_NULL(lower, "Range's lower (output)");
+ BT_ASSERT_PRE_NON_NULL(upper, "Range's upper (output)");
+ BT_ASSERT_PRE_VALID_INDEX(index, mapping->ranges->len);
+ range = BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(mapping, index);
+ *lower = range->lower.u;
+ *upper = range->upper.u;
+}
+
+void bt_field_type_unsigned_enumeration_mapping_ranges_get_range_by_index(
+ struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges,
+ uint64_t index, uint64_t *lower, uint64_t *upper)
+{
+ get_enumeration_field_type_mapping_range_at_index((void *) ranges,
+ index, lower, upper);
+}
+
+void bt_field_type_signed_enumeration_mapping_ranges_get_range_by_index(
+ struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges,
+ uint64_t index, int64_t *lower, int64_t *upper)
+{
+ get_enumeration_field_type_mapping_range_at_index((void *) ranges,
+ index, (uint64_t *) lower, (uint64_t *) upper);
+}
+
+
+
+int bt_field_type_unsigned_enumeration_get_mapping_labels_by_value(
+ struct bt_field_type *ft, uint64_t value,
+ bt_field_type_enumeration_mapping_label_array *label_array,
+ uint64_t *count)
+{
+ struct bt_field_type_enumeration *enum_ft = (void *) ft;
+ uint64_t i;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)");
+ BT_ASSERT_PRE_NON_NULL(count, "Count (output)");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION,
+ "Field type");
+ g_ptr_array_set_size(enum_ft->label_buf, 0);
+
+ for (i = 0; i < enum_ft->mappings->len; i++) {
+ uint64_t j;
+ struct bt_field_type_enumeration_mapping *mapping =
+ BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft, i);
+
+ for (j = 0; j < mapping->ranges->len; j++) {
+ struct bt_field_type_enumeration_mapping_range *range =
+ BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(
+ mapping, j);
+
+ if (value >= range->lower.u &&
+ value <= range->upper.u) {
+ g_ptr_array_add(enum_ft->label_buf,
+ mapping->label->str);
+ break;
+ }
+ }
+ }
+
+ *label_array = (void *) enum_ft->label_buf->pdata;
+ *count = (uint64_t) enum_ft->label_buf->len;
+ return 0;
+}
+
+int bt_field_type_signed_enumeration_get_mapping_labels_by_value(
+ struct bt_field_type *ft, int64_t value,
+ bt_field_type_enumeration_mapping_label_array *label_array,
+ uint64_t *count)
+{
+ struct bt_field_type_enumeration *enum_ft = (void *) ft;
+ uint64_t i;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)");
+ BT_ASSERT_PRE_NON_NULL(count, "Count (output)");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_SIGNED_ENUMERATION,
+ "Field type");
+ g_ptr_array_set_size(enum_ft->label_buf, 0);
+
+ for (i = 0; i < enum_ft->mappings->len; i++) {
+ uint64_t j;
+ struct bt_field_type_enumeration_mapping *mapping =
+ BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft, i);
+
+ for (j = 0; j < mapping->ranges->len; j++) {
+ struct bt_field_type_enumeration_mapping_range *range =
+ BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(
+ mapping, j);
+
+ if (value >= range->lower.i &&
+ value <= range->upper.i) {
+ g_ptr_array_add(enum_ft->label_buf,
+ mapping->label->str);
+ break;
+ }
+ }
+ }
+
+ *label_array = (void *) enum_ft->label_buf->pdata;
+ *count = (uint64_t) enum_ft->label_buf->len;
+ return 0;
+}
+
+static inline
+int add_mapping_to_enumeration_field_type(struct bt_field_type *ft,
+ const char *label, uint64_t lower, uint64_t upper)
+{
+ int ret = 0;
+ uint64_t i;
+ struct bt_field_type_enumeration *enum_ft = (void *) ft;
+ struct bt_field_type_enumeration_mapping *mapping = NULL;
+ struct bt_field_type_enumeration_mapping_range *range;
+
+ BT_ASSERT(ft);
+ BT_ASSERT_PRE_NON_NULL(label, "Label");
+
+ /* Find existing mapping identified by this label */
+ for (i = 0; i < enum_ft->mappings->len; i++) {
+ struct bt_field_type_enumeration_mapping *mapping_candidate =
+ BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft, i);
+
+ if (strcmp(mapping_candidate->label->str, label) == 0) {
+ mapping = mapping_candidate;
+ break;
+ }
+ }
+
+ if (!mapping) {
+ /* Create new mapping for this label */
+ g_array_set_size(enum_ft->mappings, enum_ft->mappings->len + 1);
+ mapping = BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft,
+ enum_ft->mappings->len - 1);
+ mapping->ranges = g_array_new(FALSE, TRUE,
+ sizeof(struct bt_field_type_enumeration_mapping_range));
+ if (!mapping->ranges) {
+ finalize_enumeration_field_type_mapping(mapping);
+ g_array_set_size(enum_ft->mappings,
+ enum_ft->mappings->len - 1);
+ ret = -1;
+ goto end;
+ }
+
+ mapping->label = g_string_new(label);
+ if (!mapping->label) {
+ finalize_enumeration_field_type_mapping(mapping);
+ g_array_set_size(enum_ft->mappings,
+ enum_ft->mappings->len - 1);
+ ret = -1;
+ goto end;
+ }
+ }
+
+ /* Add range */
+ BT_ASSERT(mapping);
+ g_array_set_size(mapping->ranges, mapping->ranges->len + 1);
+ range = BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(mapping,
+ mapping->ranges->len - 1);
+ range->lower.u = lower;
+ range->upper.u = upper;
+ BT_LIB_LOGV("Added mapping to enumeration field type: "
+ "%![ft-]+F, label=\"%s\", lower-unsigned=%" PRIu64 ", "
+ "upper-unsigned=%" PRIu64, ft, label, lower, upper);
+
+end:
+ return ret;
+}
+
+int bt_field_type_unsigned_enumeration_map_range(
+ struct bt_field_type *ft, const char *label,
+ uint64_t range_lower, uint64_t range_upper)
+{
+ struct bt_field_type_enumeration *enum_ft = (void *) ft;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION,
+ "Field type");
+ BT_ASSERT_PRE(range_lower <= range_upper,
+ "Range's upper bound is less than lower bound: "
+ "upper=%" PRIu64 ", lower=%" PRIu64,
+ range_lower, range_upper);
+ BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_ft->common.range,
+ range_lower),
+ "Range's lower bound is outside the enumeration field type's value range: "
+ "%![ft-]+F, lower=%" PRIu64, ft, range_lower);
+ BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_ft->common.range,
+ range_upper),
+ "Range's upper bound is outside the enumeration field type's value range: "
+ "%![ft-]+F, upper=%" PRIu64, ft, range_upper);
+ return add_mapping_to_enumeration_field_type(ft, label, range_lower,
+ range_upper);
+}
+
+int bt_field_type_signed_enumeration_map_range(
+ struct bt_field_type *ft, const char *label,
+ int64_t range_lower, int64_t range_upper)
+{
+ struct bt_field_type_enumeration *enum_ft = (void *) ft;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_SIGNED_ENUMERATION,
+ "Field type");
+ BT_ASSERT_PRE(range_lower <= range_upper,
+ "Range's upper bound is less than lower bound: "
+ "upper=%" PRId64 ", lower=%" PRId64,
+ range_lower, range_upper);
+ BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_ft->common.range,
+ range_lower),
+ "Range's lower bound is outside the enumeration field type's value range: "
+ "%![ft-]+F, lower=%" PRId64, ft, range_lower);
+ BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_ft->common.range,
+ range_upper),
+ "Range's upper bound is outside the enumeration field type's value range: "
+ "%![ft-]+F, upper=%" PRId64, ft, range_upper);
+ return add_mapping_to_enumeration_field_type(ft, label, range_lower,
+ range_upper);
+}
+
+static
+void destroy_real_field_type(struct bt_object *obj)
+{
+ BT_ASSERT(obj);
+ BT_LIB_LOGD("Destroying real field type object: %!+F", obj);
+ g_free(obj);
+}
+
+struct bt_field_type *bt_field_type_real_create(void)
+{
+ struct bt_field_type_real *real_ft = NULL;
+
+ BT_LOGD_STR("Creating default real field type object.");
+ real_ft = g_new0(struct bt_field_type_real, 1);
+ if (!real_ft) {
+ BT_LOGE_STR("Failed to allocate one real field type.");
+ goto error;
+ }
+
+ init_field_type((void *) real_ft, BT_FIELD_TYPE_ID_REAL,
+ destroy_real_field_type);
+ BT_LIB_LOGD("Created real field type object: %!+F", real_ft);
+ goto end;
+
+error:
+ BT_PUT(real_ft);
+
+end:
+ return (void *) real_ft;
+}
+
+bt_bool bt_field_type_real_is_single_precision(struct bt_field_type *ft)
+{
+ struct bt_field_type_real *real_ft = (void *) ft;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_REAL, "Field type");
+ return real_ft->is_single_precision;
+}
+
+int bt_field_type_real_set_is_single_precision(struct bt_field_type *ft,
+ bt_bool is_single_precision)
+{
+ struct bt_field_type_real *real_ft = (void *) ft;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_REAL, "Field type");
+ BT_ASSERT_PRE_FT_HOT(ft, "Field type");
+ real_ft->is_single_precision = (bool) is_single_precision;
+ BT_LIB_LOGV("Set real field type's \"is single precision\" property: "
+ "%!+F", ft);
+ return 0;
+}
+
+static
+int init_named_field_types_container(
+ struct bt_field_type_named_field_types_container *ft,
+ enum bt_field_type_id id, bt_object_release_func release_func)
+{
+ int ret = 0;
+
+ init_field_type((void *) ft, id, release_func);
+ ft->named_fts = g_array_new(FALSE, TRUE,
+ sizeof(struct bt_named_field_type));
+ if (!ft->named_fts) {
+ BT_LOGE_STR("Failed to allocate a GArray.");
+ ret = -1;
+ goto end;
+ }
+
+ ft->name_to_index = g_hash_table_new(g_str_hash, g_str_equal);
+ if (!ft->name_to_index) {
+ BT_LOGE_STR("Failed to allocate a GHashTable.");
+ ret = -1;
+ goto end;
+ }
+
+end:
+ return ret;
+}
+
+static
+void finalize_named_field_type(struct bt_named_field_type *named_ft)
+{
+ BT_ASSERT(named_ft);
+ BT_LIB_LOGD("Finalizing named field type: "
+ "addr=%p, name=\"%s\", %![ft-]+F",
+ named_ft, named_ft->name ? named_ft->name->str : NULL,
+ named_ft->ft);
+
+ if (named_ft->name) {
+ g_string_free(named_ft->name, TRUE);
+ }
+
+ BT_LOGD_STR("Putting named field type's field type.");
+ bt_put(named_ft->ft);
+}
+
+static
+void finalize_named_field_types_container(
+ struct bt_field_type_named_field_types_container *ft)
+{
+ uint64_t i;
+
+ BT_ASSERT(ft);
+
+ if (ft->named_fts) {
+ for (i = 0; i < ft->named_fts->len; i++) {
+ finalize_named_field_type(
+ &g_array_index(ft->named_fts,
+ struct bt_named_field_type, i));
+ }
+
+ g_array_free(ft->named_fts, TRUE);
+ }
+
+ if (ft->name_to_index) {
+ g_hash_table_destroy(ft->name_to_index);
+ }
+}
+
+static
+void destroy_structure_field_type(struct bt_object *obj)
+{
+ BT_ASSERT(obj);
+ BT_LIB_LOGD("Destroying string field type object: %!+F", obj);
+ finalize_named_field_types_container((void *) obj);
+ g_free(obj);
+}
+
+struct bt_field_type *bt_field_type_structure_create(void)
+{
+ int ret;
+ struct bt_field_type_structure *struct_ft = NULL;
+
+ BT_LOGD_STR("Creating default structure field type object.");
+ struct_ft = g_new0(struct bt_field_type_structure, 1);
+ if (!struct_ft) {
+ BT_LOGE_STR("Failed to allocate one structure field type.");
+ goto error;
+ }
+
+ ret = init_named_field_types_container((void *) struct_ft,
+ BT_FIELD_TYPE_ID_STRUCTURE, destroy_structure_field_type);
+ if (ret) {
+ goto error;
+ }
+
+ BT_LIB_LOGD("Created structure field type object: %!+F", struct_ft);
+ goto end;
+
+error:
+ BT_PUT(struct_ft);
+
+end:
+ return (void *) struct_ft;
+}
+
+static
+int append_named_field_type_to_container_field_type(
+ struct bt_field_type_named_field_types_container *container_ft,
+ const char *name, struct bt_field_type *ft)
+{
+ int ret = 0;
+ struct bt_named_field_type *named_ft;
+ GString *name_str;
+
+ BT_ASSERT(container_ft);
+ BT_ASSERT_PRE_FT_HOT(container_ft, "Field type");
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE(!bt_g_hash_table_contains(container_ft->name_to_index,
+ name),
+ "Duplicate member/option name in structure/variant field type: "
+ "%![container-ft-]+F, name=\"%s\"", container_ft, name);
+ name_str = g_string_new(name);
+ if (!name_str) {
+ BT_LOGE_STR("Failed to allocate a GString.");
+ ret = -1;
+ goto end;
+ }
+
+ g_array_set_size(container_ft->named_fts,
+ container_ft->named_fts->len + 1);
+ named_ft = &g_array_index(container_ft->named_fts,
+ struct bt_named_field_type, container_ft->named_fts->len - 1);
+ named_ft->name = name_str;
+ named_ft->ft = bt_get(ft);
+ g_hash_table_insert(container_ft->name_to_index, named_ft->name->str,
+ GUINT_TO_POINTER(container_ft->named_fts->len - 1));
+ bt_field_type_freeze(ft);
+
+end:
+ return ret;
+}
+
+int bt_field_type_structure_append_member(struct bt_field_type *ft,
+ const char *name, struct bt_field_type *member_ft)
+{
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STRUCTURE, "Field type");
+ return append_named_field_type_to_container_field_type((void *) ft,
+ name, member_ft);
+}
+
+uint64_t bt_field_type_structure_get_member_count(struct bt_field_type *ft)
+{
+ struct bt_field_type_structure *struct_ft = (void *) ft;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STRUCTURE, "Field type");
+ return (uint64_t) struct_ft->common.named_fts->len;
+}
+
+static
+void borrow_named_field_type_from_container_field_type_at_index(
+ struct bt_field_type_named_field_types_container *ft,
+ uint64_t index, const char **name,
+ struct bt_field_type **out_ft)
+{
+ struct bt_named_field_type *named_ft;
+
+ BT_ASSERT(ft);
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ BT_ASSERT_PRE_NON_NULL(out_ft, "Field type (output)");
+ BT_ASSERT_PRE_VALID_INDEX(index, ft->named_fts->len);
+ named_ft = BT_FIELD_TYPE_NAMED_FT_AT_INDEX(ft, index);
+ *name = named_ft->name->str;
+ *out_ft = named_ft->ft;
+}
+
+void bt_field_type_structure_borrow_member_by_index(
+ struct bt_field_type *ft, uint64_t index,
+ const char **name, struct bt_field_type **out_ft)
+{
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STRUCTURE, "Field type");
+ borrow_named_field_type_from_container_field_type_at_index((void *) ft,
+ index, name, out_ft);
+}
+
+static
+struct bt_field_type *borrow_field_type_from_container_field_type_by_name(
+ struct bt_field_type_named_field_types_container *ft,
+ const char *name)
+{
+ struct bt_field_type *ret_ft = NULL;
+ struct bt_named_field_type *named_ft;
+ gpointer orig_key;
+ gpointer value;
+
+ BT_ASSERT(ft);
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ if (!g_hash_table_lookup_extended(ft->name_to_index, name, &orig_key,
+ &value)) {
+ goto end;
+ }
+
+ named_ft = BT_FIELD_TYPE_NAMED_FT_AT_INDEX(ft,
+ GPOINTER_TO_UINT(value));
+ ret_ft = named_ft->ft;
+
+end:
+ return ret_ft;
+}
+
+struct bt_field_type *bt_field_type_structure_borrow_member_field_type_by_name(
+ struct bt_field_type *ft, const char *name)
+{
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STRUCTURE, "Field type");
+ return borrow_field_type_from_container_field_type_by_name((void *) ft,
+ name);
+}
+
+static
+void destroy_variant_field_type(struct bt_object *obj)
+{
+ struct bt_field_type_variant *ft = (void *) obj;
+
+ BT_ASSERT(ft);
+ BT_LIB_LOGD("Destroying variant field type object: %!+F", ft);
+ finalize_named_field_types_container((void *) ft);
+ BT_LOGD_STR("Putting selector field path.");
+ bt_put(ft->selector_field_path);
+ g_free(ft);
+}
+
+struct bt_field_type *bt_field_type_variant_create(void)
+{
+ int ret;
+ struct bt_field_type_variant *var_ft = NULL;
+
+ BT_LOGD_STR("Creating default variant field type object.");
+ var_ft = g_new0(struct bt_field_type_variant, 1);
+ if (!var_ft) {
+ BT_LOGE_STR("Failed to allocate one variant field type.");
+ goto error;
+ }
+
+ ret = init_named_field_types_container((void *) var_ft,
+ BT_FIELD_TYPE_ID_VARIANT, destroy_variant_field_type);
+ if (ret) {
+ goto error;
+ }
+
+ BT_LIB_LOGD("Created variant field type object: %!+F", var_ft);
+ goto end;
+
+error:
+ BT_PUT(var_ft);
+
+end:
+ return (void *) var_ft;
+}
+
+int bt_field_type_variant_set_selector_field_type(
+ struct bt_field_type *ft, struct bt_field_type *selector_ft)
+{
+ struct bt_field_type_variant *var_ft = (void *) ft;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Variant field type");
+ BT_ASSERT_PRE_NON_NULL(selector_ft, "Selector field type");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
+ BT_ASSERT_PRE_FT_IS_ENUM(selector_ft, "Selector field type");
+ BT_ASSERT_PRE_FT_HOT(ft, "Variant field type");
+ var_ft->selector_ft = selector_ft;
+ bt_field_type_freeze(selector_ft);
+ return 0;
+}
+
+int bt_field_type_variant_append_option(struct bt_field_type *ft,
+ const char *name, struct bt_field_type *option_ft)
+{
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
+ return append_named_field_type_to_container_field_type((void *) ft,
+ name, option_ft);
+}
+
+struct bt_field_type *bt_field_type_variant_borrow_option_field_type_by_name(
+ struct bt_field_type *ft, const char *name)
+{
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
+ return borrow_field_type_from_container_field_type_by_name((void *) ft,
+ name);
+}
+
+uint64_t bt_field_type_variant_get_option_count(struct bt_field_type *ft)
+{
+ struct bt_field_type_variant *var_ft = (void *) ft;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
+ return (uint64_t) var_ft->common.named_fts->len;
+}
+
+void bt_field_type_variant_borrow_option_by_index(
+ struct bt_field_type *ft, uint64_t index,
+ const char **name, struct bt_field_type **out_ft)
+{
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
+ borrow_named_field_type_from_container_field_type_at_index((void *) ft,
+ index, name, out_ft);
+}
+
+struct bt_field_path *bt_field_type_variant_borrow_selector_field_path(
+ struct bt_field_type *ft)
+{
+ struct bt_field_type_variant *var_ft = (void *) ft;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT,
+ "Field type");
+ return var_ft->selector_field_path;
+}
+
+static
+void init_array_field_type(struct bt_field_type_array *ft,
+ enum bt_field_type_id id, bt_object_release_func release_func,
+ struct bt_field_type *element_ft)
+{
+ BT_ASSERT(element_ft);
+ init_field_type((void *) ft, id, release_func);
+ ft->element_ft = bt_get(element_ft);
+ bt_field_type_freeze(element_ft);
+}
+
+static
+void finalize_array_field_type(struct bt_field_type_array *array_ft)
+{
+ BT_ASSERT(array_ft);
+ BT_LOGD_STR("Putting element field type.");
+ bt_put(array_ft->element_ft);
+}
+
+static
+void destroy_static_array_field_type(struct bt_object *obj)
+{
+ BT_ASSERT(obj);
+ BT_LIB_LOGD("Destroying static array field type object: %!+F", obj);
+ finalize_array_field_type((void *) obj);
+ g_free(obj);
+}
+
+struct bt_field_type *bt_field_type_static_array_create(
+ struct bt_field_type *element_ft, uint64_t length)
+{
+ struct bt_field_type_static_array *array_ft = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(element_ft, "Element field type");
+ BT_LOGD_STR("Creating default static array field type object.");
+ array_ft = g_new0(struct bt_field_type_static_array, 1);
+ if (!array_ft) {
+ BT_LOGE_STR("Failed to allocate one static array field type.");
+ goto error;
+ }
+
+ init_array_field_type((void *) array_ft, BT_FIELD_TYPE_ID_STATIC_ARRAY,
+ destroy_static_array_field_type, element_ft);
+ array_ft->length = length;
+ BT_LIB_LOGD("Created static array field type object: %!+F", array_ft);
+ goto end;
+
+error:
+ BT_PUT(array_ft);
+
+end:
+ return (void *) array_ft;
+}
+
+struct bt_field_type *bt_field_type_array_borrow_element_field_type(
+ struct bt_field_type *ft)
+{
+ struct bt_field_type_array *array_ft = (void *) ft;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_IS_ARRAY(ft, "Field type");
+ return array_ft->element_ft;
+}
+
+uint64_t bt_field_type_static_array_get_length(struct bt_field_type *ft)
+{
+ struct bt_field_type_static_array *array_ft = (void *) ft;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STATIC_ARRAY,
+ "Field type");
+ return (uint64_t) array_ft->length;
+}
+
+static
+void destroy_dynamic_array_field_type(struct bt_object *obj)
+{
+ struct bt_field_type_dynamic_array *ft = (void *) obj;
+
+ BT_ASSERT(ft);
+ BT_LIB_LOGD("Destroying dynamic array field type object: %!+F", ft);
+ finalize_array_field_type((void *) ft);
+ BT_LOGD_STR("Putting length field path.");
+ bt_put(ft->length_field_path);
+ g_free(ft);
+}
+
+struct bt_field_type *bt_field_type_dynamic_array_create(
+ struct bt_field_type *element_ft)
+{
+ struct bt_field_type_dynamic_array *array_ft = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(element_ft, "Element field type");
+ BT_LOGD_STR("Creating default dynamic array field type object.");
+ array_ft = g_new0(struct bt_field_type_dynamic_array, 1);
+ if (!array_ft) {
+ BT_LOGE_STR("Failed to allocate one dynamic array field type.");
+ goto error;
+ }
+
+ init_array_field_type((void *) array_ft, BT_FIELD_TYPE_ID_DYNAMIC_ARRAY,
+ destroy_dynamic_array_field_type, element_ft);
+ BT_LIB_LOGD("Created dynamic array field type object: %!+F", array_ft);
+ goto end;
+
+error:
+ BT_PUT(array_ft);
+
+end:
+ return (void *) array_ft;
+}
+
+int bt_field_type_dynamic_array_set_length_field_type(struct bt_field_type *ft,
+ struct bt_field_type *length_ft)
+{
+ struct bt_field_type_dynamic_array *array_ft = (void *) ft;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Dynamic array field type");
+ BT_ASSERT_PRE_NON_NULL(length_ft, "Length field type");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_DYNAMIC_ARRAY,
+ "Field type");
+ BT_ASSERT_PRE_FT_IS_UNSIGNED_INT(length_ft, "Length field type");
+ BT_ASSERT_PRE_FT_HOT(ft, "Dynamic array field type");
+ array_ft->length_ft = length_ft;
+ bt_field_type_freeze(length_ft);
+ return 0;
+}
+
+struct bt_field_path *bt_field_type_dynamic_array_borrow_length_field_path(
+ struct bt_field_type *ft)
+{
+ struct bt_field_type_dynamic_array *seq_ft = (void *) ft;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_DYNAMIC_ARRAY,
+ "Field type");
+ return seq_ft->length_field_path;
+}
+
+static
+void destroy_string_field_type(struct bt_object *obj)
+{
+ BT_ASSERT(obj);
+ BT_LIB_LOGD("Destroying string field type object: %!+F", obj);
+ g_free(obj);
+}
+
+struct bt_field_type *bt_field_type_string_create(void)
+{
+ struct bt_field_type_string *string_ft = NULL;
+
+ BT_LOGD_STR("Creating default string field type object.");
+ string_ft = g_new0(struct bt_field_type_string, 1);
+ if (!string_ft) {
+ BT_LOGE_STR("Failed to allocate one string field type.");
+ goto error;
+ }
+
+ init_field_type((void *) string_ft, BT_FIELD_TYPE_ID_STRING,
+ destroy_string_field_type);
+ BT_LIB_LOGD("Created string field type object: %!+F", string_ft);
+ goto end;
+
+error:
+ BT_PUT(string_ft);
+
+end:
+ return (void *) string_ft;
+}
+
+BT_HIDDEN
+void _bt_field_type_freeze(struct bt_field_type *ft)
+{
+ /*
+ * Element/member/option field types are frozen when added to
+ * their owner.
+ */
+ BT_ASSERT(ft);
+ ft->frozen = true;
+}
+
+BT_HIDDEN
+void _bt_field_type_make_part_of_trace(struct bt_field_type *ft)
+{
+ BT_ASSERT(ft);
+ BT_ASSERT_PRE(!ft->part_of_trace,
+ "Field type is already part of a trace: %!+F", ft);
+ ft->part_of_trace = true;
+
+ switch (ft->id) {
+ case BT_FIELD_TYPE_ID_STRUCTURE:
+ case BT_FIELD_TYPE_ID_VARIANT:
+ {
+ struct bt_field_type_named_field_types_container *container_ft =
+ (void *) ft;
+ uint64_t i;
+
+ for (i = 0; i < container_ft->named_fts->len; i++) {
+ struct bt_named_field_type *named_ft =
+ BT_FIELD_TYPE_NAMED_FT_AT_INDEX(
+ container_ft, i);
+
+ bt_field_type_make_part_of_trace(named_ft->ft);
+ }
+
+ break;
+ }
+ case BT_FIELD_TYPE_ID_STATIC_ARRAY:
+ case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
+ {
+ struct bt_field_type_array *array_ft = (void *) ft;
+
+ bt_field_type_make_part_of_trace(array_ft->element_ft);
+ break;
+ }
+ default:
+ break;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "FIELD-WRAPPER"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/trace-ir/field-wrapper-internal.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/object-pool-internal.h>
+#include <babeltrace/object-internal.h>
+#include <glib.h>
+
+BT_HIDDEN
+struct bt_field_wrapper *bt_field_wrapper_new(void *data)
+{
+ struct bt_field_wrapper *field_wrapper =
+ g_new0(struct bt_field_wrapper, 1);
+
+ BT_LOGD_STR("Creating empty field wrapper object.");
+
+ if (!field_wrapper) {
+ BT_LOGE("Failed to allocate one field wrapper.");
+ goto end;
+ }
+
+ bt_object_init_unique(&field_wrapper->base);
+ BT_LOGD("Created empty field wrapper object: addr=%p",
+ field_wrapper);
+
+end:
+ return field_wrapper;
+}
+
+BT_HIDDEN
+void bt_field_wrapper_destroy(struct bt_field_wrapper *field_wrapper)
+{
+ BT_LOGD("Destroying field wrapper: addr=%p", field_wrapper);
+
+ if (field_wrapper->field) {
+ BT_LOGD_STR("Destroying field.");
+ bt_field_destroy((void *) field_wrapper->field);
+ }
+
+ BT_LOGD_STR("Putting stream class.");
+ g_free(field_wrapper);
+}
+
+BT_HIDDEN
+struct bt_field_wrapper *bt_field_wrapper_create(
+ struct bt_object_pool *pool, struct bt_field_type *ft)
+{
+ struct bt_field_wrapper *field_wrapper = NULL;
+
+ BT_ASSERT(pool);
+ BT_ASSERT(ft);
+ field_wrapper = bt_object_pool_create_object(pool);
+ if (!field_wrapper) {
+ BT_LIB_LOGE("Cannot allocate one field wrapper from field wrapper pool: "
+ "%![pool-]+o", pool);
+ goto error;
+ }
+
+ if (!field_wrapper->field) {
+ field_wrapper->field = (void *) bt_field_create(ft);
+ if (!field_wrapper->field) {
+ BT_LIB_LOGE("Cannot create field wrapper from field type: "
+ "%![ft-]+F", ft);
+ goto error;
+ }
+
+ BT_LIB_LOGD("Created initial field wrapper object: "
+ "wrapper-addr=%p, %![field-]+f", field_wrapper,
+ field_wrapper->field);
+ }
+
+ goto end;
+
+error:
+ if (field_wrapper) {
+ bt_field_wrapper_destroy(field_wrapper);
+ field_wrapper = NULL;
+ }
+
+end:
+ return field_wrapper;
+}
--- /dev/null
+/*
+ * fields.c
+ *
+ * Babeltrace trace IR - Event Fields
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "FIELDS"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/compat/fcntl-internal.h>
+#include <babeltrace/align-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <inttypes.h>
+
+static
+void reset_single_field(struct bt_field *field);
+
+static
+void reset_array_field(struct bt_field *field);
+
+static
+void reset_structure_field(struct bt_field *field);
+
+static
+void reset_variant_field(struct bt_field *field);
+
+static
+void set_single_field_is_frozen(struct bt_field *field, bool is_frozen);
+
+static
+void set_array_field_is_frozen(struct bt_field *field, bool is_frozen);
+
+static
+void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen);
+
+static
+void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen);
+
+static
+bool single_field_is_set(struct bt_field *field);
+
+static
+bool array_field_is_set(struct bt_field *field);
+
+static
+bool structure_field_is_set(struct bt_field *field);
+
+static
+bool variant_field_is_set(struct bt_field *field);
+
+static
+struct bt_field_methods integer_field_methods = {
+ .set_is_frozen = set_single_field_is_frozen,
+ .is_set = single_field_is_set,
+ .reset = reset_single_field,
+};
+
+static
+struct bt_field_methods real_field_methods = {
+ .set_is_frozen = set_single_field_is_frozen,
+ .is_set = single_field_is_set,
+ .reset = reset_single_field,
+};
+
+static
+struct bt_field_methods string_field_methods = {
+ .set_is_frozen = set_single_field_is_frozen,
+ .is_set = single_field_is_set,
+ .reset = reset_single_field,
+};
+
+static
+struct bt_field_methods structure_field_methods = {
+ .set_is_frozen = set_structure_field_is_frozen,
+ .is_set = structure_field_is_set,
+ .reset = reset_structure_field,
+};
+
+static
+struct bt_field_methods array_field_methods = {
+ .set_is_frozen = set_array_field_is_frozen,
+ .is_set = array_field_is_set,
+ .reset = reset_array_field,
+};
+
+static
+struct bt_field_methods variant_field_methods = {
+ .set_is_frozen = set_variant_field_is_frozen,
+ .is_set = variant_field_is_set,
+ .reset = reset_variant_field,
+};
+
+static
+struct bt_field *create_integer_field(struct bt_field_type *);
+
+static
+struct bt_field *create_real_field(struct bt_field_type *);
+
+static
+struct bt_field *create_string_field(struct bt_field_type *);
+
+static
+struct bt_field *create_structure_field(struct bt_field_type *);
+
+static
+struct bt_field *create_static_array_field(struct bt_field_type *);
+
+static
+struct bt_field *create_dynamic_array_field(struct bt_field_type *);
+
+static
+struct bt_field *create_variant_field(struct bt_field_type *);
+
+static
+struct bt_field *(* const field_create_funcs[])(struct bt_field_type *) = {
+ [BT_FIELD_TYPE_ID_UNSIGNED_INTEGER] = create_integer_field,
+ [BT_FIELD_TYPE_ID_SIGNED_INTEGER] = create_integer_field,
+ [BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION] = create_integer_field,
+ [BT_FIELD_TYPE_ID_SIGNED_ENUMERATION] = create_integer_field,
+ [BT_FIELD_TYPE_ID_REAL] = create_real_field,
+ [BT_FIELD_TYPE_ID_STRING] = create_string_field,
+ [BT_FIELD_TYPE_ID_STRUCTURE] = create_structure_field,
+ [BT_FIELD_TYPE_ID_STATIC_ARRAY] = create_static_array_field,
+ [BT_FIELD_TYPE_ID_DYNAMIC_ARRAY] = create_dynamic_array_field,
+ [BT_FIELD_TYPE_ID_VARIANT] = create_variant_field,
+};
+
+static
+void destroy_integer_field(struct bt_field *field);
+
+static
+void destroy_real_field(struct bt_field *field);
+
+static
+void destroy_string_field(struct bt_field *field);
+
+static
+void destroy_structure_field(struct bt_field *field);
+
+static
+void destroy_array_field(struct bt_field *field);
+
+static
+void destroy_variant_field(struct bt_field *field);
+
+static
+void (* const field_destroy_funcs[])(struct bt_field *) = {
+ [BT_FIELD_TYPE_ID_UNSIGNED_INTEGER] = destroy_integer_field,
+ [BT_FIELD_TYPE_ID_SIGNED_INTEGER] = destroy_integer_field,
+ [BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION] = destroy_integer_field,
+ [BT_FIELD_TYPE_ID_SIGNED_ENUMERATION] = destroy_integer_field,
+ [BT_FIELD_TYPE_ID_REAL] = destroy_real_field,
+ [BT_FIELD_TYPE_ID_STRING] = destroy_string_field,
+ [BT_FIELD_TYPE_ID_STRUCTURE] = destroy_structure_field,
+ [BT_FIELD_TYPE_ID_STATIC_ARRAY] = destroy_array_field,
+ [BT_FIELD_TYPE_ID_DYNAMIC_ARRAY] = destroy_array_field,
+ [BT_FIELD_TYPE_ID_VARIANT] = destroy_variant_field,
+};
+
+struct bt_field_type *bt_field_borrow_type(struct bt_field *field)
+{
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ return field->type;
+}
+
+enum bt_field_type_id bt_field_get_type_id(struct bt_field *field)
+{
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ return field->type->id;
+}
+
+BT_HIDDEN
+struct bt_field *bt_field_create(struct bt_field_type *ft)
+{
+ struct bt_field *field = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT(bt_field_type_has_known_id(ft));
+ field = field_create_funcs[ft->id](ft);
+ if (!field) {
+ BT_LIB_LOGE("Cannot create field object from field type: "
+ "%![ft-]+F", ft);
+ goto end;
+ }
+
+end:
+ return field;
+}
+
+static inline
+void init_field(struct bt_field *field, struct bt_field_type *ft,
+ struct bt_field_methods *methods)
+{
+ BT_ASSERT(field);
+ BT_ASSERT(ft);
+ bt_object_init_unique(&field->base);
+ field->methods = methods;
+ field->type = bt_get(ft);
+}
+
+static
+struct bt_field *create_integer_field(struct bt_field_type *ft)
+{
+ struct bt_field_integer *int_field;
+
+ BT_LIB_LOGD("Creating integer field object: %![ft-]+F", ft);
+ int_field = g_new0(struct bt_field_integer, 1);
+ if (!int_field) {
+ BT_LOGE_STR("Failed to allocate one integer field.");
+ goto end;
+ }
+
+ init_field((void *) int_field, ft, &integer_field_methods);
+ BT_LIB_LOGD("Created integer field object: %!+f", int_field);
+
+end:
+ return (void *) int_field;
+}
+
+static
+struct bt_field *create_real_field(struct bt_field_type *ft)
+{
+ struct bt_field_real *real_field;
+
+ BT_LIB_LOGD("Creating real field object: %![ft-]+F", ft);
+ real_field = g_new0(struct bt_field_real, 1);
+ if (!real_field) {
+ BT_LOGE_STR("Failed to allocate one real field.");
+ goto end;
+ }
+
+ init_field((void *) real_field, ft, &real_field_methods);
+ BT_LIB_LOGD("Created real field object: %!+f", real_field);
+
+end:
+ return (void *) real_field;
+}
+
+static
+struct bt_field *create_string_field(struct bt_field_type *ft)
+{
+ struct bt_field_string *string_field;
+
+ BT_LIB_LOGD("Creating string field object: %![ft-]+F", ft);
+ string_field = g_new0(struct bt_field_string, 1);
+ if (!string_field) {
+ BT_LOGE_STR("Failed to allocate one string field.");
+ goto end;
+ }
+
+ init_field((void *) string_field, ft, &string_field_methods);
+ string_field->buf = g_array_sized_new(FALSE, FALSE,
+ sizeof(char), 1);
+ if (!string_field->buf) {
+ BT_LOGE_STR("Failed to allocate a GArray.");
+ BT_PUT(string_field);
+ goto end;
+ }
+
+ g_array_index(string_field->buf, char, 0) = '\0';
+ BT_LIB_LOGD("Created string field object: %!+f", string_field);
+
+end:
+ return (void *) string_field;
+}
+
+static inline
+int create_fields_from_named_field_types(
+ struct bt_field_type_named_field_types_container *ft,
+ GPtrArray **fields)
+{
+ int ret = 0;
+ uint64_t i;
+
+ *fields = g_ptr_array_new_with_free_func(
+ (GDestroyNotify) bt_field_destroy);
+ if (!*fields) {
+ BT_LOGE_STR("Failed to allocate a GPtrArray.");
+ ret = -1;
+ goto end;
+ }
+
+ g_ptr_array_set_size(*fields, ft->named_fts->len);
+
+ for (i = 0; i < ft->named_fts->len; i++) {
+ struct bt_field *field;
+ struct bt_named_field_type *named_ft =
+ BT_FIELD_TYPE_NAMED_FT_AT_INDEX(ft, i);
+
+ field = bt_field_create(named_ft->ft);
+ if (!field) {
+ BT_LIB_LOGE("Failed to create structure member or variant option field: "
+ "name=\"%s\", %![ft-]+F",
+ named_ft->name->str, named_ft->ft);
+ ret = -1;
+ goto end;
+ }
+
+ g_ptr_array_index(*fields, i) = field;
+ }
+
+end:
+ return ret;
+}
+
+static
+struct bt_field *create_structure_field(struct bt_field_type *ft)
+{
+ struct bt_field_structure *struct_field;
+
+ BT_LIB_LOGD("Creating structure field object: %![ft-]+F", ft);
+ struct_field = g_new0(struct bt_field_structure, 1);
+ if (!struct_field) {
+ BT_LOGE_STR("Failed to allocate one structure field.");
+ goto end;
+ }
+
+ init_field((void *) struct_field, ft, &structure_field_methods);
+
+ if (create_fields_from_named_field_types((void *) ft,
+ &struct_field->fields)) {
+ BT_LIB_LOGE("Cannot create structure member fields: "
+ "%![ft-]+F", ft);
+ BT_PUT(struct_field);
+ goto end;
+ }
+
+ BT_LIB_LOGD("Created structure field object: %!+f", struct_field);
+
+end:
+ return (void *) struct_field;
+}
+
+static
+struct bt_field *create_variant_field(struct bt_field_type *ft)
+{
+ struct bt_field_variant *var_field;
+
+ BT_LIB_LOGD("Creating variant field object: %![ft-]+F", ft);
+ var_field = g_new0(struct bt_field_variant, 1);
+ if (!var_field) {
+ BT_LOGE_STR("Failed to allocate one variant field.");
+ goto end;
+ }
+
+ init_field((void *) var_field, ft, &variant_field_methods);
+
+ if (create_fields_from_named_field_types((void *) ft,
+ &var_field->fields)) {
+ BT_LIB_LOGE("Cannot create variant member fields: "
+ "%![ft-]+F", ft);
+ BT_PUT(var_field);
+ goto end;
+ }
+
+ BT_LIB_LOGD("Created variant field object: %!+f", var_field);
+
+end:
+ return (void *) var_field;
+}
+
+static inline
+int init_array_field_fields(struct bt_field_array *array_field)
+{
+ int ret = 0;
+ uint64_t i;
+ struct bt_field_type_array *array_ft;
+
+ BT_ASSERT(array_field);
+ array_ft = (void *) array_field->common.type;
+ array_field->fields = g_ptr_array_sized_new(array_field->length);
+ if (!array_field->fields) {
+ BT_LOGE_STR("Failed to allocate a GPtrArray.");
+ ret = -1;
+ goto end;
+ }
+
+ g_ptr_array_set_free_func(array_field->fields,
+ (GDestroyNotify) bt_field_destroy);
+ g_ptr_array_set_size(array_field->fields, array_field->length);
+
+ for (i = 0; i < array_field->length; i++) {
+ array_field->fields->pdata[i] = bt_field_create(
+ array_ft->element_ft);
+ if (!array_field->fields->pdata[i]) {
+ BT_LIB_LOGE("Cannot create array field's element field: "
+ "index=%" PRIu64 ", %![ft-]+F", i, array_ft);
+ ret = -1;
+ goto end;
+ }
+ }
+
+end:
+ return ret;
+}
+
+static
+struct bt_field *create_static_array_field(struct bt_field_type *ft)
+{
+ struct bt_field_type_static_array *array_ft = (void *) ft;
+ struct bt_field_array *array_field;
+
+ BT_LIB_LOGD("Creating static array field object: %![ft-]+F", ft);
+ array_field = g_new0(struct bt_field_array, 1);
+ if (!array_field) {
+ BT_LOGE_STR("Failed to allocate one static array field.");
+ goto end;
+ }
+
+ init_field((void *) array_field, ft, &array_field_methods);
+ array_field->length = array_ft->length;
+
+ if (init_array_field_fields(array_field)) {
+ BT_LIB_LOGE("Cannot create static array fields: "
+ "%![ft-]+F", ft);
+ BT_PUT(array_field);
+ goto end;
+ }
+
+ BT_LIB_LOGD("Created static array field object: %!+f", array_field);
+
+end:
+ return (void *) array_field;
+}
+
+static
+struct bt_field *create_dynamic_array_field(struct bt_field_type *ft)
+{
+ struct bt_field_array *array_field;
+
+ BT_LIB_LOGD("Creating dynamic array field object: %![ft-]+F", ft);
+ array_field = g_new0(struct bt_field_array, 1);
+ if (!array_field) {
+ BT_LOGE_STR("Failed to allocate one dynamic array field.");
+ goto end;
+ }
+
+ init_field((void *) array_field, ft, &array_field_methods);
+
+ if (init_array_field_fields(array_field)) {
+ BT_LIB_LOGE("Cannot create dynamic array fields: "
+ "%![ft-]+F", ft);
+ BT_PUT(array_field);
+ goto end;
+ }
+
+ BT_LIB_LOGD("Created dynamic array field object: %!+f", array_field);
+
+end:
+ return (void *) array_field;
+}
+
+int64_t bt_field_signed_integer_get_value(struct bt_field *field)
+{
+ struct bt_field_integer *int_field = (void *) field;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
+ BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(field, "Field");
+ return int_field->value.i;
+}
+
+void bt_field_signed_integer_set_value(struct bt_field *field, int64_t value)
+{
+ struct bt_field_integer *int_field = (void *) field;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(field, "Field");
+ BT_ASSERT_PRE_FIELD_HOT(field, "Field");
+ BT_ASSERT_PRE(bt_util_value_is_in_range_signed(
+ ((struct bt_field_type_integer *) field->type)->range, value),
+ "Value is out of bounds: value=%" PRId64 ", %![field-]+f, "
+ "%![ft-]+F", value, field, field->type);
+ int_field->value.i = value;
+ bt_field_set_single(field, true);
+}
+
+uint64_t bt_field_unsigned_integer_get_value(struct bt_field *field)
+{
+ struct bt_field_integer *int_field = (void *) field;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
+ BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(field, "Field");
+ return int_field->value.u;
+}
+
+void bt_field_unsigned_integer_set_value(struct bt_field *field,
+ uint64_t value)
+{
+ struct bt_field_integer *int_field = (void *) field;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(field, "Field");
+ BT_ASSERT_PRE_FIELD_HOT(field, "Field");
+ BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(
+ ((struct bt_field_type_integer *) field->type)->range, value),
+ "Value is out of bounds: value=%" PRIu64 ", %![field-]+f, "
+ "%![ft-]+F", value, field, field->type);
+ int_field->value.u = value;
+ bt_field_set_single(field, true);
+}
+
+double bt_field_real_get_value(struct bt_field *field)
+{
+ struct bt_field_real *real_field = (void *) field;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
+ BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_REAL, "Field");
+ return real_field->value;
+}
+
+void bt_field_real_set_value(struct bt_field *field, double value)
+{
+ struct bt_field_real *real_field = (void *) field;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_REAL, "Field");
+ BT_ASSERT_PRE_FIELD_HOT(field, "Field");
+ BT_ASSERT_PRE(
+ !((struct bt_field_type_real *) field->type)->is_single_precision ||
+ (double) (float) value == value,
+ "Invalid value for a single-precision real number: value=%f, "
+ "%![ft-]+F", value, field->type);
+ real_field->value = value;
+ bt_field_set_single(field, true);
+}
+
+int bt_field_unsigned_enumeration_get_mapping_labels(struct bt_field *field,
+ bt_field_type_enumeration_mapping_label_array *label_array,
+ uint64_t *count)
+{
+ struct bt_field_integer *int_field = (void *) field;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)");
+ BT_ASSERT_PRE_NON_NULL(label_array, "Count (output)");
+ BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
+ BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+ BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION, "Field");
+ return bt_field_type_unsigned_enumeration_get_mapping_labels_by_value(
+ field->type, int_field->value.u, label_array, count);
+}
+
+int bt_field_signed_enumeration_get_mapping_labels(struct bt_field *field,
+ bt_field_type_enumeration_mapping_label_array *label_array,
+ uint64_t *count)
+{
+ struct bt_field_integer *int_field = (void *) field;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)");
+ BT_ASSERT_PRE_NON_NULL(label_array, "Count (output)");
+ BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
+ BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+ BT_FIELD_TYPE_ID_SIGNED_ENUMERATION, "Field");
+ return bt_field_type_signed_enumeration_get_mapping_labels_by_value(
+ field->type, int_field->value.i, label_array, count);
+}
+
+const char *bt_field_string_get_value(struct bt_field *field)
+{
+ struct bt_field_string *string_field = (void *) field;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
+ BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_STRING,
+ "Field");
+ return (const char *) string_field->buf->data;
+}
+
+uint64_t bt_field_string_get_length(struct bt_field *field)
+{
+ struct bt_field_string *string_field = (void *) field;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
+ BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_STRING,
+ "Field");
+ return string_field->length;
+}
+
+int bt_field_string_set_value(struct bt_field *field, const char *value)
+{
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_NON_NULL(value, "Value");
+ BT_ASSERT_PRE_FIELD_HOT(field, "Field");
+ BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_STRING,
+ "Field");
+ bt_field_string_clear(field);
+ return bt_field_string_append_with_length(field, value,
+ (uint64_t) strlen(value));
+}
+
+int bt_field_string_append(struct bt_field *field, const char *value)
+{
+ return bt_field_string_append_with_length(field, value,
+ (uint64_t) strlen(value));
+}
+
+int bt_field_string_append_with_length(struct bt_field *field,
+ const char *value, uint64_t length)
+{
+ struct bt_field_string *string_field = (void *) field;
+ char *data;
+ uint64_t new_length;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_NON_NULL(value, "Value");
+ BT_ASSERT_PRE_FIELD_HOT(field, "Field");
+ BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+ BT_FIELD_TYPE_ID_STRING, "Field");
+
+ /* Make sure no null bytes are appended */
+ BT_ASSERT_PRE(memchr(value, '\0', length) == NULL,
+ "String value to append contains a null character: "
+ "partial-value=\"%.32s\", length=%" PRIu64, value, length);
+
+ new_length = length + string_field->length;
+
+ if (unlikely(new_length + 1 > string_field->buf->len)) {
+ g_array_set_size(string_field->buf, new_length + 1);
+ }
+
+ data = string_field->buf->data;
+ memcpy(data + string_field->length, value, length);
+ ((char *) string_field->buf->data)[new_length] = '\0';
+ string_field->length = new_length;
+ bt_field_set_single(field, true);
+ return 0;
+}
+
+int bt_field_string_clear(struct bt_field *field)
+{
+ struct bt_field_string *string_field = (void *) field;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_FIELD_HOT(field, "Field");
+ BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+ BT_FIELD_TYPE_ID_STRING, "Field");
+ string_field->length = 0;
+ bt_field_set_single(field, true);
+ return 0;
+}
+
+uint64_t bt_field_array_get_length(struct bt_field *field)
+{
+ struct bt_field_array *array_field = (void *) field;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_FIELD_IS_ARRAY(field, "Field");
+ return array_field->length;
+}
+
+int bt_field_dynamic_array_set_length(struct bt_field *field,
+ uint64_t length)
+{
+ int ret = 0;
+ struct bt_field_array *array_field = (void *) field;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+ BT_FIELD_TYPE_ID_DYNAMIC_ARRAY, "Field");
+ BT_ASSERT_PRE_FIELD_HOT(field, "Field");
+
+ if (unlikely(length > array_field->fields->len)) {
+ /* Make more room */
+ struct bt_field_type_array *array_ft;
+ uint64_t cur_len = array_field->fields->len;
+ uint64_t i;
+
+ g_ptr_array_set_size(array_field->fields, length);
+ array_ft = (void *) field->type;
+
+ for (i = cur_len; i < array_field->fields->len; i++) {
+ struct bt_field *elem_field = bt_field_create(
+ array_ft->element_ft);
+
+ if (!elem_field) {
+ BT_LIB_LOGE("Cannot create element field for "
+ "dynamic array field: "
+ "index=%" PRIu64 ", "
+ "%![array-field-]+f", i, field);
+ ret = -1;
+ goto end;
+ }
+
+ BT_ASSERT(!array_field->fields->pdata[i]);
+ array_field->fields->pdata[i] = elem_field;
+ }
+ }
+
+ array_field->length = length;
+
+end:
+ return ret;
+}
+
+struct bt_field *bt_field_array_borrow_element_field_by_index(
+ struct bt_field *field, uint64_t index)
+{
+ struct bt_field_array *array_field = (void *) field;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_FIELD_IS_ARRAY(field, "Field");
+ BT_ASSERT_PRE_VALID_INDEX(index, array_field->length);
+ return array_field->fields->pdata[index];
+}
+
+struct bt_field *bt_field_structure_borrow_member_field_by_index(
+ struct bt_field *field, uint64_t index)
+{
+ struct bt_field_structure *struct_field = (void *) field;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+ BT_FIELD_TYPE_ID_STRUCTURE, "Field");
+ BT_ASSERT_PRE_VALID_INDEX(index, struct_field->fields->len);
+ return struct_field->fields->pdata[index];
+}
+
+struct bt_field *bt_field_structure_borrow_member_field_by_name(
+ struct bt_field *field, const char *name)
+{
+ struct bt_field *ret_field = NULL;
+ struct bt_field_type_structure *struct_ft;
+ struct bt_field_structure *struct_field = (void *) field;
+ gpointer orig_key;
+ gpointer index;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_NON_NULL(name, "Field name");
+ BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+ BT_FIELD_TYPE_ID_STRUCTURE, "Field");
+ struct_ft = (void *) field->type;
+
+ if (!g_hash_table_lookup_extended(struct_ft->common.name_to_index, name,
+ &orig_key, &index)) {
+ goto end;
+ }
+
+ ret_field = struct_field->fields->pdata[GPOINTER_TO_UINT(index)];
+ BT_ASSERT(ret_field);
+
+end:
+ return ret_field;
+}
+
+struct bt_field *bt_field_variant_borrow_selected_option_field(
+ struct bt_field *field)
+{
+ struct bt_field_variant *var_field = (void *) field;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+ BT_FIELD_TYPE_ID_VARIANT, "Field");
+ BT_ASSERT_PRE(var_field->selected_field,
+ "Variant field has no selected field: %!+f", field);
+ return var_field->selected_field;
+}
+
+int bt_field_variant_select_option_field(struct bt_field *field,
+ uint64_t index)
+{
+ struct bt_field_variant *var_field = (void *) field;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+ BT_FIELD_TYPE_ID_VARIANT, "Field");
+ BT_ASSERT_PRE_FIELD_HOT(field, "Field");
+ BT_ASSERT_PRE_VALID_INDEX(index, var_field->fields->len);
+ var_field->selected_field = var_field->fields->pdata[index];
+ var_field->selected_index = index;
+ return 0;
+}
+
+uint64_t bt_field_variant_get_selected_option_field_index(
+ struct bt_field *field)
+{
+ struct bt_field_variant *var_field = (void *) field;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+ BT_FIELD_TYPE_ID_VARIANT, "Field");
+ BT_ASSERT_PRE(var_field->selected_field,
+ "Variant field has no selected field: %!+f", field);
+ return var_field->selected_index;
+}
+
+static inline
+void bt_field_finalize(struct bt_field *field)
+{
+ BT_ASSERT(field);
+ BT_LOGD_STR("Putting field's type.");
+ bt_put(field->type);
+}
+
+static
+void destroy_integer_field(struct bt_field *field)
+{
+ BT_ASSERT(field);
+ BT_LIB_LOGD("Destroying integer field object: %!+f", field);
+ bt_field_finalize(field);
+ g_free(field);
+}
+
+static
+void destroy_real_field(struct bt_field *field)
+{
+ BT_ASSERT(field);
+ BT_LIB_LOGD("Destroying real field object: %!+f", field);
+ bt_field_finalize(field);
+ g_free(field);
+}
+
+static
+void destroy_structure_field(struct bt_field *field)
+{
+ struct bt_field_structure *struct_field = (void *) field;
+
+ BT_ASSERT(field);
+ BT_LIB_LOGD("Destroying structure field object: %!+f", field);
+ bt_field_finalize(field);
+
+ if (struct_field->fields) {
+ g_ptr_array_free(struct_field->fields, TRUE);
+ }
+
+ g_free(field);
+}
+
+static
+void destroy_variant_field(struct bt_field *field)
+{
+ struct bt_field_variant *var_field = (void *) field;
+
+ BT_ASSERT(field);
+ BT_LIB_LOGD("Destroying variant field object: %!+f", field);
+ bt_field_finalize(field);
+
+ if (var_field->fields) {
+ g_ptr_array_free(var_field->fields, TRUE);
+ }
+
+ g_free(field);
+}
+
+static
+void destroy_array_field(struct bt_field *field)
+{
+ struct bt_field_array *array_field = (void *) field;
+
+ BT_ASSERT(field);
+ BT_LIB_LOGD("Destroying array field object: %!+f", field);
+ bt_field_finalize(field);
+
+ if (array_field->fields) {
+ g_ptr_array_free(array_field->fields, TRUE);
+ }
+
+ g_free(field);
+}
+
+static
+void destroy_string_field(struct bt_field *field)
+{
+ struct bt_field_string *string_field = (void *) field;
+
+ BT_ASSERT(field);
+ BT_LIB_LOGD("Destroying string field object: %!+f", field);
+ bt_field_finalize(field);
+
+ if (string_field->buf) {
+ g_array_free(string_field->buf, TRUE);
+ }
+
+ g_free(field);
+}
+
+BT_HIDDEN
+void bt_field_destroy(struct bt_field *field)
+{
+ BT_ASSERT(field);
+ BT_ASSERT(bt_field_type_has_known_id(field->type));
+ field_destroy_funcs[field->type->id](field);
+}
+
+static
+void reset_single_field(struct bt_field *field)
+{
+ BT_ASSERT(field);
+ field->is_set = false;
+}
+
+static
+void reset_structure_field(struct bt_field *field)
+{
+ uint64_t i;
+ struct bt_field_structure *struct_field = (void *) field;
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < struct_field->fields->len; i++) {
+ bt_field_reset(struct_field->fields->pdata[i]);
+ }
+}
+
+static
+void reset_variant_field(struct bt_field *field)
+{
+ uint64_t i;
+ struct bt_field_variant *var_field = (void *) field;
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < var_field->fields->len; i++) {
+ bt_field_reset(var_field->fields->pdata[i]);
+ }
+}
+
+static
+void reset_array_field(struct bt_field *field)
+{
+ uint64_t i;
+ struct bt_field_array *array_field = (void *) field;
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < array_field->fields->len; i++) {
+ bt_field_reset(array_field->fields->pdata[i]);
+ }
+}
+
+static
+void set_single_field_is_frozen(struct bt_field *field, bool is_frozen)
+{
+ field->frozen = is_frozen;
+}
+
+static
+void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen)
+{
+ uint64_t i;
+ struct bt_field_structure *struct_field = (void *) field;
+
+ BT_LIB_LOGD("Setting structure field's frozen state: "
+ "%![field-]+f, is-frozen=%d", field, is_frozen);
+
+ for (i = 0; i < struct_field->fields->len; i++) {
+ struct bt_field *member_field = struct_field->fields->pdata[i];
+
+ BT_LIB_LOGD("Setting structure field's member field's "
+ "frozen state: %![field-]+f, index=%" PRIu64,
+ member_field, i);
+ bt_field_set_is_frozen(member_field, is_frozen);
+ }
+
+ set_single_field_is_frozen(field, is_frozen);
+}
+
+static
+void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen)
+{
+ uint64_t i;
+ struct bt_field_variant *var_field = (void *) field;
+
+ BT_LIB_LOGD("Setting variant field's frozen state: "
+ "%![field-]+f, is-frozen=%d", field, is_frozen);
+
+ for (i = 0; i < var_field->fields->len; i++) {
+ struct bt_field *option_field = var_field->fields->pdata[i];
+
+ BT_LIB_LOGD("Setting variant field's option field's "
+ "frozen state: %![field-]+f, index=%" PRIu64,
+ option_field, i);
+ bt_field_set_is_frozen(option_field, is_frozen);
+ }
+
+ set_single_field_is_frozen(field, is_frozen);
+}
+
+static
+void set_array_field_is_frozen(struct bt_field *field, bool is_frozen)
+{
+ uint64_t i;
+ struct bt_field_array *array_field = (void *) field;
+
+ BT_LIB_LOGD("Setting array field's frozen state: "
+ "%![field-]+f, is-frozen=%d", field, is_frozen);
+
+ for (i = 0; i < array_field->fields->len; i++) {
+ struct bt_field *elem_field = array_field->fields->pdata[i];
+
+ BT_LIB_LOGD("Setting array field's element field's "
+ "frozen state: %![field-]+f, index=%" PRIu64,
+ elem_field, i);
+ bt_field_set_is_frozen(elem_field, is_frozen);
+ }
+
+ set_single_field_is_frozen(field, is_frozen);
+}
+
+BT_HIDDEN
+void _bt_field_set_is_frozen(struct bt_field *field,
+ bool is_frozen)
+{
+ BT_ASSERT(field);
+ BT_LIB_LOGD("Setting field object's frozen state: %!+f, is-frozen=%d",
+ field, is_frozen);
+ BT_ASSERT(field->methods->set_is_frozen);
+ field->methods->set_is_frozen(field, is_frozen);
+}
+
+static
+bool single_field_is_set(struct bt_field *field)
+{
+ BT_ASSERT(field);
+ return field->is_set;
+}
+
+static
+bool structure_field_is_set(struct bt_field *field)
+{
+ bool is_set = true;
+ uint64_t i;
+ struct bt_field_structure *struct_field = (void *) field;
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < struct_field->fields->len; i++) {
+ is_set = bt_field_is_set(struct_field->fields->pdata[i]);
+ if (!is_set) {
+ goto end;
+ }
+ }
+
+end:
+ return is_set;
+}
+
+static
+bool variant_field_is_set(struct bt_field *field)
+{
+ struct bt_field_variant *var_field = (void *) field;
+ bool is_set = false;
+
+ BT_ASSERT(field);
+
+ if (var_field->selected_field) {
+ is_set = bt_field_is_set(var_field->selected_field);
+ }
+
+ return is_set;
+}
+
+static
+bool array_field_is_set(struct bt_field *field)
+{
+ bool is_set = true;
+ uint64_t i;
+ struct bt_field_array *array_field = (void *) field;
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < array_field->length; i++) {
+ is_set = bt_field_is_set(array_field->fields->pdata[i]);
+ if (!is_set) {
+ goto end;
+ }
+ }
+
+end:
+ return is_set;
+}
--- /dev/null
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "PACKET-CONTEXT-FIELD"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/packet-context-field.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/field-wrapper-internal.h>
+#include <glib.h>
+
+struct bt_field *bt_packet_context_field_borrow_field(
+ struct bt_packet_context_field *context_field)
+{
+ struct bt_field_wrapper *field_wrapper = (void *) context_field;
+
+ BT_ASSERT_PRE_NON_NULL(field_wrapper, "Packet context field");
+ return field_wrapper->field;
+}
+
+void bt_packet_context_field_release(struct bt_packet_context_field *context_field)
+{
+ struct bt_field_wrapper *field_wrapper = (void *) context_field;
+
+ BT_ASSERT_PRE_NON_NULL(field_wrapper, "Packet context field");
+
+ /*
+ * Do not recycle because the pool could be destroyed at this
+ * point. This function is only called when there's an error
+ * anyway because the goal of a packet context field wrapper is
+ * to eventually move it to a packet with
+ * bt_packet_move_context() after creating it.
+ */
+ bt_field_wrapper_destroy(field_wrapper);
+}
+
+struct bt_packet_context_field *bt_packet_context_field_create(
+ struct bt_stream_class *stream_class)
+{
+ struct bt_field_wrapper *field_wrapper;
+
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ BT_ASSERT_PRE(stream_class->frozen,
+ "Stream class is not part of a trace: %!+S", stream_class);
+ BT_ASSERT_PRE(stream_class->packet_context_ft,
+ "Stream class has no packet context field type: %!+S",
+ stream_class);
+ field_wrapper = bt_field_wrapper_create(
+ &stream_class->packet_context_field_pool,
+ (void *) stream_class->packet_context_ft);
+ if (!field_wrapper) {
+ BT_LIB_LOGE("Cannot allocate one packet context field from stream class: "
+ "%![sc-]+S", stream_class);
+ goto error;
+ }
+
+ BT_ASSERT(field_wrapper->field);
+ bt_stream_class_freeze(stream_class);
+ goto end;
+
+error:
+ if (field_wrapper) {
+ bt_field_wrapper_destroy(field_wrapper);
+ field_wrapper = NULL;
+ }
+
+end:
+ return (void *) field_wrapper;
+}
--- /dev/null
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "PACKET-HEADER-FIELD"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/trace-internal.h>
+#include <babeltrace/trace-ir/packet-header-field.h>
+#include <babeltrace/trace-ir/field-wrapper-internal.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <glib.h>
+
+struct bt_field *bt_packet_header_field_borrow_field(
+ struct bt_packet_header_field *header_field)
+{
+ struct bt_field_wrapper *field_wrapper = (void *) header_field;
+
+ BT_ASSERT_PRE_NON_NULL(field_wrapper, "Packet header field");
+ return (void *) field_wrapper->field;
+}
+
+void bt_packet_header_field_release(struct bt_packet_header_field *header_field)
+{
+ struct bt_field_wrapper *field_wrapper = (void *) header_field;
+
+ BT_ASSERT_PRE_NON_NULL(field_wrapper, "Packet header field");
+
+ /*
+ * Do not recycle because the pool could be destroyed at this
+ * point. This function is only called when there's an error
+ * anyway because the goal of a packet header field wrapper is
+ * to eventually move it to a packet with
+ * bt_packet_move_header() after creating it.
+ */
+ bt_field_wrapper_destroy(field_wrapper);
+}
+
+struct bt_packet_header_field *bt_packet_header_field_create(
+ struct bt_trace *trace)
+{
+ struct bt_field_wrapper *field_wrapper;
+
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE(trace->packet_header_ft,
+ "Trace has no packet header field type: %!+t", trace);
+ field_wrapper = bt_field_wrapper_create(
+ &trace->packet_header_field_pool,
+ (void *) trace->packet_header_ft);
+ if (!field_wrapper) {
+ BT_LIB_LOGE("Cannot allocate one packet header field from trace: "
+ "%![trace-]+t", trace);
+ goto error;
+ }
+
+ BT_ASSERT(field_wrapper->field);
+ bt_trace_freeze(trace);
+ goto end;
+
+error:
+ if (field_wrapper) {
+ bt_field_wrapper_destroy(field_wrapper);
+ field_wrapper = NULL;
+ }
+
+end:
+ return (void *) field_wrapper;
+}
--- /dev/null
+/*
+ * packet.c
+ *
+ * Babeltrace trace IR - Stream packet
+ *
+ * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "PACKET"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/packet.h>
+#include <babeltrace/trace-ir/packet-internal.h>
+#include <babeltrace/trace-ir/field-wrapper-internal.h>
+#include <babeltrace/trace-ir/trace.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/stream-internal.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/trace-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/assert-internal.h>
+#include <inttypes.h>
+
+#define BT_ASSERT_PRE_PACKET_HOT(_packet) \
+ BT_ASSERT_PRE_HOT((_packet), "Packet", ": %!+a", (_packet))
+
+struct bt_stream *bt_packet_borrow_stream(struct bt_packet *packet)
+{
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ return packet->stream;
+}
+
+struct bt_field *bt_packet_borrow_header_field(struct bt_packet *packet)
+{
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ return packet->header_field ? packet->header_field->field : NULL;
+}
+
+struct bt_field *bt_packet_borrow_context_field(struct bt_packet *packet)
+{
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ return packet->context_field ? packet->context_field->field : NULL;
+}
+
+BT_HIDDEN
+void _bt_packet_set_is_frozen(struct bt_packet *packet, bool is_frozen)
+{
+ if (!packet) {
+ return;
+ }
+
+ BT_LIB_LOGD("Setting packet's frozen state: %![packet-]+a, "
+ "is-frozen=%d", packet, is_frozen);
+
+ if (packet->header_field) {
+ BT_LOGD_STR("Setting packet's header field's frozen state.");
+ bt_field_set_is_frozen(packet->header_field->field,
+ is_frozen);
+ }
+
+ if (packet->context_field) {
+ BT_LOGD_STR("Setting packet's context field's frozen state.");
+ bt_field_set_is_frozen(packet->context_field->field,
+ is_frozen);
+ }
+
+ packet->frozen = is_frozen;
+}
+
+static inline
+void reset_counter_snapshots(struct bt_packet *packet)
+{
+ packet->discarded_event_counter_snapshot.base.avail =
+ BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE;
+ packet->packet_counter_snapshot.base.avail =
+ BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE;
+}
+
+static inline
+void reset_packet(struct bt_packet *packet)
+{
+ BT_ASSERT(packet);
+ BT_LIB_LOGD("Resetting packet: %!+a", packet);
+ bt_packet_set_is_frozen(packet, false);
+
+ if (packet->header_field) {
+ bt_field_set_is_frozen(packet->header_field->field, false);
+ bt_field_reset(packet->header_field->field);
+ }
+
+ if (packet->context_field) {
+ bt_field_set_is_frozen(packet->context_field->field, false);
+ bt_field_reset(packet->context_field->field);
+ }
+
+ if (packet->default_beginning_cv) {
+ bt_clock_value_reset(packet->default_beginning_cv);
+ }
+
+ if (packet->default_end_cv) {
+ bt_clock_value_reset(packet->default_end_cv);
+ }
+
+ reset_counter_snapshots(packet);
+}
+
+static
+void recycle_header_field(struct bt_field_wrapper *header_field,
+ struct bt_trace *trace)
+{
+ BT_ASSERT(header_field);
+ BT_LIB_LOGD("Recycling packet header field: "
+ "addr=%p, %![trace-]+t, %![field-]+f", header_field,
+ trace, header_field->field);
+ bt_object_pool_recycle_object(&trace->packet_header_field_pool,
+ header_field);
+}
+
+static
+void recycle_context_field(struct bt_field_wrapper *context_field,
+ struct bt_stream_class *stream_class)
+{
+ BT_ASSERT(context_field);
+ BT_LIB_LOGD("Recycling packet context field: "
+ "addr=%p, %![sc-]+S, %![field-]+f", context_field,
+ stream_class, context_field->field);
+ bt_object_pool_recycle_object(&stream_class->packet_context_field_pool,
+ context_field);
+}
+
+BT_HIDDEN
+void bt_packet_recycle(struct bt_packet *packet)
+{
+ struct bt_stream *stream;
+
+ BT_ASSERT(packet);
+ BT_LIB_LOGD("Recycling packet: %!+a", packet);
+
+ /*
+ * Those are the important ordered steps:
+ *
+ * 1. Reset the packet object (put any permanent reference it
+ * has, unfreeze it and its fields in developer mode, etc.),
+ * but do NOT put its stream's reference. This stream
+ * contains the pool to which we're about to recycle this
+ * packet object, so we must guarantee its existence thanks
+ * to this existing reference.
+ *
+ * 2. Move the stream reference to our `stream`
+ * variable so that we can set the packet's stream member
+ * to NULL before recycling it. We CANNOT do this after
+ * we put the stream reference because this bt_put()
+ * could destroy the stream, also destroying its
+ * packet pool, thus also destroying our packet object (this
+ * would result in an invalid write access).
+ *
+ * 3. Recycle the packet object.
+ *
+ * 4. Put our stream reference.
+ */
+ reset_packet(packet);
+ stream = packet->stream;
+ BT_ASSERT(stream);
+ packet->stream = NULL;
+ bt_object_pool_recycle_object(&stream->packet_pool, packet);
+ bt_object_put_no_null_check(&stream->base);
+}
+
+BT_HIDDEN
+void bt_packet_destroy(struct bt_packet *packet)
+{
+ BT_LIB_LOGD("Destroying packet: %!+a", packet);
+
+ if (packet->header_field) {
+ if (packet->stream) {
+ BT_LOGD_STR("Recycling packet's header field.");
+ recycle_header_field(packet->header_field,
+ bt_stream_class_borrow_trace_inline(
+ packet->stream->class));
+ } else {
+ bt_field_wrapper_destroy(packet->header_field);
+ }
+ }
+
+ if (packet->context_field) {
+ if (packet->stream) {
+ BT_LOGD_STR("Recycling packet's context field.");
+ recycle_context_field(packet->context_field,
+ packet->stream->class);
+ } else {
+ bt_field_wrapper_destroy(packet->context_field);
+ }
+ }
+
+ if (packet->default_beginning_cv) {
+ BT_LOGD_STR("Recycling beginning clock value.");
+ bt_clock_value_recycle(packet->default_beginning_cv);
+ }
+
+ if (packet->default_end_cv) {
+ BT_LOGD_STR("Recycling end clock value.");
+ bt_clock_value_recycle(packet->default_end_cv);
+ }
+
+ BT_LOGD_STR("Putting packet's stream.");
+ bt_put(packet->stream);
+ g_free(packet);
+}
+
+BT_HIDDEN
+struct bt_packet *bt_packet_new(struct bt_stream *stream)
+{
+ struct bt_packet *packet = NULL;
+ struct bt_trace *trace = NULL;
+
+ BT_ASSERT(stream);
+ BT_LIB_LOGD("Creating packet object: %![stream-]+s", stream);
+ packet = g_new0(struct bt_packet, 1);
+ if (!packet) {
+ BT_LOGE_STR("Failed to allocate one packet object.");
+ goto error;
+ }
+
+ bt_object_init_shared(&packet->base,
+ (bt_object_release_func) bt_packet_recycle);
+ packet->stream = bt_get(stream);
+ trace = bt_stream_class_borrow_trace_inline(stream->class);
+ BT_ASSERT(trace);
+
+ if (trace->packet_header_ft) {
+ BT_LOGD_STR("Creating initial packet header field.");
+ packet->header_field = bt_field_wrapper_create(
+ &trace->packet_header_field_pool,
+ trace->packet_header_ft);
+ if (!packet->header_field) {
+ BT_LOGE_STR("Cannot create packet header field wrapper.");
+ goto error;
+ }
+ }
+
+ if (stream->class->packet_context_ft) {
+ BT_LOGD_STR("Creating initial packet context field.");
+ packet->context_field = bt_field_wrapper_create(
+ &stream->class->packet_context_field_pool,
+ stream->class->packet_context_ft);
+ if (!packet->context_field) {
+ BT_LOGE_STR("Cannot create packet context field wrapper.");
+ goto error;
+ }
+ }
+
+ if (stream->class->default_clock_class) {
+ if (stream->class->packets_have_default_beginning_cv) {
+ packet->default_beginning_cv = bt_clock_value_create(
+ stream->class->default_clock_class);
+ if (!packet->default_beginning_cv) {
+ /* bt_clock_value_create() logs errors */
+ goto error;
+ }
+ }
+
+ if (stream->class->packets_have_default_end_cv) {
+ packet->default_end_cv = bt_clock_value_create(
+ stream->class->default_clock_class);
+ if (!packet->default_end_cv) {
+ /* bt_clock_value_create() logs errors */
+ goto error;
+ }
+ }
+ }
+
+ reset_counter_snapshots(packet);
+ BT_LIB_LOGD("Created packet object: %!+a", packet);
+ goto end;
+
+error:
+ BT_PUT(packet);
+
+end:
+ return packet;
+}
+
+struct bt_packet *bt_packet_create(struct bt_stream *stream)
+{
+ struct bt_packet *packet = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(stream, "Stream");
+ packet = bt_object_pool_create_object(&stream->packet_pool);
+ if (unlikely(!packet)) {
+ BT_LIB_LOGE("Cannot allocate one packet from stream's packet pool: "
+ "%![stream-]+s", stream);
+ goto end;
+ }
+
+ if (likely(!packet->stream)) {
+ packet->stream = stream;
+ bt_object_get_no_null_check_no_parent_check(
+ &packet->stream->base);
+ }
+
+end:
+ return packet;
+}
+
+int bt_packet_move_header_field(struct bt_packet *packet,
+ struct bt_packet_header_field *header_field)
+{
+ struct bt_trace *trace;
+ struct bt_field_wrapper *field_wrapper = (void *) header_field;
+
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ BT_ASSERT_PRE_NON_NULL(field_wrapper, "Header field");
+ BT_ASSERT_PRE_PACKET_HOT(packet);
+ trace = bt_stream_class_borrow_trace_inline(packet->stream->class);
+ BT_ASSERT_PRE(trace->packet_header_ft,
+ "Trace has no packet header field type: %!+t",
+ trace);
+ BT_ASSERT_PRE(field_wrapper->field->type ==
+ trace->packet_header_ft,
+ "Unexpected packet header field's type: "
+ "%![ft-]+F, %![expected-ft-]+F", field_wrapper->field->type,
+ trace->packet_header_ft);
+
+ /* Recycle current header field: always exists */
+ BT_ASSERT(packet->header_field);
+ recycle_header_field(packet->header_field, trace);
+
+ /* Move new field */
+ packet->header_field = field_wrapper;
+ return 0;
+}
+
+int bt_packet_move_context_field(struct bt_packet *packet,
+ struct bt_packet_context_field *context_field)
+{
+ struct bt_stream_class *stream_class;
+ struct bt_field_wrapper *field_wrapper = (void *) context_field;
+
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ BT_ASSERT_PRE_NON_NULL(field_wrapper, "Context field");
+ BT_ASSERT_PRE_HOT(packet, "Packet", ": %!+a", packet);
+ stream_class = packet->stream->class;
+ BT_ASSERT_PRE(stream_class->packet_context_ft,
+ "Stream class has no packet context field type: %!+S",
+ stream_class);
+ BT_ASSERT_PRE(field_wrapper->field->type ==
+ stream_class->packet_context_ft,
+ "Unexpected packet header field's type: "
+ "%![ft-]+F, %![expected-ft-]+F", field_wrapper->field->type,
+ stream_class->packet_context_ft);
+
+ /* Recycle current context field: always exists */
+ BT_ASSERT(packet->context_field);
+ recycle_context_field(packet->context_field, stream_class);
+
+ /* Move new field */
+ packet->context_field = field_wrapper;
+ return 0;
+}
+
+int bt_packet_set_default_beginning_clock_value(struct bt_packet *packet,
+ uint64_t value_cycles)
+{
+ struct bt_stream_class *sc;
+
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ BT_ASSERT_PRE_PACKET_HOT(packet);
+ sc = packet->stream->class;
+ BT_ASSERT(sc);
+ BT_ASSERT_PRE(sc->default_clock_class,
+ "Packet's stream class has no default clock class: "
+ "%![packet-]+a, %![sc-]+S", packet, sc);
+ BT_ASSERT_PRE(sc->packets_have_default_beginning_cv,
+ "Packet's stream class indicates that its packets have "
+ "no default beginning clock value: %![packet-]+a, %![sc-]+S",
+ packet, sc);
+ BT_ASSERT(packet->default_beginning_cv);
+ bt_clock_value_set_value_inline(packet->default_beginning_cv, value_cycles);
+ BT_LIB_LOGV("Set packet's default beginning clock value: "
+ "%![packet-]+a, value=%" PRIu64, value_cycles);
+ return 0;
+}
+
+enum bt_clock_value_status bt_packet_borrow_default_beginning_clock_value(
+ struct bt_packet *packet, struct bt_clock_value **clock_value)
+{
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value (output)");
+ *clock_value = packet->default_beginning_cv;
+ return BT_CLOCK_VALUE_STATUS_KNOWN;
+}
+
+int bt_packet_set_default_end_clock_value(struct bt_packet *packet,
+ uint64_t value_cycles)
+{
+ struct bt_stream_class *sc;
+
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ BT_ASSERT_PRE_PACKET_HOT(packet);
+ sc = packet->stream->class;
+ BT_ASSERT(sc);
+ BT_ASSERT_PRE(sc->default_clock_class,
+ "Packet's stream class has no default clock class: "
+ "%![packet-]+a, %![sc-]+S", packet, sc);
+ BT_ASSERT_PRE(sc->packets_have_default_end_cv,
+ "Packet's stream class indicates that its packets have "
+ "no default end clock value: %![packet-]+a, %![sc-]+S",
+ packet, sc);
+ BT_ASSERT(packet->default_end_cv);
+ bt_clock_value_set_value_inline(packet->default_end_cv, value_cycles);
+ BT_LIB_LOGV("Set packet's default end clock value: "
+ "%![packet-]+a, value=%" PRIu64, value_cycles);
+ return 0;
+}
+
+enum bt_clock_value_status bt_packet_borrow_default_end_clock_value(
+ struct bt_packet *packet, struct bt_clock_value **clock_value)
+{
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value (output)");
+ *clock_value = packet->default_end_cv;
+ return BT_CLOCK_VALUE_STATUS_KNOWN;
+}
+
+enum bt_property_availability bt_packet_get_discarded_event_counter_snapshot(
+ struct bt_packet *packet, uint64_t *value)
+{
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ BT_ASSERT_PRE_NON_NULL(value, "Value (output)");
+ *value = packet->discarded_event_counter_snapshot.value;
+ return packet->discarded_event_counter_snapshot.base.avail;
+}
+
+int bt_packet_set_discarded_event_counter_snapshot(struct bt_packet *packet,
+ uint64_t value)
+{
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ BT_ASSERT_PRE_PACKET_HOT(packet);
+ BT_ASSERT_PRE(packet->stream->class->packets_have_discarded_event_counter_snapshot,
+ "Packet's stream's discarded event counter is not enabled: "
+ "%![packet-]+a", packet);
+ bt_property_uint_set(&packet->discarded_event_counter_snapshot, value);
+ return 0;
+}
+
+enum bt_property_availability bt_packet_get_packet_counter_snapshot(
+ struct bt_packet *packet, uint64_t *value)
+{
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ BT_ASSERT_PRE_NON_NULL(value, "Value (output)");
+ *value = packet->packet_counter_snapshot.value;
+ return packet->packet_counter_snapshot.base.avail;
+}
+
+int bt_packet_set_packet_counter_snapshot(struct bt_packet *packet,
+ uint64_t value)
+{
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ BT_ASSERT_PRE_PACKET_HOT(packet);
+ BT_ASSERT_PRE(packet->stream->class->packets_have_packet_counter_snapshot,
+ "Packet's stream's packet counter is not enabled: "
+ "%![packet-]+a", packet);
+ bt_property_uint_set(&packet->packet_counter_snapshot, value);
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "RESOLVE-FIELD-PATH"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/field-path-internal.h>
+#include <babeltrace/trace-ir/field-path.h>
+#include <babeltrace/trace-ir/resolve-field-path-internal.h>
+#include <limits.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <glib.h>
+
+static
+bool find_field_type_recursive(struct bt_field_type *ft,
+ struct bt_field_type *tgt_ft, struct bt_field_path *field_path)
+{
+ bool found = false;
+
+ if (tgt_ft == ft) {
+ found = true;
+ goto end;
+ }
+
+ switch (ft->id) {
+ case BT_FIELD_TYPE_ID_STRUCTURE:
+ case BT_FIELD_TYPE_ID_VARIANT:
+ {
+ struct bt_field_type_named_field_types_container *container_ft =
+ (void *) ft;
+ uint64_t i;
+
+ for (i = 0; i < container_ft->named_fts->len; i++) {
+ struct bt_named_field_type *named_ft =
+ BT_FIELD_TYPE_NAMED_FT_AT_INDEX(
+ container_ft, i);
+
+ g_array_append_val(field_path->indexes, i);
+ found = find_field_type_recursive(named_ft->ft,
+ tgt_ft, field_path);
+ if (found) {
+ goto end;
+ }
+
+ g_array_set_size(field_path->indexes,
+ field_path->indexes->len - 1);
+ }
+
+ break;
+ }
+ case BT_FIELD_TYPE_ID_STATIC_ARRAY:
+ case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
+ {
+ struct bt_field_type_array *array_ft = (void *) ft;
+
+ found = find_field_type_recursive(array_ft->element_ft,
+ tgt_ft, field_path);
+ break;
+ }
+ default:
+ break;
+ }
+
+end:
+ return found;
+}
+
+static
+int find_field_type(struct bt_field_type *root_ft,
+ enum bt_scope root_scope, struct bt_field_type *tgt_ft,
+ struct bt_field_path **ret_field_path)
+{
+ int ret = 0;
+ struct bt_field_path *field_path = NULL;
+
+ if (!root_ft) {
+ goto end;
+ }
+
+ field_path = bt_field_path_create();
+ if (!field_path) {
+ ret = -1;
+ goto end;
+ }
+
+ field_path->root = root_scope;
+ if (!find_field_type_recursive(root_ft, tgt_ft, field_path)) {
+ /* Not found here */
+ BT_PUT(field_path);
+ }
+
+end:
+ *ret_field_path = field_path;
+ return ret;
+}
+
+static
+struct bt_field_path *find_field_type_in_ctx(struct bt_field_type *ft,
+ struct bt_resolve_field_path_context *ctx)
+{
+ struct bt_field_path *field_path = NULL;
+ int ret;
+
+ ret = find_field_type(ctx->packet_header, BT_SCOPE_PACKET_HEADER,
+ ft, &field_path);
+ if (ret || field_path) {
+ goto end;
+ }
+
+ ret = find_field_type(ctx->packet_context, BT_SCOPE_PACKET_CONTEXT,
+ ft, &field_path);
+ if (ret || field_path) {
+ goto end;
+ }
+
+ ret = find_field_type(ctx->event_header, BT_SCOPE_EVENT_HEADER,
+ ft, &field_path);
+ if (ret || field_path) {
+ goto end;
+ }
+
+ ret = find_field_type(ctx->event_common_context,
+ BT_SCOPE_EVENT_COMMON_CONTEXT, ft, &field_path);
+ if (ret || field_path) {
+ goto end;
+ }
+
+ ret = find_field_type(ctx->event_specific_context,
+ BT_SCOPE_EVENT_SPECIFIC_CONTEXT, ft, &field_path);
+ if (ret || field_path) {
+ goto end;
+ }
+
+ ret = find_field_type(ctx->event_payload, BT_SCOPE_EVENT_PAYLOAD,
+ ft, &field_path);
+ if (ret || field_path) {
+ goto end;
+ }
+
+end:
+ return field_path;
+}
+
+BT_ASSERT_PRE_FUNC
+static inline
+bool target_is_before_source(struct bt_field_path *src_field_path,
+ struct bt_field_path *tgt_field_path)
+{
+ bool is_valid = true;
+ uint64_t src_i = 0, tgt_i = 0;
+
+ if (tgt_field_path->root < src_field_path->root) {
+ goto end;
+ }
+
+ if (tgt_field_path->root > src_field_path->root) {
+ is_valid = false;
+ goto end;
+ }
+
+ BT_ASSERT(tgt_field_path->root == src_field_path->root);
+
+ while (src_i < src_field_path->indexes->len &&
+ tgt_i < tgt_field_path->indexes->len) {
+ uint64_t src_index = bt_field_path_get_index_by_index_inline(
+ src_field_path, src_i);
+ uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
+ tgt_field_path, tgt_i);
+
+ if (tgt_index > src_index) {
+ is_valid = false;
+ goto end;
+ }
+
+ src_i++;
+ tgt_i++;
+ }
+
+end:
+ return is_valid;
+}
+
+BT_ASSERT_PRE_FUNC
+static inline
+struct bt_field_type *borrow_root_field_type(
+ struct bt_resolve_field_path_context *ctx, enum bt_scope scope)
+{
+ switch (scope) {
+ case BT_SCOPE_PACKET_HEADER:
+ return ctx->packet_header;
+ case BT_SCOPE_PACKET_CONTEXT:
+ return ctx->packet_context;
+ case BT_SCOPE_EVENT_HEADER:
+ return ctx->event_header;
+ case BT_SCOPE_EVENT_COMMON_CONTEXT:
+ return ctx->event_common_context;
+ case BT_SCOPE_EVENT_SPECIFIC_CONTEXT:
+ return ctx->event_specific_context;
+ case BT_SCOPE_EVENT_PAYLOAD:
+ return ctx->event_payload;
+ default:
+ abort();
+ }
+
+ return NULL;
+}
+
+BT_ASSERT_PRE_FUNC
+static inline
+struct bt_field_type *borrow_child_field_type(struct bt_field_type *parent_ft,
+ uint64_t index, bool *advance)
+{
+ struct bt_field_type *child_ft = NULL;
+
+ switch (parent_ft->id) {
+ case BT_FIELD_TYPE_ID_STRUCTURE:
+ case BT_FIELD_TYPE_ID_VARIANT:
+ {
+ struct bt_named_field_type *named_ft =
+ BT_FIELD_TYPE_NAMED_FT_AT_INDEX(parent_ft, index);
+
+ child_ft = named_ft->ft;
+ *advance = true;
+ break;
+ }
+ case BT_FIELD_TYPE_ID_STATIC_ARRAY:
+ case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
+ {
+ struct bt_field_type_array *array_ft = (void *) parent_ft;
+
+ child_ft = array_ft->element_ft;
+ *advance = false;
+ break;
+ }
+ default:
+ break;
+ }
+
+ return child_ft;
+}
+
+BT_ASSERT_PRE_FUNC
+static inline
+bool target_field_path_in_different_scope_has_struct_ft_only(
+ struct bt_field_path *src_field_path,
+ struct bt_field_path *tgt_field_path,
+ struct bt_resolve_field_path_context *ctx)
+{
+ bool is_valid = true;
+ uint64_t i = 0;
+ struct bt_field_type *ft;
+
+ if (src_field_path->root == tgt_field_path->root) {
+ goto end;
+ }
+
+ ft = borrow_root_field_type(ctx, tgt_field_path->root);
+
+ while (i < tgt_field_path->indexes->len) {
+ uint64_t index = bt_field_path_get_index_by_index_inline(
+ tgt_field_path, i);
+ bool advance;
+
+ if (ft->id == BT_FIELD_TYPE_ID_STATIC_ARRAY ||
+ ft->id == BT_FIELD_TYPE_ID_DYNAMIC_ARRAY ||
+ ft->id == BT_FIELD_TYPE_ID_VARIANT) {
+ is_valid = false;
+ goto end;
+ }
+
+ ft = borrow_child_field_type(ft, index, &advance);
+
+ if (advance) {
+ i++;
+ }
+ }
+
+end:
+ return is_valid;
+}
+
+BT_ASSERT_PRE_FUNC
+static inline
+bool lca_is_structure_field_type(struct bt_field_path *src_field_path,
+ struct bt_field_path *tgt_field_path,
+ struct bt_resolve_field_path_context *ctx)
+{
+ bool is_valid = true;
+ struct bt_field_type *src_ft;
+ struct bt_field_type *tgt_ft;
+ struct bt_field_type *prev_ft = NULL;
+ uint64_t src_i = 0, tgt_i = 0;
+
+ if (src_field_path->root != tgt_field_path->root) {
+ goto end;
+ }
+
+ src_ft = borrow_root_field_type(ctx, src_field_path->root);
+ tgt_ft = borrow_root_field_type(ctx, tgt_field_path->root);
+ BT_ASSERT(src_ft);
+ BT_ASSERT(tgt_ft);
+
+ while (src_i < src_field_path->indexes->len &&
+ tgt_i < tgt_field_path->indexes->len) {
+ bool advance;
+ uint64_t src_index = bt_field_path_get_index_by_index_inline(
+ src_field_path, src_i);
+ uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
+ tgt_field_path, tgt_i);
+
+ if (src_ft != tgt_ft) {
+ if (!prev_ft) {
+ /*
+ * This is correct: the LCA is the root
+ * scope field type, which must be a
+ * structure field type.
+ */
+ break;
+ }
+
+ if (prev_ft->id != BT_FIELD_TYPE_ID_STRUCTURE) {
+ is_valid = false;
+ }
+
+ break;
+ }
+
+ prev_ft = src_ft;
+ src_ft = borrow_child_field_type(src_ft, src_index, &advance);
+
+ if (advance) {
+ src_i++;
+ }
+
+ tgt_ft = borrow_child_field_type(tgt_ft, tgt_index, &advance);
+
+ if (advance) {
+ tgt_i++;
+ }
+ }
+
+end:
+ return is_valid;
+}
+
+BT_ASSERT_PRE_FUNC
+static inline
+bool lca_to_target_has_struct_ft_only(struct bt_field_path *src_field_path,
+ struct bt_field_path *tgt_field_path,
+ struct bt_resolve_field_path_context *ctx)
+{
+ bool is_valid = true;
+ struct bt_field_type *src_ft;
+ struct bt_field_type *tgt_ft;
+ uint64_t src_i = 0, tgt_i = 0;
+
+ if (src_field_path->root != tgt_field_path->root) {
+ goto end;
+ }
+
+ src_ft = borrow_root_field_type(ctx, src_field_path->root);
+ tgt_ft = borrow_root_field_type(ctx, tgt_field_path->root);
+ BT_ASSERT(src_ft);
+ BT_ASSERT(tgt_ft);
+ BT_ASSERT(src_ft == tgt_ft);
+
+ /* Find LCA */
+ while (src_i < src_field_path->indexes->len &&
+ tgt_i < tgt_field_path->indexes->len) {
+ bool advance;
+ uint64_t src_index = bt_field_path_get_index_by_index_inline(
+ src_field_path, src_i);
+ uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
+ tgt_field_path, tgt_i);
+
+ if (src_i != tgt_i) {
+ /* Next FT is different: LCA is `tgt_ft` */
+ break;
+ }
+
+ src_ft = borrow_child_field_type(src_ft, src_index, &advance);
+
+ if (advance) {
+ src_i++;
+ }
+
+ tgt_ft = borrow_child_field_type(tgt_ft, tgt_index, &advance);
+
+ if (advance) {
+ tgt_i++;
+ }
+ }
+
+ /* Only structure field types to the target */
+ while (tgt_i < tgt_field_path->indexes->len) {
+ bool advance;
+ uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
+ tgt_field_path, tgt_i);
+
+ if (tgt_ft->id == BT_FIELD_TYPE_ID_STATIC_ARRAY ||
+ tgt_ft->id == BT_FIELD_TYPE_ID_DYNAMIC_ARRAY ||
+ tgt_ft->id == BT_FIELD_TYPE_ID_VARIANT) {
+ is_valid = false;
+ goto end;
+ }
+
+ tgt_ft = borrow_child_field_type(tgt_ft, tgt_index, &advance);
+
+ if (advance) {
+ tgt_i++;
+ }
+ }
+
+end:
+ return is_valid;
+}
+
+BT_ASSERT_PRE_FUNC
+static inline
+bool field_path_is_valid(struct bt_field_type *src_ft,
+ struct bt_field_type *tgt_ft,
+ struct bt_resolve_field_path_context *ctx)
+{
+ bool is_valid = true;
+ struct bt_field_path *src_field_path = find_field_type_in_ctx(
+ src_ft, ctx);
+ struct bt_field_path *tgt_field_path = find_field_type_in_ctx(
+ tgt_ft, ctx);
+
+ if (!src_field_path) {
+ BT_ASSERT_PRE_MSG("Cannot find requesting field type in "
+ "resolving context: %!+F", src_ft);
+ is_valid = false;
+ goto end;
+ }
+
+ if (!tgt_field_path) {
+ BT_ASSERT_PRE_MSG("Cannot find target field type in "
+ "resolving context: %!+F", tgt_ft);
+ is_valid = false;
+ goto end;
+ }
+
+ /* Target must be before source */
+ if (!target_is_before_source(src_field_path, tgt_field_path)) {
+ BT_ASSERT_PRE_MSG("Target field type is located after "
+ "requesting field type: %![req-ft-]+F, %![tgt-ft-]+F",
+ src_ft, tgt_ft);
+ is_valid = false;
+ goto end;
+ }
+
+ /*
+ * If target is in a different scope than source, there are no
+ * array or variant field types on the way to the target.
+ */
+ if (!target_field_path_in_different_scope_has_struct_ft_only(
+ src_field_path, tgt_field_path, ctx)) {
+ BT_ASSERT_PRE_MSG("Target field type is located in a "
+ "different scope than requesting field type, "
+ "but within an array or a variant field type: "
+ "%![req-ft-]+F, %![tgt-ft-]+F",
+ src_ft, tgt_ft);
+ is_valid = false;
+ goto end;
+ }
+
+ /* Same scope: LCA must be a structure field type */
+ if (!lca_is_structure_field_type(src_field_path, tgt_field_path, ctx)) {
+ BT_ASSERT_PRE_MSG("Lowest common ancestor of target and "
+ "requesting field types is not a structure field type: "
+ "%![req-ft-]+F, %![tgt-ft-]+F",
+ src_ft, tgt_ft);
+ is_valid = false;
+ goto end;
+ }
+
+ /* Same scope: path from LCA to target has no array/variant FTs */
+ if (!lca_to_target_has_struct_ft_only(src_field_path, tgt_field_path,
+ ctx)) {
+ BT_ASSERT_PRE_MSG("Path from lowest common ancestor of target "
+ "and requesting field types to target field type "
+ "contains an array or a variant field type: "
+ "%![req-ft-]+F, %![tgt-ft-]+F", src_ft, tgt_ft);
+ is_valid = false;
+ goto end;
+ }
+
+end:
+ bt_put(src_field_path);
+ bt_put(tgt_field_path);
+ return is_valid;
+}
+
+static
+struct bt_field_path *resolve_field_path(struct bt_field_type *src_ft,
+ struct bt_field_type *tgt_ft,
+ struct bt_resolve_field_path_context *ctx)
+{
+ BT_ASSERT_PRE(field_path_is_valid(src_ft, tgt_ft, ctx),
+ "Invalid target field type: %![req-ft-]+F, %![tgt-ft-]+F",
+ src_ft, tgt_ft);
+ return find_field_type_in_ctx(tgt_ft, ctx);
+}
+
+BT_HIDDEN
+int bt_resolve_field_paths(struct bt_field_type *ft,
+ struct bt_resolve_field_path_context *ctx)
+{
+ int ret = 0;
+
+ BT_ASSERT(ft);
+
+ /* Resolving part for dynamic array and variant field types */
+ switch (ft->id) {
+ case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
+ {
+ struct bt_field_type_dynamic_array *dyn_array_ft = (void *) ft;
+
+ if (dyn_array_ft->length_ft) {
+ BT_ASSERT(!dyn_array_ft->length_field_path);
+ dyn_array_ft->length_field_path = resolve_field_path(
+ ft, dyn_array_ft->length_ft, ctx);
+ if (!dyn_array_ft->length_field_path) {
+ ret = -1;
+ goto end;
+ }
+ }
+
+ break;
+ }
+ case BT_FIELD_TYPE_ID_VARIANT:
+ {
+ struct bt_field_type_variant *var_ft = (void *) ft;
+
+ if (var_ft->selector_ft) {
+ BT_ASSERT(!var_ft->selector_field_path);
+ var_ft->selector_field_path =
+ resolve_field_path(ft,
+ var_ft->selector_ft, ctx);
+ if (!var_ft->selector_field_path) {
+ ret = -1;
+ goto end;
+ }
+ }
+ }
+ default:
+ break;
+ }
+
+ /* Recursive part */
+ switch (ft->id) {
+ case BT_FIELD_TYPE_ID_STRUCTURE:
+ case BT_FIELD_TYPE_ID_VARIANT:
+ {
+ struct bt_field_type_named_field_types_container *container_ft =
+ (void *) ft;
+ uint64_t i;
+
+ for (i = 0; i < container_ft->named_fts->len; i++) {
+ struct bt_named_field_type *named_ft =
+ BT_FIELD_TYPE_NAMED_FT_AT_INDEX(
+ container_ft, i);
+
+ ret = bt_resolve_field_paths(named_ft->ft, ctx);
+ if (ret) {
+ goto end;
+ }
+ }
+
+ break;
+ }
+ case BT_FIELD_TYPE_ID_STATIC_ARRAY:
+ case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
+ {
+ struct bt_field_type_array *array_ft = (void *) ft;
+
+ ret = bt_resolve_field_paths(array_ft->element_ft, ctx);
+ break;
+ }
+ default:
+ break;
+ }
+
+end:
+ return ret;
+}
--- /dev/null
+/*
+ * stream-class.c
+ *
+ * Babeltrace trace IR - Stream Class
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "STREAM-CLASS"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/trace-ir/event-class-internal.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/utils-internal.h>
+#include <babeltrace/trace-ir/field-wrapper-internal.h>
+#include <babeltrace/trace-ir/resolve-field-path-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/align-internal.h>
+#include <babeltrace/endian-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/property-internal.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#define BT_ASSERT_PRE_STREAM_CLASS_HOT(_sc) \
+ BT_ASSERT_PRE_HOT((_sc), "Stream class", ": %!+S", (_sc))
+
+static
+void destroy_stream_class(struct bt_object *obj)
+{
+ struct bt_stream_class *stream_class = (void *) obj;
+
+ BT_LIB_LOGD("Destroying stream class: %!+S", stream_class);
+ BT_LOGD_STR("Putting default clock class.");
+ bt_put(stream_class->default_clock_class);
+
+ if (stream_class->event_classes) {
+ BT_LOGD_STR("Destroying event classes.");
+ g_ptr_array_free(stream_class->event_classes, TRUE);
+ }
+
+ if (stream_class->name.str) {
+ g_string_free(stream_class->name.str, TRUE);
+ }
+
+ BT_LOGD_STR("Putting event header field type.");
+ bt_put(stream_class->event_header_ft);
+ BT_LOGD_STR("Putting packet context field type.");
+ bt_put(stream_class->packet_context_ft);
+ BT_LOGD_STR("Putting event common context field type.");
+ bt_put(stream_class->event_common_context_ft);
+ bt_object_pool_finalize(&stream_class->event_header_field_pool);
+ bt_object_pool_finalize(&stream_class->packet_context_field_pool);
+ g_free(stream_class);
+}
+
+static
+void free_field_wrapper(struct bt_field_wrapper *field_wrapper,
+ struct bt_stream_class *stream_class)
+{
+ bt_field_wrapper_destroy((void *) field_wrapper);
+}
+
+BT_ASSERT_PRE_FUNC
+static
+bool stream_class_id_is_unique(struct bt_trace *trace, uint64_t id)
+{
+ uint64_t i;
+ bool is_unique = true;
+
+ for (i = 0; i < trace->stream_classes->len; i++) {
+ struct bt_stream_class *sc =
+ trace->stream_classes->pdata[i];
+
+ if (sc->id == id) {
+ is_unique = false;
+ goto end;
+ }
+ }
+
+end:
+ return is_unique;
+}
+
+static
+struct bt_stream_class *create_stream_class_with_id(struct bt_trace *trace,
+ uint64_t id)
+{
+ struct bt_stream_class *stream_class = NULL;
+ int ret;
+
+ BT_ASSERT(trace);
+ BT_ASSERT_PRE(stream_class_id_is_unique(trace, id),
+ "Duplicate stream class ID: %![trace-]+t, id=%" PRIu64,
+ trace, id);
+ BT_LIB_LOGD("Creating stream class object: %![trace-]+t, id=%" PRIu64,
+ trace, id);
+ stream_class = g_new0(struct bt_stream_class, 1);
+ if (!stream_class) {
+ BT_LOGE_STR("Failed to allocate one stream class.");
+ goto error;
+ }
+
+ bt_object_init_shared_with_parent(&stream_class->base,
+ destroy_stream_class);
+
+ stream_class->name.str = g_string_new(NULL);
+ if (!stream_class->name.str) {
+ BT_LOGE_STR("Failed to allocate a GString.");
+ ret = -1;
+ goto end;
+ }
+
+ stream_class->id = id;
+ stream_class->assigns_automatic_event_class_id = true;
+ stream_class->assigns_automatic_stream_id = true;
+ stream_class->event_classes = g_ptr_array_new_with_free_func(
+ (GDestroyNotify) bt_object_try_spec_release);
+ if (!stream_class->event_classes) {
+ BT_LOGE_STR("Failed to allocate a GPtrArray.");
+ goto error;
+ }
+
+ ret = bt_object_pool_initialize(&stream_class->event_header_field_pool,
+ (bt_object_pool_new_object_func) bt_field_wrapper_new,
+ (bt_object_pool_destroy_object_func) free_field_wrapper,
+ stream_class);
+ if (ret) {
+ BT_LOGE("Failed to initialize event header field pool: ret=%d",
+ ret);
+ goto error;
+ }
+
+ ret = bt_object_pool_initialize(&stream_class->packet_context_field_pool,
+ (bt_object_pool_new_object_func) bt_field_wrapper_new,
+ (bt_object_pool_destroy_object_func) free_field_wrapper,
+ stream_class);
+ if (ret) {
+ BT_LOGE("Failed to initialize packet context field pool: ret=%d",
+ ret);
+ goto error;
+ }
+
+ bt_object_set_parent(&stream_class->base, &trace->base);
+ g_ptr_array_add(trace->stream_classes, stream_class);
+ bt_trace_freeze(trace);
+ BT_LIB_LOGD("Created stream class object: %!+S", stream_class);
+ goto end;
+
+error:
+ BT_PUT(stream_class);
+
+end:
+ return stream_class;
+}
+
+struct bt_stream_class *bt_stream_class_create(struct bt_trace *trace)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE(trace->assigns_automatic_stream_class_id,
+ "Trace does not automatically assigns stream class IDs: "
+ "%![sc-]+t", trace);
+ return create_stream_class_with_id(trace,
+ (uint64_t) trace->stream_classes->len);
+}
+
+struct bt_stream_class *bt_stream_class_create_with_id(
+ struct bt_trace *trace, uint64_t id)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE(!trace->assigns_automatic_stream_class_id,
+ "Trace automatically assigns stream class IDs: "
+ "%![sc-]+t", trace);
+ return create_stream_class_with_id(trace, id);
+}
+
+struct bt_trace *bt_stream_class_borrow_trace(struct bt_stream_class *stream_class)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ return bt_stream_class_borrow_trace_inline(stream_class);
+}
+
+const char *bt_stream_class_get_name(struct bt_stream_class *stream_class)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ return stream_class->name.value;
+}
+
+int bt_stream_class_set_name(struct bt_stream_class *stream_class,
+ const char *name)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+ g_string_assign(stream_class->name.str, name);
+ stream_class->name.value = stream_class->name.str->str;
+ BT_LIB_LOGV("Set stream class's name: %!+S", stream_class);
+ return 0;
+}
+
+uint64_t bt_stream_class_get_id(struct bt_stream_class *stream_class)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ return stream_class->id;
+}
+
+uint64_t bt_stream_class_get_event_class_count(
+ struct bt_stream_class *stream_class)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ return (uint64_t) stream_class->event_classes->len;
+}
+
+struct bt_event_class *bt_stream_class_borrow_event_class_by_index(
+ struct bt_stream_class *stream_class, uint64_t index)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ BT_ASSERT_PRE_VALID_INDEX(index, stream_class->event_classes->len);
+ return g_ptr_array_index(stream_class->event_classes, index);
+}
+
+struct bt_event_class *bt_stream_class_borrow_event_class_by_id(
+ struct bt_stream_class *trace, uint64_t id)
+{
+ struct bt_event_class *event_class = NULL;
+ uint64_t i;
+
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+
+ for (i = 0; i < trace->event_classes->len; i++) {
+ struct bt_event_class *event_class_candidate =
+ g_ptr_array_index(trace->event_classes, i);
+
+ if (event_class_candidate->id == id) {
+ event_class = event_class_candidate;
+ goto end;
+ }
+ }
+
+end:
+ return event_class;
+}
+
+struct bt_field_type *bt_stream_class_borrow_packet_context_field_type(
+ struct bt_stream_class *stream_class)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ return stream_class->packet_context_ft;
+}
+
+int bt_stream_class_set_packet_context_field_type(
+ struct bt_stream_class *stream_class,
+ struct bt_field_type *field_type)
+{
+ int ret;
+ struct bt_resolve_field_path_context resolve_ctx = {
+ .packet_header = NULL,
+ .packet_context = field_type,
+ .event_header = NULL,
+ .event_common_context = NULL,
+ .event_specific_context = NULL,
+ .event_payload = NULL,
+ };
+
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
+ BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+ BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
+ BT_FIELD_TYPE_ID_STRUCTURE,
+ "Packet context field type is not a structure field type: %!+F",
+ field_type);
+ resolve_ctx.packet_header =
+ bt_stream_class_borrow_trace_inline(stream_class)->packet_header_ft;
+ ret = bt_resolve_field_paths(field_type, &resolve_ctx);
+ if (ret) {
+ goto end;
+ }
+
+ bt_field_type_make_part_of_trace(field_type);
+ bt_put(stream_class->packet_context_ft);
+ stream_class->packet_context_ft = bt_get(field_type);
+ bt_field_type_freeze(field_type);
+ BT_LIB_LOGV("Set stream class's packet context field type: %!+S",
+ stream_class);
+
+end:
+ return ret;
+}
+
+struct bt_field_type *bt_stream_class_borrow_event_header_field_type(
+ struct bt_stream_class *stream_class)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ return stream_class->event_header_ft;
+}
+
+int bt_stream_class_set_event_header_field_type(
+ struct bt_stream_class *stream_class,
+ struct bt_field_type *field_type)
+{
+ int ret;
+ struct bt_resolve_field_path_context resolve_ctx = {
+ .packet_header = NULL,
+ .packet_context = NULL,
+ .event_header = field_type,
+ .event_common_context = NULL,
+ .event_specific_context = NULL,
+ .event_payload = NULL,
+ };
+
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
+ BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+ BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
+ BT_FIELD_TYPE_ID_STRUCTURE,
+ "Event header field type is not a structure field type: %!+F",
+ field_type);
+ resolve_ctx.packet_header =
+ bt_stream_class_borrow_trace_inline(stream_class)->packet_header_ft;
+ resolve_ctx.packet_context = stream_class->packet_context_ft;
+ ret = bt_resolve_field_paths(field_type, &resolve_ctx);
+ if (ret) {
+ goto end;
+ }
+
+ bt_field_type_make_part_of_trace(field_type);
+ bt_put(stream_class->event_header_ft);
+ stream_class->event_header_ft = bt_get(field_type);
+ bt_field_type_freeze(field_type);
+ BT_LIB_LOGV("Set stream class's event header field type: %!+S",
+ stream_class);
+
+end:
+ return ret;
+}
+
+struct bt_field_type *bt_stream_class_borrow_event_common_context_field_type(
+ struct bt_stream_class *stream_class)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ return stream_class->event_common_context_ft;
+}
+
+int bt_stream_class_set_event_common_context_field_type(
+ struct bt_stream_class *stream_class,
+ struct bt_field_type *field_type)
+{
+ int ret;
+ struct bt_resolve_field_path_context resolve_ctx = {
+ .packet_header = NULL,
+ .packet_context = NULL,
+ .event_header = NULL,
+ .event_common_context = field_type,
+ .event_specific_context = NULL,
+ .event_payload = NULL,
+ };
+
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
+ BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+ BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
+ BT_FIELD_TYPE_ID_STRUCTURE,
+ "Event common context field type is not a structure field type: %!+F",
+ field_type);
+ resolve_ctx.packet_header =
+ bt_stream_class_borrow_trace_inline(stream_class)->packet_header_ft;
+ resolve_ctx.packet_context = stream_class->packet_context_ft;
+ resolve_ctx.event_header = stream_class->event_header_ft;
+ ret = bt_resolve_field_paths(field_type, &resolve_ctx);
+ if (ret) {
+ goto end;
+ }
+
+ bt_field_type_make_part_of_trace(field_type);
+ bt_put(stream_class->event_common_context_ft);
+ stream_class->event_common_context_ft = bt_get(field_type);
+ bt_field_type_freeze(field_type);
+ BT_LIB_LOGV("Set stream class's event common context field type: %!+S",
+ stream_class);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+void _bt_stream_class_freeze(struct bt_stream_class *stream_class)
+{
+ /* The field types and default clock class are already frozen */
+ BT_ASSERT(stream_class);
+ BT_LIB_LOGD("Freezing stream class: %!+S", stream_class);
+ stream_class->frozen = true;
+}
+
+int bt_stream_class_set_default_clock_class(
+ struct bt_stream_class *stream_class,
+ struct bt_clock_class *clock_class)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+ BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+ bt_put(stream_class->default_clock_class);
+ stream_class->default_clock_class = bt_get(clock_class);
+ bt_clock_class_freeze(clock_class);
+ BT_LIB_LOGV("Set stream class's default clock class: %!+S",
+ stream_class);
+ return 0;
+}
+
+struct bt_clock_class *bt_stream_class_borrow_default_clock_class(
+ struct bt_stream_class *stream_class)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ return stream_class->default_clock_class;
+}
+
+bt_bool bt_stream_class_assigns_automatic_event_class_id(
+ struct bt_stream_class *stream_class)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ return (bt_bool) stream_class->assigns_automatic_event_class_id;
+}
+
+int bt_stream_class_set_assigns_automatic_event_class_id(
+ struct bt_stream_class *stream_class, bt_bool value)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+ stream_class->assigns_automatic_event_class_id = (bool) value;
+ BT_LIB_LOGV("Set stream class's automatic event class ID "
+ "assignment property: %!+S", stream_class);
+ return 0;
+}
+
+bt_bool bt_stream_class_assigns_automatic_stream_id(
+ struct bt_stream_class *stream_class)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ return (bt_bool) stream_class->assigns_automatic_stream_id;
+}
+
+int bt_stream_class_set_assigns_automatic_stream_id(
+ struct bt_stream_class *stream_class, bt_bool value)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+ stream_class->assigns_automatic_stream_id = (bool) value;
+ BT_LIB_LOGV("Set stream class's automatic stream ID "
+ "assignment property: %!+S", stream_class);
+ return 0;
+}
+
+bt_bool bt_stream_class_packets_have_discarded_event_counter_snapshot(
+ struct bt_stream_class *stream_class)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ return (bt_bool) stream_class->packets_have_discarded_event_counter_snapshot;
+}
+
+int bt_stream_class_set_packets_have_discarded_event_counter_snapshot(
+ struct bt_stream_class *stream_class, bt_bool value)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+ stream_class->packets_have_discarded_event_counter_snapshot =
+ (bool) value;
+ BT_LIB_LOGV("Set stream class's "
+ "\"packets have discarded event counter snapshot\" property: "
+ "%!+S", stream_class);
+ return 0;
+}
+
+bt_bool bt_stream_class_packets_have_packet_counter_snapshot(
+ struct bt_stream_class *stream_class)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ return (bt_bool) stream_class->packets_have_packet_counter_snapshot;
+}
+
+int bt_stream_class_set_packets_have_packet_counter_snapshot(
+ struct bt_stream_class *stream_class, bt_bool value)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+ stream_class->packets_have_packet_counter_snapshot =
+ (bool) value;
+ BT_LIB_LOGV("Set stream class's "
+ "\"packets have packet counter snapshot\" property: "
+ "%!+S", stream_class);
+ return 0;
+}
+
+bt_bool bt_stream_class_packets_have_default_beginning_clock_value(
+ struct bt_stream_class *stream_class)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ return (bt_bool) stream_class->packets_have_default_beginning_cv;
+}
+
+int bt_stream_class_set_packets_have_default_beginning_clock_value(
+ struct bt_stream_class *stream_class, bt_bool value)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+ BT_ASSERT_PRE(!value || stream_class->default_clock_class,
+ "Stream class does not have a default clock class: %!+S",
+ stream_class);
+ stream_class->packets_have_default_beginning_cv = (bool) value;
+ BT_LIB_LOGV("Set stream class's "
+ "\"packets have default beginning clock value\" property: "
+ "%!+S", stream_class);
+ return 0;
+}
+
+bt_bool bt_stream_class_packets_have_default_end_clock_value(
+ struct bt_stream_class *stream_class)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ return (bt_bool) stream_class->packets_have_default_end_cv;
+}
+
+int bt_stream_class_set_packets_have_default_end_clock_value(
+ struct bt_stream_class *stream_class, bt_bool value)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+ BT_ASSERT_PRE(!value || stream_class->default_clock_class,
+ "Stream class does not have a default clock class: %!+S",
+ stream_class);
+ stream_class->packets_have_default_end_cv = (bool) value;
+ BT_LIB_LOGV("Set stream class's "
+ "\"packets have default end clock value\" property: "
+ "%!+S", stream_class);
+ return 0;
+}
+
+bt_bool bt_stream_class_default_clock_is_always_known(
+ struct bt_stream_class *stream_class)
+{
+ /* BT_CLOCK_VALUE_STATUS_UNKNOWN is not supported as of 2.0 */
+ return BT_TRUE;
+}
--- /dev/null
+/*
+ * stream.c
+ *
+ * Babeltrace trace IR - Stream
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "STREAM"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/stream-internal.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/trace.h>
+#include <babeltrace/trace-ir/trace-internal.h>
+#include <babeltrace/trace-ir/packet-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/align-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/property-internal.h>
+#include <inttypes.h>
+#include <unistd.h>
+
+#define BT_ASSERT_PRE_STREAM_HOT(_stream) \
+ BT_ASSERT_PRE_HOT((_stream), "Stream", ": %!+s", (_stream))
+
+static
+void destroy_stream(struct bt_object *obj)
+{
+ struct bt_stream *stream = (void *) obj;
+
+ BT_LIB_LOGD("Destroying stream object: %!+s", stream);
+
+ if (stream->name.str) {
+ g_string_free(stream->name.str, TRUE);
+ }
+
+ bt_object_pool_finalize(&stream->packet_pool);
+ g_free(stream);
+}
+
+static
+void bt_stream_free_packet(struct bt_packet *packet, struct bt_stream *stream)
+{
+ bt_packet_destroy(packet);
+}
+
+BT_ASSERT_PRE_FUNC
+static inline
+bool stream_id_is_unique(struct bt_trace *trace,
+ struct bt_stream_class *stream_class, uint64_t id)
+{
+ uint64_t i;
+ bool is_unique = true;
+
+ for (i = 0; i < trace->streams->len; i++) {
+ struct bt_stream *stream = trace->streams->pdata[i];
+
+ if (stream->class != stream_class) {
+ continue;
+ }
+
+ if (stream->id == id) {
+ is_unique = false;
+ goto end;
+ }
+ }
+
+end:
+ return is_unique;
+}
+
+static
+struct bt_stream *create_stream_with_id(struct bt_stream_class *stream_class,
+ uint64_t id)
+{
+ int ret;
+ struct bt_stream *stream;
+ struct bt_trace *trace;
+
+ BT_ASSERT(stream_class);
+ trace = bt_stream_class_borrow_trace_inline(stream_class);
+ BT_ASSERT_PRE(stream_id_is_unique(trace, stream_class, id),
+ "Duplicate stream ID: %![trace-]+t, id=%" PRIu64, trace, id);
+ BT_ASSERT_PRE(!trace->is_static,
+ "Trace is static: %![trace-]+t", trace);
+ BT_LIB_LOGD("Creating stream object: %![trace-]+t, id=%" PRIu64,
+ trace, id);
+ stream = g_new0(struct bt_stream, 1);
+ if (!stream) {
+ BT_LOGE_STR("Failed to allocate one stream.");
+ goto error;
+ }
+
+ bt_object_init_shared_with_parent(&stream->base, destroy_stream);
+ stream->name.str = g_string_new(NULL);
+ if (!stream->name.str) {
+ BT_LOGE_STR("Failed to allocate a GString.");
+ goto error;
+ }
+
+ stream->id = id;
+ ret = bt_object_pool_initialize(&stream->packet_pool,
+ (bt_object_pool_new_object_func) bt_packet_new,
+ (bt_object_pool_destroy_object_func) bt_stream_free_packet,
+ stream);
+ if (ret) {
+ BT_LOGE("Failed to initialize packet pool: ret=%d", ret);
+ goto error;
+ }
+
+ stream->class = stream_class;
+ bt_trace_add_stream(trace, stream);
+ bt_stream_class_freeze(stream_class);
+ BT_LIB_LOGD("Created stream object: %!+s", stream);
+ goto end;
+
+error:
+ BT_PUT(stream);
+
+end:
+ return stream;
+}
+
+struct bt_stream *bt_stream_create(struct bt_stream_class *stream_class)
+{
+ uint64_t id;
+
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ BT_ASSERT_PRE(stream_class->assigns_automatic_stream_id,
+ "Stream class does not automatically assigns stream IDs: "
+ "%![sc-]+S", stream_class);
+ id = bt_trace_get_automatic_stream_id(
+ bt_stream_class_borrow_trace_inline(stream_class),
+ stream_class);
+ return create_stream_with_id(stream_class, id);
+}
+
+struct bt_stream *bt_stream_create_with_id(struct bt_stream_class *stream_class,
+ uint64_t id)
+{
+ BT_ASSERT_PRE(!stream_class->assigns_automatic_stream_id,
+ "Stream class automatically assigns stream IDs: "
+ "%![sc-]+S", stream_class);
+ return create_stream_with_id(stream_class, id);
+}
+
+struct bt_stream_class *bt_stream_borrow_class(struct bt_stream *stream)
+{
+ BT_ASSERT_PRE_NON_NULL(stream, "Stream");
+ return stream->class;
+}
+
+const char *bt_stream_get_name(struct bt_stream *stream)
+{
+ BT_ASSERT_PRE_NON_NULL(stream, "Stream class");
+ return stream->name.value;
+}
+
+int bt_stream_set_name(struct bt_stream *stream, const char *name)
+{
+ BT_ASSERT_PRE_NON_NULL(stream, "Clock class");
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ BT_ASSERT_PRE_STREAM_HOT(stream);
+ g_string_assign(stream->name.str, name);
+ stream->name.value = stream->name.str->str;
+ BT_LIB_LOGV("Set stream class's name: %!+S", stream);
+ return 0;
+}
+
+uint64_t bt_stream_get_id(struct bt_stream *stream)
+{
+ BT_ASSERT_PRE_NON_NULL(stream, "Stream class");
+ return stream->id;
+}
+
+BT_HIDDEN
+void _bt_stream_freeze(struct bt_stream *stream)
+{
+ /* The field types and default clock class are already frozen */
+ BT_ASSERT(stream);
+ BT_LIB_LOGD("Freezing stream: %!+s", stream);
+ stream->frozen = true;
+}
--- /dev/null
+/*
+ * trace.c
+ *
+ * Babeltrace trace IR - Trace
+ *
+ * Copyright 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "TRACE"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/trace-internal.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/trace-ir/stream-internal.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/event-internal.h>
+#include <babeltrace/trace-ir/event-class.h>
+#include <babeltrace/trace-ir/event-class-internal.h>
+#include <babeltrace/ctf-writer/functor-internal.h>
+#include <babeltrace/ctf-writer/clock-internal.h>
+#include <babeltrace/trace-ir/field-wrapper-internal.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/attributes-internal.h>
+#include <babeltrace/trace-ir/utils-internal.h>
+#include <babeltrace/trace-ir/resolve-field-path-internal.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/values.h>
+#include <babeltrace/values-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/types.h>
+#include <babeltrace/endian-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/compat/glib-internal.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+
+struct bt_trace_is_static_listener_elem {
+ bt_trace_is_static_listener func;
+ bt_trace_listener_removed removed;
+ void *data;
+};
+
+#define BT_ASSERT_PRE_TRACE_HOT(_trace) \
+ BT_ASSERT_PRE_HOT((_trace), "Trace", ": %!+t", (_trace))
+
+static
+void destroy_trace(struct bt_object *obj)
+{
+ struct bt_trace *trace = (void *) obj;
+
+ BT_LIB_LOGD("Destroying trace object: %!+t", trace);
+
+ /*
+ * Call remove listeners first so that everything else still
+ * exists in the trace.
+ */
+ if (trace->is_static_listeners) {
+ size_t i;
+
+ for (i = 0; i < trace->is_static_listeners->len; i++) {
+ struct bt_trace_is_static_listener_elem elem =
+ g_array_index(trace->is_static_listeners,
+ struct bt_trace_is_static_listener_elem, i);
+
+ if (elem.removed) {
+ elem.removed(trace, elem.data);
+ }
+ }
+
+ g_array_free(trace->is_static_listeners, TRUE);
+ }
+
+ bt_object_pool_finalize(&trace->packet_header_field_pool);
+
+ if (trace->environment) {
+ BT_LOGD_STR("Destroying environment attributes.");
+ bt_attributes_destroy(trace->environment);
+ }
+
+ if (trace->name.str) {
+ g_string_free(trace->name.str, TRUE);
+ }
+
+ if (trace->streams) {
+ BT_LOGD_STR("Destroying streams.");
+ g_ptr_array_free(trace->streams, TRUE);
+ }
+
+ if (trace->stream_classes) {
+ BT_LOGD_STR("Destroying stream classes.");
+ g_ptr_array_free(trace->stream_classes, TRUE);
+ }
+
+ if (trace->stream_classes_stream_count) {
+ g_hash_table_destroy(trace->stream_classes_stream_count);
+ }
+
+ BT_LOGD_STR("Putting packet header field type.");
+ bt_put(trace->packet_header_ft);
+ g_free(trace);
+}
+
+static
+void free_packet_header_field(struct bt_field_wrapper *field_wrapper,
+ struct bt_trace *trace)
+{
+ bt_field_wrapper_destroy(field_wrapper);
+}
+
+struct bt_trace *bt_trace_create(void)
+{
+ struct bt_trace *trace = NULL;
+ int ret;
+
+ BT_LOGD_STR("Creating default trace object.");
+ trace = g_new0(struct bt_trace, 1);
+ if (!trace) {
+ BT_LOGE_STR("Failed to allocate one trace.");
+ goto error;
+ }
+
+ bt_object_init_shared_with_parent(&trace->base, destroy_trace);
+ trace->streams = g_ptr_array_new_with_free_func(
+ (GDestroyNotify) bt_object_try_spec_release);
+ if (!trace->streams) {
+ BT_LOGE_STR("Failed to allocate one GPtrArray.");
+ goto error;
+ }
+
+ trace->stream_classes = g_ptr_array_new_with_free_func(
+ (GDestroyNotify) bt_object_try_spec_release);
+ if (!trace->stream_classes) {
+ BT_LOGE_STR("Failed to allocate one GPtrArray.");
+ goto error;
+ }
+
+ trace->stream_classes_stream_count = g_hash_table_new(g_direct_hash,
+ g_direct_equal);
+ if (!trace->stream_classes_stream_count) {
+ BT_LOGE_STR("Failed to allocate one GHashTable.");
+ goto error;
+ }
+
+ trace->name.str = g_string_new(NULL);
+ if (!trace->name.str) {
+ BT_LOGE_STR("Failed to allocate one GString.");
+ goto error;
+ }
+
+ trace->environment = bt_attributes_create();
+ if (!trace->environment) {
+ BT_LOGE_STR("Cannot create empty attributes object.");
+ goto error;
+ }
+
+ trace->is_static_listeners = g_array_new(FALSE, TRUE,
+ sizeof(struct bt_trace_is_static_listener_elem));
+ if (!trace->is_static_listeners) {
+ BT_LOGE_STR("Failed to allocate one GArray.");
+ goto error;
+ }
+
+ trace->assigns_automatic_stream_class_id = true;
+ ret = bt_object_pool_initialize(&trace->packet_header_field_pool,
+ (bt_object_pool_new_object_func) bt_field_wrapper_new,
+ (bt_object_pool_destroy_object_func) free_packet_header_field,
+ trace);
+ if (ret) {
+ BT_LOGE("Failed to initialize packet header field pool: ret=%d",
+ ret);
+ goto error;
+ }
+
+ BT_LIB_LOGD("Created trace object: %!+t", trace);
+ goto end;
+
+error:
+ BT_PUT(trace);
+
+end:
+ return trace;
+}
+
+const char *bt_trace_get_name(struct bt_trace *trace)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ return trace->name.value;
+}
+
+int bt_trace_set_name(struct bt_trace *trace, const char *name)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ BT_ASSERT_PRE_TRACE_HOT(trace);
+ g_string_assign(trace->name.str, name);
+ trace->name.value = trace->name.str->str;
+ BT_LIB_LOGV("Set trace's name: %!+t", trace);
+ return 0;
+}
+
+bt_uuid bt_trace_get_uuid(struct bt_trace *trace)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ return trace->uuid.value;
+}
+
+int bt_trace_set_uuid(struct bt_trace *trace, bt_uuid uuid)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE_NON_NULL(uuid, "UUID");
+ BT_ASSERT_PRE_TRACE_HOT(trace);
+ memcpy(trace->uuid.uuid, uuid, BABELTRACE_UUID_LEN);
+ trace->uuid.value = trace->uuid.uuid;
+ BT_LIB_LOGV("Set trace's UUID: %!+t", trace);
+ return 0;
+}
+
+BT_ASSERT_FUNC
+static
+bool trace_has_environment_entry(struct bt_trace *trace, const char *name)
+{
+ struct bt_value *attribute;
+
+ BT_ASSERT(trace);
+
+ attribute = bt_attributes_borrow_field_value_by_name(
+ trace->environment, name);
+ return attribute != NULL;
+}
+
+static
+int set_environment_entry(struct bt_trace *trace, const char *name,
+ struct bt_value *value)
+{
+ int ret;
+
+ BT_ASSERT(trace);
+ BT_ASSERT(name);
+ BT_ASSERT(value);
+ BT_ASSERT_PRE(!trace->frozen ||
+ !trace_has_environment_entry(trace, name),
+ "Trace is frozen: cannot replace environment entry: "
+ "%![trace-]+t, entry-name=\"%s\"", trace, name);
+ ret = bt_attributes_set_field_value(trace->environment, name,
+ value);
+ bt_value_freeze(value);
+ if (ret) {
+ BT_LIB_LOGE("Cannot set trace's environment entry: "
+ "%![trace-]+t, entry-name=\"%s\"", trace, name);
+ } else {
+ BT_LIB_LOGV("Set trace's environment entry: "
+ "%![trace-]+t, entry-name=\"%s\"", trace, name);
+ }
+
+ return ret;
+}
+
+int bt_trace_set_environment_entry_string(struct bt_trace *trace,
+ const char *name, const char *value)
+{
+ int ret;
+ struct bt_value *value_obj;
+
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ BT_ASSERT_PRE_NON_NULL(value, "Value");
+ value_obj = bt_value_string_create_init(value);
+ if (!value_obj) {
+ BT_LOGE_STR("Cannot create a string value object.");
+ ret = -1;
+ goto end;
+ }
+
+ /* set_environment_entry() logs errors */
+ ret = set_environment_entry(trace, name, value_obj);
+
+end:
+ bt_put(value_obj);
+ return ret;
+}
+
+int bt_trace_set_environment_entry_integer(
+ struct bt_trace *trace, const char *name, int64_t value)
+{
+ int ret;
+ struct bt_value *value_obj;
+
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ value_obj = bt_value_integer_create_init(value);
+ if (!value_obj) {
+ BT_LOGE_STR("Cannot create an integer value object.");
+ ret = -1;
+ goto end;
+ }
+
+ /* set_environment_entry() logs errors */
+ ret = set_environment_entry(trace, name, value_obj);
+
+end:
+ bt_put(value_obj);
+ return ret;
+}
+
+uint64_t bt_trace_get_environment_entry_count(struct bt_trace *trace)
+{
+ int64_t ret;
+
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ ret = bt_attributes_get_count(trace->environment);
+ BT_ASSERT(ret >= 0);
+ return (uint64_t) ret;
+}
+
+void bt_trace_borrow_environment_entry_by_index(
+ struct bt_trace *trace, uint64_t index,
+ const char **name, struct bt_value **value)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ BT_ASSERT_PRE_NON_NULL(value, "Value");
+ BT_ASSERT_PRE_VALID_INDEX(index,
+ bt_attributes_get_count(trace->environment));
+ *value = bt_attributes_borrow_field_value(trace->environment, index);
+ BT_ASSERT(*value);
+ *name = bt_attributes_get_field_name(trace->environment, index);
+ BT_ASSERT(*name);
+}
+
+struct bt_value *bt_trace_borrow_environment_entry_value_by_name(
+ struct bt_trace *trace, const char *name)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ return bt_attributes_borrow_field_value_by_name(trace->environment,
+ name);
+}
+
+uint64_t bt_trace_get_stream_count(struct bt_trace *trace)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ return (uint64_t) trace->streams->len;
+}
+
+struct bt_stream *bt_trace_borrow_stream_by_index(
+ struct bt_trace *trace, uint64_t index)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE_VALID_INDEX(index, trace->streams->len);
+ return g_ptr_array_index(trace->streams, index);
+}
+
+struct bt_stream *bt_trace_borrow_stream_by_id(
+ struct bt_trace *trace, uint64_t id)
+{
+ struct bt_stream *stream = NULL;
+ uint64_t i;
+
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+
+ for (i = 0; i < trace->streams->len; i++) {
+ struct bt_stream *stream_candidate =
+ g_ptr_array_index(trace->streams, i);
+
+ if (stream_candidate->id == id) {
+ stream = stream_candidate;
+ goto end;
+ }
+ }
+
+end:
+ return stream;
+}
+
+uint64_t bt_trace_get_stream_class_count(struct bt_trace *trace)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ return (uint64_t) trace->stream_classes->len;
+}
+
+struct bt_stream_class *bt_trace_borrow_stream_class_by_index(
+ struct bt_trace *trace, uint64_t index)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE_VALID_INDEX(index, trace->stream_classes->len);
+ return g_ptr_array_index(trace->stream_classes, index);
+}
+
+struct bt_stream_class *bt_trace_borrow_stream_class_by_id(
+ struct bt_trace *trace, uint64_t id)
+{
+ struct bt_stream_class *stream_class = NULL;
+ uint64_t i;
+
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+
+ for (i = 0; i < trace->stream_classes->len; i++) {
+ struct bt_stream_class *stream_class_candidate =
+ g_ptr_array_index(trace->stream_classes, i);
+
+ if (stream_class_candidate->id == id) {
+ stream_class = stream_class_candidate;
+ goto end;
+ }
+ }
+
+end:
+ return stream_class;
+}
+
+struct bt_field_type *bt_trace_borrow_packet_header_field_type(
+ struct bt_trace *trace)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ return trace->packet_header_ft;
+}
+
+int bt_trace_set_packet_header_field_type(struct bt_trace *trace,
+ struct bt_field_type *field_type)
+{
+ int ret;
+ struct bt_resolve_field_path_context resolve_ctx = {
+ .packet_header = field_type,
+ .packet_context = NULL,
+ .event_header = NULL,
+ .event_common_context = NULL,
+ .event_specific_context = NULL,
+ .event_payload = NULL,
+ };
+
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
+ BT_ASSERT_PRE_TRACE_HOT(trace);
+ BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
+ BT_FIELD_TYPE_ID_STRUCTURE,
+ "Packet header field type is not a structure field type: %!+F",
+ field_type);
+ ret = bt_resolve_field_paths(field_type, &resolve_ctx);
+ if (ret) {
+ goto end;
+ }
+
+ bt_field_type_make_part_of_trace(field_type);
+ bt_put(trace->packet_header_ft);
+ trace->packet_header_ft = bt_get(field_type);
+ bt_field_type_freeze(field_type);
+ BT_LIB_LOGV("Set trace's packet header field type: %!+t", trace);
+
+end:
+ return ret;
+}
+
+bt_bool bt_trace_is_static(struct bt_trace *trace)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ return (bt_bool) trace->is_static;
+}
+
+int bt_trace_make_static(struct bt_trace *trace)
+{
+ uint64_t i;
+
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ trace->is_static = true;
+ bt_trace_freeze(trace);
+ BT_LIB_LOGV("Trace is now static: %!+t", trace);
+
+ /* Call all the "trace is static" listeners */
+ for (i = 0; i < trace->is_static_listeners->len; i++) {
+ struct bt_trace_is_static_listener_elem elem =
+ g_array_index(trace->is_static_listeners,
+ struct bt_trace_is_static_listener_elem, i);
+
+ if (elem.func) {
+ elem.func(trace, elem.data);
+ }
+ }
+
+ return 0;
+}
+
+int bt_trace_add_is_static_listener(struct bt_trace *trace,
+ bt_trace_is_static_listener listener,
+ bt_trace_listener_removed listener_removed, void *data,
+ uint64_t *listener_id)
+{
+ uint64_t i;
+ struct bt_trace_is_static_listener_elem new_elem = {
+ .func = listener,
+ .removed = listener_removed,
+ .data = data,
+ };
+
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE_NON_NULL(listener, "Listener");
+ BT_ASSERT_PRE(!trace->is_static,
+ "Trace is already static: %!+t", trace);
+ BT_ASSERT_PRE(trace->in_remove_listener,
+ "Cannot call this function while executing a "
+ "remove listener: %!+t", trace);
+
+ /* Find the next available spot */
+ for (i = 0; i < trace->is_static_listeners->len; i++) {
+ struct bt_trace_is_static_listener_elem elem =
+ g_array_index(trace->is_static_listeners,
+ struct bt_trace_is_static_listener_elem, i);
+
+ if (!elem.func) {
+ break;
+ }
+ }
+
+ if (i == trace->is_static_listeners->len) {
+ g_array_append_val(trace->is_static_listeners, new_elem);
+ } else {
+ g_array_insert_val(trace->is_static_listeners, i, new_elem);
+ }
+
+ if (listener_id) {
+ *listener_id = i;
+ }
+
+ BT_LIB_LOGV("Added \"trace is static\" listener: "
+ "%![trace-]+t, listener-id=%" PRIu64, trace, i);
+ return 0;
+}
+
+BT_ASSERT_PRE_FUNC
+static
+bool has_listener_id(struct bt_trace *trace, uint64_t listener_id)
+{
+ BT_ASSERT(listener_id < trace->is_static_listeners->len);
+ return (&g_array_index(trace->is_static_listeners,
+ struct bt_trace_is_static_listener_elem,
+ listener_id))->func != NULL;
+}
+
+int bt_trace_remove_is_static_listener(
+ struct bt_trace *trace, uint64_t listener_id)
+{
+ struct bt_trace_is_static_listener_elem *elem;
+
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE(!trace->is_static,
+ "Trace is already static: %!+t", trace);
+ BT_ASSERT_PRE(trace->in_remove_listener,
+ "Cannot call this function while executing a "
+ "remove listener: %!+t", trace);
+ BT_ASSERT_PRE(has_listener_id(trace, listener_id),
+ "Trace has no such \"trace is static\" listener ID: "
+ "%![trace-]+t, %" PRIu64, trace, listener_id);
+ elem = &g_array_index(trace->is_static_listeners,
+ struct bt_trace_is_static_listener_elem,
+ listener_id);
+ BT_ASSERT(elem->func);
+
+ if (elem->removed) {
+ /* Call remove listener */
+ BT_LIB_LOGV("Calling remove listener: "
+ "%![trace-]+t, listener-id=%" PRIu64,
+ trace, listener_id);
+ trace->in_remove_listener = true;
+ elem->removed(trace, elem->data);
+ trace->in_remove_listener = false;
+ }
+
+ elem->func = NULL;
+ elem->removed = NULL;
+ elem->data = NULL;
+ BT_LIB_LOGV("Removed \"trace is static\" listener: "
+ "%![trace-]+t, listener-id=%" PRIu64,
+ trace, listener_id);
+ return 0;
+}
+
+BT_HIDDEN
+void _bt_trace_freeze(struct bt_trace *trace)
+{
+ /* The packet header field type is already frozen */
+ BT_ASSERT(trace);
+ BT_LIB_LOGD("Freezing trace: %!+t", trace);
+ trace->frozen = true;
+}
+
+bt_bool bt_trace_assigns_automatic_stream_class_id(struct bt_trace *trace)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ return (bt_bool) trace->assigns_automatic_stream_class_id;
+}
+
+int bt_trace_set_assigns_automatic_stream_class_id(
+ struct bt_trace *trace, bt_bool value)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE_TRACE_HOT(trace);
+ trace->assigns_automatic_stream_class_id = (bool) value;
+ BT_LIB_LOGV("Set trace's automatic stream class ID "
+ "assignment property: %!+t", trace);
+ return 0;
+}
+
+BT_HIDDEN
+void bt_trace_add_stream(struct bt_trace *trace, struct bt_stream *stream)
+{
+ guint count = 0;
+
+ bt_object_set_parent(&stream->base, &trace->base);
+ g_ptr_array_add(trace->streams, stream);
+ bt_trace_freeze(trace);
+
+ if (bt_g_hash_table_contains(trace->stream_classes_stream_count,
+ stream->class)) {
+ count = GPOINTER_TO_UINT(g_hash_table_lookup(
+ trace->stream_classes_stream_count, stream->class));
+ }
+
+ g_hash_table_insert(trace->stream_classes_stream_count,
+ stream->class, GUINT_TO_POINTER(count + 1));
+}
+
+BT_HIDDEN
+uint64_t bt_trace_get_automatic_stream_id(struct bt_trace *trace,
+ struct bt_stream_class *stream_class)
+{
+ gpointer orig_key;
+ gpointer value;
+ uint64_t id = 0;
+
+ BT_ASSERT(stream_class);
+ BT_ASSERT(trace);
+ if (g_hash_table_lookup_extended(trace->stream_classes_stream_count,
+ stream_class, &orig_key, &value)) {
+ id = (uint64_t) GPOINTER_TO_UINT(value);
+ }
+
+ return id;
+}
--- /dev/null
+/*
+ * utils.c
+ *
+ * Babeltrace trace IR - Utilities
+ *
+ * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "TRACE-IR-UTILS"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <stdlib.h>
+#include <glib.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/clock-class.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/assert-internal.h>
* belong to this group (a single stream instance).
*
* You can call ctf_fs_ds_file_create() with one of those paths
- * and the CTF IR stream below.
+ * and the trace IR stream below.
*/
GPtrArray *ds_file_infos;
TESTS_LIB = \
lib/test_ctf_writer_complete \
lib/test_bt_values \
- lib/test_ctf_ir_ref \
+ lib/test_trace_ir_ref \
lib/test_bt_ctf_field_type_validation \
lib/test_ir_visit \
lib/test_graph_topo \
endif
if ENABLE_PYTHON_BINDINGS
-TESTS_LIB += lib/ctf-ir/test_ctf_ir
+TESTS_LIB += lib/trace-ir/test_trace_ir
TESTS_LIB += lib/ctf-writer/test_ctf_writer
endif
-SUBDIRS = ctf-ir ctf-writer
+SUBDIRS = trace-ir ctf-writer
AM_CPPFLAGS += -I$(top_srcdir)/tests/utils
test_bt_values_LDADD = $(COMMON_TEST_LDADD)
-test_ctf_ir_ref_LDADD = $(COMMON_TEST_LDADD)
+test_trace_ir_ref_LDADD = $(COMMON_TEST_LDADD)
test_graph_topo_LDADD = $(COMMON_TEST_LDADD)
test_bt_notification_iterator_LDADD = $(COMMON_TEST_LDADD)
noinst_PROGRAMS = test_bitfield test_ctf_writer test_bt_values \
- test_ctf_ir_ref test_graph_topo test_bt_notification_iterator
+ test_trace_ir_ref test_graph_topo test_bt_notification_iterator
test_bitfield_SOURCES = test_bitfield.c
test_ctf_writer_SOURCES = test_ctf_writer.c
test_bt_values_SOURCES = test_bt_values.c
-test_ctf_ir_ref_SOURCES = test_ctf_ir_ref.c
+test_trace_ir_ref_SOURCES = test_trace_ir_ref.c
test_graph_topo_SOURCES = test_graph_topo.c
test_bt_notification_iterator_SOURCES = test_bt_notification_iterator.c
+++ /dev/null
-if ENABLE_PYTHON_BINDINGS
-check_SCRIPTS = test_ctf_ir
-endif
-
-EXTRA_DIST = test_trace.py test_stream_class.py
+++ /dev/null
-#!/bin/bash
-#
-# Copyright (C) 2017 - Philippe Proulx <pproulx@efficios.com>
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; only version 2
-# of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-
-NO_SH_TAP=1
-. "@abs_top_builddir@/tests/utils/common.sh"
-
-PYTHON_BUILD_DIR="${BT_BUILD_PATH}/bindings/python/bt2/build/build_lib"
-TESTS_UTILS_PYTHON_DIR="${BT_SRC_PATH}/tests/utils/python"
-TESTRUNNER_PY="${BT_SRC_PATH}/tests/utils/python/testrunner.py"
-THIS_DIR="${BT_SRC_PATH}/tests/lib/ctf-ir"
-
-if [ "x${MSYSTEM}" != "x" ]; then
- export PATH="${BT_BUILD_PATH}/lib/.libs:${PATH}"
-else
- export LD_LIBRARY_PATH="${BT_BUILD_PATH}/lib/.libs:${LD_LIBRARY_PATH}"
-fi
-
-PYTHONPATH="${PYTHON_BUILD_DIR}:${TESTS_UTILS_PYTHON_DIR}" \
- "@PYTHON@" "${TESTRUNNER_PY}" "${THIS_DIR}"
-exit $?
+++ /dev/null
-import unittest
-import bt2
-
-
-class StreamClassSingleClockClassTestCase(unittest.TestCase):
- def setUp(self):
- self._sc = bt2.StreamClass()
-
- def tearDown(self):
- del self._sc
-
- def _test_add_sc_ft_vs_event_class(self, set_ft_func):
- cc = bt2.ClockClass('first_cc', 1000)
- scft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- scft.append_field('salut', ft)
- set_ft_func(scft)
- cc = bt2.ClockClass('second_cc', 1000)
- payloadft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- payloadft.append_field('zorg', ft)
- ec = bt2.EventClass('ec', payload_field_type=payloadft)
- self._sc.add_event_class(ec)
- trace = bt2.Trace()
-
- with self.assertRaises(bt2.Error):
- trace.add_stream_class(self._sc)
-
- def test_add_sc_packet_context_vs_event_class(self):
- def func(ft):
- self._sc.packet_context_field_type = ft
-
- self._test_add_sc_ft_vs_event_class(func)
-
- def test_add_sc_event_context_vs_event_class(self):
- def func(ft):
- self._sc.event_context_field_type = ft
-
- self._test_add_sc_ft_vs_event_class(func)
-
- def test_add_sc_event_header_vs_event_class(self):
- def func(ft):
- self._sc.event_header_field_type = ft
-
- self._test_add_sc_ft_vs_event_class(func)
-
- def test_add_sc_event_class_vs_event_class(self):
- ehft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32)
- ehft.append_field('id', ft)
- self._sc.event_header_field_type = ehft
- cc = bt2.ClockClass('first_cc', 1000)
- payloadft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- payloadft.append_field('zorg', ft)
- ec1 = bt2.EventClass('ec', payload_field_type=payloadft)
- cc = bt2.ClockClass('second_cc', 1000)
- payloadft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- payloadft.append_field('logi', ft)
- ec2 = bt2.EventClass('ec', payload_field_type=payloadft)
- self._sc.add_event_class(ec1)
- self._sc.add_event_class(ec2)
- trace = bt2.Trace()
-
- with self.assertRaises(bt2.Error):
- trace.add_stream_class(self._sc)
-
- def _test_create_event_ft_vs_event_class(self, set_ft_func):
- cc = bt2.ClockClass('first_cc', 1000)
- scft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- scft.append_field('salut', ft)
- set_ft_func(scft)
- cc = bt2.ClockClass('second_cc', 1000)
- payloadft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- payloadft.append_field('zorg', ft)
- ec = bt2.EventClass('ec', payload_field_type=payloadft)
- self._sc.add_event_class(ec)
-
- with self.assertRaises(bt2.Error):
- ev = ec()
-
- def test_create_event_packet_context_vs_event_class(self):
- def func(ft):
- self._sc.packet_context_field_type = ft
-
- self._test_create_event_ft_vs_event_class(func)
-
- def test_create_event_event_context_vs_event_class(self):
- def func(ft):
- self._sc.event_context_field_type = ft
-
- self._test_create_event_ft_vs_event_class(func)
-
- def test_create_event_event_header_vs_event_class(self):
- def func(ft):
- self._sc.event_header_field_type = ft
-
- self._test_create_event_ft_vs_event_class(func)
-
- def test_create_event_event_class_vs_event_class(self):
- ehft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32)
- ehft.append_field('id', ft)
- self._sc.event_header_field_type = ehft
- cc = bt2.ClockClass('first_cc', 1000)
- payloadft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- payloadft.append_field('zorg', ft)
- ec1 = bt2.EventClass('ec', payload_field_type=payloadft)
- cc = bt2.ClockClass('second_cc', 1000)
- payloadft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- payloadft.append_field('logi', ft)
- ec2 = bt2.EventClass('ec', payload_field_type=payloadft)
- self._sc.add_event_class(ec1)
- self._sc.add_event_class(ec2)
-
- with self.assertRaises(bt2.Error):
- ev = ec1()
-
- def test_add_ec_after_add_sc(self):
- cc = bt2.ClockClass('first_cc', 1000)
- scft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- scft.append_field('salut', ft)
- self._sc.packet_context_field_type = scft
- trace = bt2.Trace()
- trace.add_stream_class(self._sc)
- cc = bt2.ClockClass('second_cc', 1000)
- payloadft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- payloadft.append_field('zorg', ft)
- ec = bt2.EventClass('ec', payload_field_type=payloadft)
-
- with self.assertRaises(bt2.Error):
- self._sc.add_event_class(ec)
-
- def test_add_ec_after_add_sc_single_cc(self):
- ehft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32)
- ehft.append_field('id', ft)
- self._sc.event_header_field_type = ehft
- trace = bt2.Trace()
- trace.add_stream_class(self._sc)
- cc = bt2.ClockClass('first_cc', 1000)
- payloadft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- payloadft.append_field('zorg', ft)
- ec = bt2.EventClass('ec', payload_field_type=payloadft)
- self._sc.add_event_class(ec)
- cc = bt2.ClockClass('second_cc', 1000)
- payloadft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- payloadft.append_field('lel', ft)
- ec = bt2.EventClass('ec', payload_field_type=payloadft)
-
- with self.assertRaises(bt2.Error):
- self._sc.add_event_class(ec)
-
- def test_add_ec_after_create_event(self):
- ehft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32)
- ehft.append_field('id', ft)
- self._sc.event_header_field_type = ehft
- cc = bt2.ClockClass('first_cc', 1000)
- payloadft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- payloadft.append_field('zorg', ft)
- ec1 = bt2.EventClass('ec', payload_field_type=payloadft)
- self._sc.add_event_class(ec1)
- ev = ec1()
- cc = bt2.ClockClass('second_cc', 1000)
- payloadft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- payloadft.append_field('logi', ft)
- ec2 = bt2.EventClass('ec', payload_field_type=payloadft)
-
- with self.assertRaises(bt2.Error):
- self._sc.add_event_class(ec2)
-
- def test_sc_clock_matches_expected_clock_class(self):
- clock = bt2.CtfWriterClock('sc_clock')
- self._sc.clock = clock
- writer = bt2.CtfWriter('/tmp')
- writer.add_clock(clock)
- writer.trace.add_stream_class(self._sc)
- cc = bt2.ClockClass('other_cc', 1000)
- payloadft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- payloadft.append_field('zorg', ft)
- ec = bt2.EventClass('ec', payload_field_type=payloadft)
-
- with self.assertRaises(bt2.Error):
- self._sc.add_event_class(ec)
+++ /dev/null
-import unittest
-import bt2
-
-
-class TraceTestCase(unittest.TestCase):
- def setUp(self):
- self._trace = bt2.Trace()
-
- def tearDown(self):
- del self._trace
-
- def _add_stream_class(self):
- sc = bt2.StreamClass()
- self._trace.add_stream_class(sc)
-
- def test_packet_header_ft_no_clock_class_simple(self):
- cc = bt2.ClockClass('hello', 1000)
- phft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- phft.append_field('salut', ft)
- self._trace.add_clock_class(cc)
- self._trace.packet_header_field_type = phft
-
- with self.assertRaises(bt2.Error):
- self._add_stream_class()
-
- def test_packet_header_ft_no_clock_class_struct(self):
- cc = bt2.ClockClass('hello', 1000)
- phft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- struct_ft = bt2.StructureFieldType()
- struct_ft.append_field('salut', ft)
- phft.append_field('boucane', struct_ft)
- self._trace.add_clock_class(cc)
- self._trace.packet_header_field_type = phft
-
- with self.assertRaises(bt2.Error):
- self._add_stream_class()
-
- def test_packet_header_ft_no_clock_class_variant(self):
- cc = bt2.ClockClass('hello', 1000)
- phft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- tag_ft = bt2.EnumerationFieldType(size=32)
- tag_ft.add_mapping('heille', 12)
- variant_ft = bt2.VariantFieldType('tag', tag_ft)
- variant_ft.append_field('heille', ft)
- phft.append_field('tag', tag_ft)
- phft.append_field('boucane', variant_ft)
- self._trace.add_clock_class(cc)
- self._trace.packet_header_field_type = phft
-
- with self.assertRaises(bt2.Error):
- self._add_stream_class()
-
- def test_packet_header_ft_no_clock_class_array(self):
- cc = bt2.ClockClass('hello', 1000)
- phft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- array_ft = bt2.ArrayFieldType(ft, 23)
- phft.append_field('boucane', array_ft)
- self._trace.add_clock_class(cc)
- self._trace.packet_header_field_type = phft
-
- with self.assertRaises(bt2.Error):
- self._add_stream_class()
-
- def test_packet_header_ft_no_clock_class_sequence(self):
- cc = bt2.ClockClass('hello', 1000)
- phft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- len_ft = bt2.IntegerFieldType(32)
- seq_ft = bt2.SequenceFieldType(ft, 'len')
- phft.append_field('len', len_ft)
- phft.append_field('boucane', seq_ft)
- self._trace.add_clock_class(cc)
- self._trace.packet_header_field_type = phft
-
- with self.assertRaises(bt2.Error):
- self._add_stream_class()
-
- def test_packet_header_ft_no_clock_class_set_static(self):
- cc = bt2.ClockClass('hello', 1000)
- phft = bt2.StructureFieldType()
- ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
- phft.append_field('salut', ft)
- self._trace.add_clock_class(cc)
- self._trace.packet_header_field_type = phft
-
- with self.assertRaises(bt2.Error):
- self._trace.set_is_static()
#include <inttypes.h>
#include <string.h>
#include <babeltrace/assert-internal.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/event.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/packet.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/trace.h>
+#include <babeltrace/trace-ir/event-class.h>
+#include <babeltrace/trace-ir/event.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/trace-ir/packet.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/trace.h>
#include <babeltrace/graph/component-class-filter.h>
#include <babeltrace/graph/component-class-sink.h>
#include <babeltrace/graph/component-class-source.h>
+++ /dev/null
-/*
- * test_ctf_ir_ref.c
- *
- * CTF IR Reference Count test
- *
- * Copyright 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; under version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "tap/tap.h"
-#include <babeltrace/ctf-writer/clock.h>
-#include <babeltrace/ctf-writer/event.h>
-#include <babeltrace/ctf-writer/fields.h>
-#include <babeltrace/ctf-writer/stream-class.h>
-#include <babeltrace/ctf-writer/stream.h>
-#include <babeltrace/ctf-writer/trace.h>
-#include <babeltrace/ctf-writer/writer.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/event.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/trace.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/compat/stdlib-internal.h>
-#include <babeltrace/assert-internal.h>
-#include "common.h"
-
-#define NR_TESTS 37
-
-struct user {
- struct bt_trace *tc;
- struct bt_stream_class *sc;
- struct bt_event_class *ec;
- struct bt_stream *stream;
- struct bt_event *event;
-};
-
-struct writer_user {
- struct bt_ctf_writer *writer;
- struct bt_ctf_trace *tc;
- struct bt_ctf_stream_class *sc;
- struct bt_ctf_event_class *ec;
- struct bt_ctf_stream *stream;
- struct bt_ctf_event *event;
-};
-
-const char *writer_user_names[] = {
- "writer",
- "trace",
- "stream class",
- "event class",
- "stream",
- "event",
-};
-
-static const size_t WRITER_USER_NR_ELEMENTS =
- sizeof(struct writer_user) / sizeof(void *);
-
-/**
- * Returns a structure containing the following fields:
- * - uint8_t payload_8;
- * - uint16_t payload_16;
- * - uint32_t payload_32;
- */
-static struct bt_field_type *create_integer_struct(void)
-{
- int ret;
- struct bt_field_type *structure = NULL;
- struct bt_field_type *ui8 = NULL, *ui16 = NULL, *ui32 = NULL;
-
- structure = bt_field_type_structure_create();
- BT_ASSERT(structure);
- ui8 = bt_field_type_unsigned_integer_create();
- BT_ASSERT(ui8);
- ret = bt_field_type_integer_set_field_value_range(ui8, 8);
- BT_ASSERT(ret == 0);
- ret = bt_field_type_structure_append_member(structure,
- "payload_8", ui8);
- BT_ASSERT(ret == 0);
- ui16 = bt_field_type_unsigned_integer_create();
- BT_ASSERT(ui16);
- ret = bt_field_type_integer_set_field_value_range(ui16, 16);
- BT_ASSERT(ret == 0);
- ret = bt_field_type_structure_append_member(structure,
- "payload_16", ui16);
- BT_ASSERT(ret == 0);
- ui32 = bt_field_type_unsigned_integer_create();
- BT_ASSERT(ui32);
- ret = bt_field_type_integer_set_field_value_range(ui32, 32);
- BT_ASSERT(ret == 0);
- ret = bt_field_type_structure_append_member(structure,
- "payload_32", ui32);
- BT_ASSERT(ret == 0);
- BT_PUT(ui8);
- BT_PUT(ui16);
- BT_PUT(ui32);
- return structure;
-}
-
-static struct bt_ctf_field_type *create_writer_integer_struct(void)
-{
- int ret;
- struct bt_ctf_field_type *structure = NULL;
- struct bt_ctf_field_type *ui8 = NULL, *ui16 = NULL, *ui32 = NULL;
-
- structure = bt_ctf_field_type_structure_create();
- BT_ASSERT(structure);
- ui8 = bt_ctf_field_type_integer_create(8);
- BT_ASSERT(ui8);
- ret = bt_ctf_field_type_structure_add_field(structure, ui8,
- "payload_8");
- BT_ASSERT(ret == 0);
- ui16 = bt_ctf_field_type_integer_create(16);
- BT_ASSERT(ui16);
- ret = bt_ctf_field_type_structure_add_field(structure, ui16,
- "payload_16");
- BT_ASSERT(ret == 0);
- ui32 = bt_ctf_field_type_integer_create(32);
- BT_ASSERT(ui32);
- ret = bt_ctf_field_type_structure_add_field(structure, ui32,
- "payload_32");
- BT_ASSERT(ret == 0);
- BT_PUT(ui8);
- BT_PUT(ui16);
- BT_PUT(ui32);
- return structure;
-}
-
-/**
- * A simple event has the following payload:
- * - uint8_t payload_8;
- * - uint16_t payload_16;
- * - uint32_t payload_32;
- */
-static struct bt_event_class *create_simple_event(struct bt_stream_class *sc,
- const char *name)
-{
- int ret;
- struct bt_event_class *event = NULL;
- struct bt_field_type *payload = NULL;
-
- BT_ASSERT(name);
- event = bt_event_class_create(sc);
- BT_ASSERT(event);
- ret = bt_event_class_set_name(event, name);
- BT_ASSERT(ret == 0);
- payload = create_integer_struct();
- BT_ASSERT(payload);
- ret = bt_event_class_set_payload_field_type(event, payload);
- BT_ASSERT(ret == 0);
- BT_PUT(payload);
- return event;
-}
-
-/**
- * A complex event has the following payload:
- * - uint8_t payload_8;
- * - uint16_t payload_16;
- * - uint32_t payload_32;
- * - struct payload_struct:
- * - uint8_t payload_8;
- * - uint16_t payload_16;
- * - uint32_t payload_32;
- */
-static struct bt_event_class *create_complex_event(struct bt_stream_class *sc,
- const char *name)
-{
- int ret;
- struct bt_event_class *event = NULL;
- struct bt_field_type *inner = NULL, *outer = NULL;
-
- BT_ASSERT(name);
- event = bt_event_class_create(sc);
- BT_ASSERT(event);
- ret = bt_event_class_set_name(event, name);
- BT_ASSERT(ret == 0);
- outer = create_integer_struct();
- BT_ASSERT(outer);
- inner = create_integer_struct();
- BT_ASSERT(inner);
- ret = bt_field_type_structure_append_member(outer,
- "payload_struct", inner);
- BT_ASSERT(ret == 0);
- ret = bt_event_class_set_payload_field_type(event, outer);
- BT_ASSERT(ret == 0);
- BT_PUT(inner);
- BT_PUT(outer);
- return event;
-}
-
-static void set_stream_class_field_types(
- struct bt_stream_class *stream_class)
-{
- struct bt_field_type *packet_context_type;
- struct bt_field_type *event_header_type;
- struct bt_field_type *ft;
- int ret;
-
- packet_context_type = bt_field_type_structure_create();
- BT_ASSERT(packet_context_type);
- ft = bt_field_type_unsigned_integer_create();
- BT_ASSERT(ft);
- ret = bt_field_type_integer_set_field_value_range(ft, 32);
- BT_ASSERT(ret == 0);
- ret = bt_field_type_structure_append_member(packet_context_type,
- "packet_size", ft);
- BT_ASSERT(ret == 0);
- bt_put(ft);
- ft = bt_field_type_unsigned_integer_create();
- BT_ASSERT(ft);
- ret = bt_field_type_integer_set_field_value_range(ft, 32);
- BT_ASSERT(ret == 0);
- ret = bt_field_type_structure_append_member(packet_context_type,
- "content_size", ft);
- BT_ASSERT(ret == 0);
- bt_put(ft);
- event_header_type = bt_field_type_structure_create();
- BT_ASSERT(event_header_type);
- ft = bt_field_type_unsigned_integer_create();
- BT_ASSERT(ft);
- ret = bt_field_type_integer_set_field_value_range(ft, 32);
- BT_ASSERT(ret == 0);
- ret = bt_field_type_structure_append_member(event_header_type,
- "id", ft);
- BT_ASSERT(ret == 0);
- bt_put(ft);
- ret = bt_stream_class_set_packet_context_field_type(stream_class,
- packet_context_type);
- BT_ASSERT(ret == 0);
- ret = bt_stream_class_set_event_header_field_type(stream_class,
- event_header_type);
- BT_ASSERT(ret == 0);
- bt_put(packet_context_type);
- bt_put(event_header_type);
-}
-
-static void create_sc1(struct bt_trace *trace)
-{
- int ret;
- struct bt_event_class *ec1 = NULL, *ec2 = NULL;
- struct bt_stream_class *sc1 = NULL, *ret_stream = NULL;
-
- sc1 = bt_stream_class_create(trace);
- BT_ASSERT(sc1);
- ret = bt_stream_class_set_name(sc1, "sc1");
- BT_ASSERT(ret == 0);
- set_stream_class_field_types(sc1);
- ec1 = create_complex_event(sc1, "ec1");
- BT_ASSERT(ec1);
- ec2 = create_simple_event(sc1, "ec2");
- BT_ASSERT(ec2);
- ret_stream = bt_event_class_borrow_stream_class(ec1);
- ok(ret_stream == sc1, "Borrow parent stream SC1 from EC1");
- ret_stream = bt_event_class_borrow_stream_class(ec2);
- ok(ret_stream == sc1, "Borrow parent stream SC1 from EC2");
- BT_PUT(ec1);
- BT_PUT(ec2);
- BT_PUT(sc1);
-}
-
-static void create_sc2(struct bt_trace *trace)
-{
- int ret;
- struct bt_event_class *ec3 = NULL;
- struct bt_stream_class *sc2 = NULL, *ret_stream = NULL;
-
- sc2 = bt_stream_class_create(trace);
- BT_ASSERT(sc2);
- ret = bt_stream_class_set_name(sc2, "sc2");
- BT_ASSERT(ret == 0);
- set_stream_class_field_types(sc2);
- ec3 = create_simple_event(sc2, "ec3");
- ret_stream = bt_event_class_borrow_stream_class(ec3);
- ok(ret_stream == sc2, "Borrow parent stream SC2 from EC3");
- BT_PUT(ec3);
- BT_PUT(sc2);
-}
-
-static void set_trace_packet_header(struct bt_trace *trace)
-{
- struct bt_field_type *packet_header_type;
- struct bt_field_type *ft;
- int ret;
-
- packet_header_type = bt_field_type_structure_create();
- BT_ASSERT(packet_header_type);
- ft = bt_field_type_unsigned_integer_create();
- BT_ASSERT(ft);
- ret = bt_field_type_integer_set_field_value_range(ft, 32);
- BT_ASSERT(ret == 0);
- ret = bt_field_type_structure_append_member(packet_header_type,
- "stream_id", ft);
- BT_ASSERT(ret == 0);
- bt_put(ft);
- ret = bt_trace_set_packet_header_field_type(trace,
- packet_header_type);
- BT_ASSERT(ret == 0);
-
- bt_put(packet_header_type);
-}
-
-static struct bt_trace *create_tc1(void)
-{
- struct bt_trace *tc1 = NULL;
-
- tc1 = bt_trace_create();
- BT_ASSERT(tc1);
- set_trace_packet_header(tc1);
- create_sc1(tc1);
- create_sc2(tc1);
- return tc1;
-}
-
-static void init_weak_refs(struct bt_trace *tc,
- struct bt_trace **tc1,
- struct bt_stream_class **sc1,
- struct bt_stream_class **sc2,
- struct bt_event_class **ec1,
- struct bt_event_class **ec2,
- struct bt_event_class **ec3)
-{
- *tc1 = tc;
- *sc1 = bt_trace_borrow_stream_class_by_index(tc, 0);
- *sc2 = bt_trace_borrow_stream_class_by_index(tc, 1);
- *ec1 = bt_stream_class_borrow_event_class_by_index(*sc1, 0);
- *ec2 = bt_stream_class_borrow_event_class_by_index(*sc1, 1);
- *ec3 = bt_stream_class_borrow_event_class_by_index(*sc2, 0);
-}
-
-static void test_example_scenario(void)
-{
- /**
- * Weak pointers to CTF-IR objects are to be used very carefully.
- * This is NOT a good practice and is strongly discouraged; this
- * is only done to facilitate the validation of expected reference
- * counts without affecting them by taking "real" references to the
- * objects.
- */
- struct bt_trace *tc1 = NULL, *weak_tc1 = NULL;
- struct bt_stream_class *weak_sc1 = NULL, *weak_sc2 = NULL;
- struct bt_event_class *weak_ec1 = NULL, *weak_ec2 = NULL,
- *weak_ec3 = NULL;
- struct user user_a = { 0 }, user_b = { 0 }, user_c = { 0 };
-
- /* The only reference which exists at this point is on TC1. */
- tc1 = create_tc1();
- ok(tc1, "Initialize trace");
- BT_ASSERT(tc1);
- init_weak_refs(tc1, &weak_tc1, &weak_sc1, &weak_sc2, &weak_ec1,
- &weak_ec2, &weak_ec3);
- ok(bt_object_get_ref_count((void *) weak_sc1) == 0,
- "Initial SC1 reference count is 0");
- ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
- "Initial SC2 reference count is 0");
- ok(bt_object_get_ref_count((void *) weak_ec1) == 0,
- "Initial EC1 reference count is 0");
- ok(bt_object_get_ref_count((void *) weak_ec2) == 0,
- "Initial EC2 reference count is 0");
- ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
- "Initial EC3 reference count is 0");
-
- /* User A has ownership of the trace. */
- BT_MOVE(user_a.tc, tc1);
- ok(bt_object_get_ref_count((void *) user_a.tc) == 1,
- "TC1 reference count is 1");
-
- /* User A acquires a reference to SC2 from TC1. */
- user_a.sc = bt_get(bt_trace_borrow_stream_class_by_index(user_a.tc, 1));
- ok(user_a.sc, "User A acquires SC2 from TC1");
- ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
- "TC1 reference count is 2");
- ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
- "SC2 reference count is 1");
-
- /* User A acquires a reference to EC3 from SC2. */
- user_a.ec = bt_get(
- bt_stream_class_borrow_event_class_by_index(user_a.sc, 0));
- ok(user_a.ec, "User A acquires EC3 from SC2");
- ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
- "TC1 reference count is 2");
- ok(bt_object_get_ref_count((void *) weak_sc2) == 2,
- "SC2 reference count is 2");
- ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
- "EC3 reference count is 1");
-
- /* User A releases its reference to SC2. */
- diag("User A releases SC2");
- BT_PUT(user_a.sc);
- /*
- * We keep the pointer to SC2 around to validate its reference
- * count.
- */
- ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
- "TC1 reference count is 2");
- ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
- "SC2 reference count is 1");
- ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
- "EC3 reference count is 1");
-
- /* User A releases its reference to TC1. */
- diag("User A releases TC1");
- BT_PUT(user_a.tc);
- /*
- * We keep the pointer to TC1 around to validate its reference
- * count.
- */
- ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
- "TC1 reference count is 1");
- ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
- "SC2 reference count is 1");
- ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
- "EC3 reference count is 1");
-
- /* User B acquires a reference to SC1. */
- diag("User B acquires a reference to SC1");
- user_b.sc = bt_get(weak_sc1);
- ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
- "TC1 reference count is 2");
- ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
- "SC1 reference count is 1");
-
- /* User C acquires a reference to EC1. */
- diag("User C acquires a reference to EC1");
- user_c.ec = bt_get(
- bt_stream_class_borrow_event_class_by_index(user_b.sc, 0));
- ok(bt_object_get_ref_count((void *) weak_ec1) == 1,
- "EC1 reference count is 1");
- ok(bt_object_get_ref_count((void *) weak_sc1) == 2,
- "SC1 reference count is 2");
-
- /* User A releases its reference on EC3. */
- diag("User A releases its reference on EC3");
- BT_PUT(user_a.ec);
- ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
- "EC3 reference count is 1");
- ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
- "SC2 reference count is 0");
- ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
- "TC1 reference count is 1");
-
- /* User B releases its reference on SC1. */
- diag("User B releases its reference on SC1");
- BT_PUT(user_b.sc);
- ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
- "SC1 reference count is 1");
-
- /*
- * User C is the sole owner of an object and is keeping the whole
- * trace hierarchy "alive" by holding a reference to EC1.
- */
- ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
- "TC1 reference count is 1");
- ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
- "SC1 reference count is 1");
- ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
- "SC2 reference count is 0");
- ok(bt_object_get_ref_count((void *) weak_ec1) == 1,
- "EC1 reference count is 1");
- ok(bt_object_get_ref_count((void *) weak_ec2) == 0,
- "EC2 reference count is 0");
- ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
- "EC3 reference count is 0");
-
- /* Reclaim last reference held by User C. */
- BT_PUT(user_c.ec);
-}
-
-static void create_writer_user_full(struct writer_user *user)
-{
- gchar *trace_path;
- struct bt_ctf_field_type *ft;
- struct bt_ctf_field *field;
- struct bt_ctf_clock *clock;
- int ret;
-
- trace_path = g_build_filename(g_get_tmp_dir(), "ctfwriter_XXXXXX", NULL);
- if (!bt_mkdtemp(trace_path)) {
- perror("# perror");
- }
-
- user->writer = bt_ctf_writer_create(trace_path);
- BT_ASSERT(user->writer);
- ret = bt_ctf_writer_set_byte_order(user->writer,
- BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
- BT_ASSERT(ret == 0);
- user->tc = bt_ctf_writer_get_trace(user->writer);
- BT_ASSERT(user->tc);
- user->sc = bt_ctf_stream_class_create("sc");
- BT_ASSERT(user->sc);
- clock = bt_ctf_clock_create("the_clock");
- BT_ASSERT(clock);
- ret = bt_ctf_writer_add_clock(user->writer, clock);
- BT_ASSERT(!ret);
- ret = bt_ctf_stream_class_set_clock(user->sc, clock);
- BT_ASSERT(!ret);
- BT_PUT(clock);
- user->stream = bt_ctf_writer_create_stream(user->writer, user->sc);
- BT_ASSERT(user->stream);
- user->ec = bt_ctf_event_class_create("ec");
- BT_ASSERT(user->ec);
- ft = create_writer_integer_struct();
- BT_ASSERT(ft);
- ret = bt_ctf_event_class_set_payload_field_type(user->ec, ft);
- BT_PUT(ft);
- BT_ASSERT(!ret);
- ret = bt_ctf_stream_class_add_event_class(user->sc, user->ec);
- BT_ASSERT(!ret);
- user->event = bt_ctf_event_create(user->ec);
- BT_ASSERT(user->event);
- field = bt_ctf_event_get_payload(user->event, "payload_8");
- BT_ASSERT(field);
- ret = bt_ctf_field_integer_unsigned_set_value(field, 10);
- BT_ASSERT(!ret);
- BT_PUT(field);
- field = bt_ctf_event_get_payload(user->event, "payload_16");
- BT_ASSERT(field);
- ret = bt_ctf_field_integer_unsigned_set_value(field, 20);
- BT_ASSERT(!ret);
- BT_PUT(field);
- field = bt_ctf_event_get_payload(user->event, "payload_32");
- BT_ASSERT(field);
- ret = bt_ctf_field_integer_unsigned_set_value(field, 30);
- BT_ASSERT(!ret);
- BT_PUT(field);
- ret = bt_ctf_stream_append_event(user->stream, user->event);
- BT_ASSERT(!ret);
- recursive_rmdir(trace_path);
- g_free(trace_path);
-}
-
-static void test_put_order_swap(size_t *array, size_t a, size_t b)
-{
- size_t temp = array[a];
-
- array[a] = array[b];
- array[b] = temp;
-}
-
-static void test_put_order_put_objects(size_t *array, size_t size)
-{
- size_t i;
- struct writer_user user = { 0 };
- void **objects = (void *) &user;
-
- create_writer_user_full(&user);
- printf("# ");
-
- for (i = 0; i < size; ++i) {
- void *obj = objects[array[i]];
-
- printf("%s", writer_user_names[array[i]]);
- BT_PUT(obj);
-
- if (i < size - 1) {
- printf(" -> ");
- }
- }
-
- puts("");
-}
-
-static void test_put_order_permute(size_t *array, int k, size_t size)
-{
- if (k == 0) {
- test_put_order_put_objects(array, size);
- } else {
- int i;
-
- for (i = k - 1; i >= 0; i--) {
- size_t next_k = k - 1;
-
- test_put_order_swap(array, i, next_k);
- test_put_order_permute(array, next_k, size);
- test_put_order_swap(array, i, next_k);
- }
- }
-}
-
-static void test_put_order(void)
-{
- size_t i;
- size_t array[WRITER_USER_NR_ELEMENTS];
-
- /* Initialize array of indexes */
- for (i = 0; i < WRITER_USER_NR_ELEMENTS; ++i) {
- array[i] = i;
- }
-
- test_put_order_permute(array, WRITER_USER_NR_ELEMENTS,
- WRITER_USER_NR_ELEMENTS);
-}
-
-/**
- * The objective of this test is to implement and expand upon the scenario
- * described in the reference counting documentation and ensure that any node of
- * the Trace, Stream Class, Event Class, Stream and Event hiearchy keeps all
- * other "alive" and reachable.
- *
- * External tools (e.g. valgrind) should be used to confirm that this
- * known-good test does not leak memory.
- */
-int main(int argc, char **argv)
-{
- /* Initialize tap harness before any tests */
- plan_tests(NR_TESTS);
-
- test_example_scenario();
- test_put_order();
-
- return exit_status();
-}
/*
* test_ir_visit.c
*
- * CTF IR visitor interface test
+ * Trace IR visitor interface test
*
* Copyright 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
#include "tap/tap.h"
#include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/trace.h>
-#include <babeltrace/ctf-ir/visitor.h>
+#include <babeltrace/trace-ir/event-class.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/trace.h>
+#include <babeltrace/trace-ir/visitor.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
/*
* test_plugin.c
*
- * CTF IR Reference Count test
+ * Trace IR Reference Count test
*
* Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
*
--- /dev/null
+/*
+ * test_trace_ir_ref.c
+ *
+ * Trace IR Reference Count test
+ *
+ * Copyright 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "tap/tap.h"
+#include <babeltrace/ctf-writer/clock.h>
+#include <babeltrace/ctf-writer/event.h>
+#include <babeltrace/ctf-writer/fields.h>
+#include <babeltrace/ctf-writer/stream-class.h>
+#include <babeltrace/ctf-writer/stream.h>
+#include <babeltrace/ctf-writer/trace.h>
+#include <babeltrace/ctf-writer/writer.h>
+#include <babeltrace/trace-ir/clock-class.h>
+#include <babeltrace/trace-ir/event.h>
+#include <babeltrace/trace-ir/event-class.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/trace.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/compat/stdlib-internal.h>
+#include <babeltrace/assert-internal.h>
+#include "common.h"
+
+#define NR_TESTS 37
+
+struct user {
+ struct bt_trace *tc;
+ struct bt_stream_class *sc;
+ struct bt_event_class *ec;
+ struct bt_stream *stream;
+ struct bt_event *event;
+};
+
+struct writer_user {
+ struct bt_ctf_writer *writer;
+ struct bt_ctf_trace *tc;
+ struct bt_ctf_stream_class *sc;
+ struct bt_ctf_event_class *ec;
+ struct bt_ctf_stream *stream;
+ struct bt_ctf_event *event;
+};
+
+const char *writer_user_names[] = {
+ "writer",
+ "trace",
+ "stream class",
+ "event class",
+ "stream",
+ "event",
+};
+
+static const size_t WRITER_USER_NR_ELEMENTS =
+ sizeof(struct writer_user) / sizeof(void *);
+
+/**
+ * Returns a structure containing the following fields:
+ * - uint8_t payload_8;
+ * - uint16_t payload_16;
+ * - uint32_t payload_32;
+ */
+static struct bt_field_type *create_integer_struct(void)
+{
+ int ret;
+ struct bt_field_type *structure = NULL;
+ struct bt_field_type *ui8 = NULL, *ui16 = NULL, *ui32 = NULL;
+
+ structure = bt_field_type_structure_create();
+ BT_ASSERT(structure);
+ ui8 = bt_field_type_unsigned_integer_create();
+ BT_ASSERT(ui8);
+ ret = bt_field_type_integer_set_field_value_range(ui8, 8);
+ BT_ASSERT(ret == 0);
+ ret = bt_field_type_structure_append_member(structure,
+ "payload_8", ui8);
+ BT_ASSERT(ret == 0);
+ ui16 = bt_field_type_unsigned_integer_create();
+ BT_ASSERT(ui16);
+ ret = bt_field_type_integer_set_field_value_range(ui16, 16);
+ BT_ASSERT(ret == 0);
+ ret = bt_field_type_structure_append_member(structure,
+ "payload_16", ui16);
+ BT_ASSERT(ret == 0);
+ ui32 = bt_field_type_unsigned_integer_create();
+ BT_ASSERT(ui32);
+ ret = bt_field_type_integer_set_field_value_range(ui32, 32);
+ BT_ASSERT(ret == 0);
+ ret = bt_field_type_structure_append_member(structure,
+ "payload_32", ui32);
+ BT_ASSERT(ret == 0);
+ BT_PUT(ui8);
+ BT_PUT(ui16);
+ BT_PUT(ui32);
+ return structure;
+}
+
+static struct bt_ctf_field_type *create_writer_integer_struct(void)
+{
+ int ret;
+ struct bt_ctf_field_type *structure = NULL;
+ struct bt_ctf_field_type *ui8 = NULL, *ui16 = NULL, *ui32 = NULL;
+
+ structure = bt_ctf_field_type_structure_create();
+ BT_ASSERT(structure);
+ ui8 = bt_ctf_field_type_integer_create(8);
+ BT_ASSERT(ui8);
+ ret = bt_ctf_field_type_structure_add_field(structure, ui8,
+ "payload_8");
+ BT_ASSERT(ret == 0);
+ ui16 = bt_ctf_field_type_integer_create(16);
+ BT_ASSERT(ui16);
+ ret = bt_ctf_field_type_structure_add_field(structure, ui16,
+ "payload_16");
+ BT_ASSERT(ret == 0);
+ ui32 = bt_ctf_field_type_integer_create(32);
+ BT_ASSERT(ui32);
+ ret = bt_ctf_field_type_structure_add_field(structure, ui32,
+ "payload_32");
+ BT_ASSERT(ret == 0);
+ BT_PUT(ui8);
+ BT_PUT(ui16);
+ BT_PUT(ui32);
+ return structure;
+}
+
+/**
+ * A simple event has the following payload:
+ * - uint8_t payload_8;
+ * - uint16_t payload_16;
+ * - uint32_t payload_32;
+ */
+static struct bt_event_class *create_simple_event(struct bt_stream_class *sc,
+ const char *name)
+{
+ int ret;
+ struct bt_event_class *event = NULL;
+ struct bt_field_type *payload = NULL;
+
+ BT_ASSERT(name);
+ event = bt_event_class_create(sc);
+ BT_ASSERT(event);
+ ret = bt_event_class_set_name(event, name);
+ BT_ASSERT(ret == 0);
+ payload = create_integer_struct();
+ BT_ASSERT(payload);
+ ret = bt_event_class_set_payload_field_type(event, payload);
+ BT_ASSERT(ret == 0);
+ BT_PUT(payload);
+ return event;
+}
+
+/**
+ * A complex event has the following payload:
+ * - uint8_t payload_8;
+ * - uint16_t payload_16;
+ * - uint32_t payload_32;
+ * - struct payload_struct:
+ * - uint8_t payload_8;
+ * - uint16_t payload_16;
+ * - uint32_t payload_32;
+ */
+static struct bt_event_class *create_complex_event(struct bt_stream_class *sc,
+ const char *name)
+{
+ int ret;
+ struct bt_event_class *event = NULL;
+ struct bt_field_type *inner = NULL, *outer = NULL;
+
+ BT_ASSERT(name);
+ event = bt_event_class_create(sc);
+ BT_ASSERT(event);
+ ret = bt_event_class_set_name(event, name);
+ BT_ASSERT(ret == 0);
+ outer = create_integer_struct();
+ BT_ASSERT(outer);
+ inner = create_integer_struct();
+ BT_ASSERT(inner);
+ ret = bt_field_type_structure_append_member(outer,
+ "payload_struct", inner);
+ BT_ASSERT(ret == 0);
+ ret = bt_event_class_set_payload_field_type(event, outer);
+ BT_ASSERT(ret == 0);
+ BT_PUT(inner);
+ BT_PUT(outer);
+ return event;
+}
+
+static void set_stream_class_field_types(
+ struct bt_stream_class *stream_class)
+{
+ struct bt_field_type *packet_context_type;
+ struct bt_field_type *event_header_type;
+ struct bt_field_type *ft;
+ int ret;
+
+ packet_context_type = bt_field_type_structure_create();
+ BT_ASSERT(packet_context_type);
+ ft = bt_field_type_unsigned_integer_create();
+ BT_ASSERT(ft);
+ ret = bt_field_type_integer_set_field_value_range(ft, 32);
+ BT_ASSERT(ret == 0);
+ ret = bt_field_type_structure_append_member(packet_context_type,
+ "packet_size", ft);
+ BT_ASSERT(ret == 0);
+ bt_put(ft);
+ ft = bt_field_type_unsigned_integer_create();
+ BT_ASSERT(ft);
+ ret = bt_field_type_integer_set_field_value_range(ft, 32);
+ BT_ASSERT(ret == 0);
+ ret = bt_field_type_structure_append_member(packet_context_type,
+ "content_size", ft);
+ BT_ASSERT(ret == 0);
+ bt_put(ft);
+ event_header_type = bt_field_type_structure_create();
+ BT_ASSERT(event_header_type);
+ ft = bt_field_type_unsigned_integer_create();
+ BT_ASSERT(ft);
+ ret = bt_field_type_integer_set_field_value_range(ft, 32);
+ BT_ASSERT(ret == 0);
+ ret = bt_field_type_structure_append_member(event_header_type,
+ "id", ft);
+ BT_ASSERT(ret == 0);
+ bt_put(ft);
+ ret = bt_stream_class_set_packet_context_field_type(stream_class,
+ packet_context_type);
+ BT_ASSERT(ret == 0);
+ ret = bt_stream_class_set_event_header_field_type(stream_class,
+ event_header_type);
+ BT_ASSERT(ret == 0);
+ bt_put(packet_context_type);
+ bt_put(event_header_type);
+}
+
+static void create_sc1(struct bt_trace *trace)
+{
+ int ret;
+ struct bt_event_class *ec1 = NULL, *ec2 = NULL;
+ struct bt_stream_class *sc1 = NULL, *ret_stream = NULL;
+
+ sc1 = bt_stream_class_create(trace);
+ BT_ASSERT(sc1);
+ ret = bt_stream_class_set_name(sc1, "sc1");
+ BT_ASSERT(ret == 0);
+ set_stream_class_field_types(sc1);
+ ec1 = create_complex_event(sc1, "ec1");
+ BT_ASSERT(ec1);
+ ec2 = create_simple_event(sc1, "ec2");
+ BT_ASSERT(ec2);
+ ret_stream = bt_event_class_borrow_stream_class(ec1);
+ ok(ret_stream == sc1, "Borrow parent stream SC1 from EC1");
+ ret_stream = bt_event_class_borrow_stream_class(ec2);
+ ok(ret_stream == sc1, "Borrow parent stream SC1 from EC2");
+ BT_PUT(ec1);
+ BT_PUT(ec2);
+ BT_PUT(sc1);
+}
+
+static void create_sc2(struct bt_trace *trace)
+{
+ int ret;
+ struct bt_event_class *ec3 = NULL;
+ struct bt_stream_class *sc2 = NULL, *ret_stream = NULL;
+
+ sc2 = bt_stream_class_create(trace);
+ BT_ASSERT(sc2);
+ ret = bt_stream_class_set_name(sc2, "sc2");
+ BT_ASSERT(ret == 0);
+ set_stream_class_field_types(sc2);
+ ec3 = create_simple_event(sc2, "ec3");
+ ret_stream = bt_event_class_borrow_stream_class(ec3);
+ ok(ret_stream == sc2, "Borrow parent stream SC2 from EC3");
+ BT_PUT(ec3);
+ BT_PUT(sc2);
+}
+
+static void set_trace_packet_header(struct bt_trace *trace)
+{
+ struct bt_field_type *packet_header_type;
+ struct bt_field_type *ft;
+ int ret;
+
+ packet_header_type = bt_field_type_structure_create();
+ BT_ASSERT(packet_header_type);
+ ft = bt_field_type_unsigned_integer_create();
+ BT_ASSERT(ft);
+ ret = bt_field_type_integer_set_field_value_range(ft, 32);
+ BT_ASSERT(ret == 0);
+ ret = bt_field_type_structure_append_member(packet_header_type,
+ "stream_id", ft);
+ BT_ASSERT(ret == 0);
+ bt_put(ft);
+ ret = bt_trace_set_packet_header_field_type(trace,
+ packet_header_type);
+ BT_ASSERT(ret == 0);
+
+ bt_put(packet_header_type);
+}
+
+static struct bt_trace *create_tc1(void)
+{
+ struct bt_trace *tc1 = NULL;
+
+ tc1 = bt_trace_create();
+ BT_ASSERT(tc1);
+ set_trace_packet_header(tc1);
+ create_sc1(tc1);
+ create_sc2(tc1);
+ return tc1;
+}
+
+static void init_weak_refs(struct bt_trace *tc,
+ struct bt_trace **tc1,
+ struct bt_stream_class **sc1,
+ struct bt_stream_class **sc2,
+ struct bt_event_class **ec1,
+ struct bt_event_class **ec2,
+ struct bt_event_class **ec3)
+{
+ *tc1 = tc;
+ *sc1 = bt_trace_borrow_stream_class_by_index(tc, 0);
+ *sc2 = bt_trace_borrow_stream_class_by_index(tc, 1);
+ *ec1 = bt_stream_class_borrow_event_class_by_index(*sc1, 0);
+ *ec2 = bt_stream_class_borrow_event_class_by_index(*sc1, 1);
+ *ec3 = bt_stream_class_borrow_event_class_by_index(*sc2, 0);
+}
+
+static void test_example_scenario(void)
+{
+ /*
+ * Weak pointers to trace IR objects are to be used very
+ * carefully. This is NOT a good practice and is strongly
+ * discouraged; this is only done to facilitate the validation
+ * of expected reference counts without affecting them by taking
+ * "real" references to the objects.
+ */
+ struct bt_trace *tc1 = NULL, *weak_tc1 = NULL;
+ struct bt_stream_class *weak_sc1 = NULL, *weak_sc2 = NULL;
+ struct bt_event_class *weak_ec1 = NULL, *weak_ec2 = NULL,
+ *weak_ec3 = NULL;
+ struct user user_a = { 0 }, user_b = { 0 }, user_c = { 0 };
+
+ /* The only reference which exists at this point is on TC1. */
+ tc1 = create_tc1();
+ ok(tc1, "Initialize trace");
+ BT_ASSERT(tc1);
+ init_weak_refs(tc1, &weak_tc1, &weak_sc1, &weak_sc2, &weak_ec1,
+ &weak_ec2, &weak_ec3);
+ ok(bt_object_get_ref_count((void *) weak_sc1) == 0,
+ "Initial SC1 reference count is 0");
+ ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
+ "Initial SC2 reference count is 0");
+ ok(bt_object_get_ref_count((void *) weak_ec1) == 0,
+ "Initial EC1 reference count is 0");
+ ok(bt_object_get_ref_count((void *) weak_ec2) == 0,
+ "Initial EC2 reference count is 0");
+ ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
+ "Initial EC3 reference count is 0");
+
+ /* User A has ownership of the trace. */
+ BT_MOVE(user_a.tc, tc1);
+ ok(bt_object_get_ref_count((void *) user_a.tc) == 1,
+ "TC1 reference count is 1");
+
+ /* User A acquires a reference to SC2 from TC1. */
+ user_a.sc = bt_get(bt_trace_borrow_stream_class_by_index(user_a.tc, 1));
+ ok(user_a.sc, "User A acquires SC2 from TC1");
+ ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
+ "TC1 reference count is 2");
+ ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
+ "SC2 reference count is 1");
+
+ /* User A acquires a reference to EC3 from SC2. */
+ user_a.ec = bt_get(
+ bt_stream_class_borrow_event_class_by_index(user_a.sc, 0));
+ ok(user_a.ec, "User A acquires EC3 from SC2");
+ ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
+ "TC1 reference count is 2");
+ ok(bt_object_get_ref_count((void *) weak_sc2) == 2,
+ "SC2 reference count is 2");
+ ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
+ "EC3 reference count is 1");
+
+ /* User A releases its reference to SC2. */
+ diag("User A releases SC2");
+ BT_PUT(user_a.sc);
+ /*
+ * We keep the pointer to SC2 around to validate its reference
+ * count.
+ */
+ ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
+ "TC1 reference count is 2");
+ ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
+ "SC2 reference count is 1");
+ ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
+ "EC3 reference count is 1");
+
+ /* User A releases its reference to TC1. */
+ diag("User A releases TC1");
+ BT_PUT(user_a.tc);
+ /*
+ * We keep the pointer to TC1 around to validate its reference
+ * count.
+ */
+ ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
+ "TC1 reference count is 1");
+ ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
+ "SC2 reference count is 1");
+ ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
+ "EC3 reference count is 1");
+
+ /* User B acquires a reference to SC1. */
+ diag("User B acquires a reference to SC1");
+ user_b.sc = bt_get(weak_sc1);
+ ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
+ "TC1 reference count is 2");
+ ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
+ "SC1 reference count is 1");
+
+ /* User C acquires a reference to EC1. */
+ diag("User C acquires a reference to EC1");
+ user_c.ec = bt_get(
+ bt_stream_class_borrow_event_class_by_index(user_b.sc, 0));
+ ok(bt_object_get_ref_count((void *) weak_ec1) == 1,
+ "EC1 reference count is 1");
+ ok(bt_object_get_ref_count((void *) weak_sc1) == 2,
+ "SC1 reference count is 2");
+
+ /* User A releases its reference on EC3. */
+ diag("User A releases its reference on EC3");
+ BT_PUT(user_a.ec);
+ ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
+ "EC3 reference count is 1");
+ ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
+ "SC2 reference count is 0");
+ ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
+ "TC1 reference count is 1");
+
+ /* User B releases its reference on SC1. */
+ diag("User B releases its reference on SC1");
+ BT_PUT(user_b.sc);
+ ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
+ "SC1 reference count is 1");
+
+ /*
+ * User C is the sole owner of an object and is keeping the whole
+ * trace hierarchy "alive" by holding a reference to EC1.
+ */
+ ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
+ "TC1 reference count is 1");
+ ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
+ "SC1 reference count is 1");
+ ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
+ "SC2 reference count is 0");
+ ok(bt_object_get_ref_count((void *) weak_ec1) == 1,
+ "EC1 reference count is 1");
+ ok(bt_object_get_ref_count((void *) weak_ec2) == 0,
+ "EC2 reference count is 0");
+ ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
+ "EC3 reference count is 0");
+
+ /* Reclaim last reference held by User C. */
+ BT_PUT(user_c.ec);
+}
+
+static void create_writer_user_full(struct writer_user *user)
+{
+ gchar *trace_path;
+ struct bt_ctf_field_type *ft;
+ struct bt_ctf_field *field;
+ struct bt_ctf_clock *clock;
+ int ret;
+
+ trace_path = g_build_filename(g_get_tmp_dir(), "ctfwriter_XXXXXX", NULL);
+ if (!bt_mkdtemp(trace_path)) {
+ perror("# perror");
+ }
+
+ user->writer = bt_ctf_writer_create(trace_path);
+ BT_ASSERT(user->writer);
+ ret = bt_ctf_writer_set_byte_order(user->writer,
+ BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
+ BT_ASSERT(ret == 0);
+ user->tc = bt_ctf_writer_get_trace(user->writer);
+ BT_ASSERT(user->tc);
+ user->sc = bt_ctf_stream_class_create("sc");
+ BT_ASSERT(user->sc);
+ clock = bt_ctf_clock_create("the_clock");
+ BT_ASSERT(clock);
+ ret = bt_ctf_writer_add_clock(user->writer, clock);
+ BT_ASSERT(!ret);
+ ret = bt_ctf_stream_class_set_clock(user->sc, clock);
+ BT_ASSERT(!ret);
+ BT_PUT(clock);
+ user->stream = bt_ctf_writer_create_stream(user->writer, user->sc);
+ BT_ASSERT(user->stream);
+ user->ec = bt_ctf_event_class_create("ec");
+ BT_ASSERT(user->ec);
+ ft = create_writer_integer_struct();
+ BT_ASSERT(ft);
+ ret = bt_ctf_event_class_set_payload_field_type(user->ec, ft);
+ BT_PUT(ft);
+ BT_ASSERT(!ret);
+ ret = bt_ctf_stream_class_add_event_class(user->sc, user->ec);
+ BT_ASSERT(!ret);
+ user->event = bt_ctf_event_create(user->ec);
+ BT_ASSERT(user->event);
+ field = bt_ctf_event_get_payload(user->event, "payload_8");
+ BT_ASSERT(field);
+ ret = bt_ctf_field_integer_unsigned_set_value(field, 10);
+ BT_ASSERT(!ret);
+ BT_PUT(field);
+ field = bt_ctf_event_get_payload(user->event, "payload_16");
+ BT_ASSERT(field);
+ ret = bt_ctf_field_integer_unsigned_set_value(field, 20);
+ BT_ASSERT(!ret);
+ BT_PUT(field);
+ field = bt_ctf_event_get_payload(user->event, "payload_32");
+ BT_ASSERT(field);
+ ret = bt_ctf_field_integer_unsigned_set_value(field, 30);
+ BT_ASSERT(!ret);
+ BT_PUT(field);
+ ret = bt_ctf_stream_append_event(user->stream, user->event);
+ BT_ASSERT(!ret);
+ recursive_rmdir(trace_path);
+ g_free(trace_path);
+}
+
+static void test_put_order_swap(size_t *array, size_t a, size_t b)
+{
+ size_t temp = array[a];
+
+ array[a] = array[b];
+ array[b] = temp;
+}
+
+static void test_put_order_put_objects(size_t *array, size_t size)
+{
+ size_t i;
+ struct writer_user user = { 0 };
+ void **objects = (void *) &user;
+
+ create_writer_user_full(&user);
+ printf("# ");
+
+ for (i = 0; i < size; ++i) {
+ void *obj = objects[array[i]];
+
+ printf("%s", writer_user_names[array[i]]);
+ BT_PUT(obj);
+
+ if (i < size - 1) {
+ printf(" -> ");
+ }
+ }
+
+ puts("");
+}
+
+static void test_put_order_permute(size_t *array, int k, size_t size)
+{
+ if (k == 0) {
+ test_put_order_put_objects(array, size);
+ } else {
+ int i;
+
+ for (i = k - 1; i >= 0; i--) {
+ size_t next_k = k - 1;
+
+ test_put_order_swap(array, i, next_k);
+ test_put_order_permute(array, next_k, size);
+ test_put_order_swap(array, i, next_k);
+ }
+ }
+}
+
+static void test_put_order(void)
+{
+ size_t i;
+ size_t array[WRITER_USER_NR_ELEMENTS];
+
+ /* Initialize array of indexes */
+ for (i = 0; i < WRITER_USER_NR_ELEMENTS; ++i) {
+ array[i] = i;
+ }
+
+ test_put_order_permute(array, WRITER_USER_NR_ELEMENTS,
+ WRITER_USER_NR_ELEMENTS);
+}
+
+/**
+ * The objective of this test is to implement and expand upon the scenario
+ * described in the reference counting documentation and ensure that any node of
+ * the Trace, Stream Class, Event Class, Stream and Event hiearchy keeps all
+ * other "alive" and reachable.
+ *
+ * External tools (e.g. valgrind) should be used to confirm that this
+ * known-good test does not leak memory.
+ */
+int main(int argc, char **argv)
+{
+ /* Initialize tap harness before any tests */
+ plan_tests(NR_TESTS);
+
+ test_example_scenario();
+ test_put_order();
+
+ return exit_status();
+}
--- /dev/null
+if ENABLE_PYTHON_BINDINGS
+check_SCRIPTS = test_trace_ir
+endif
+
+EXTRA_DIST = test_trace.py test_stream_class.py
--- /dev/null
+import unittest
+import bt2
+
+
+class StreamClassSingleClockClassTestCase(unittest.TestCase):
+ def setUp(self):
+ self._sc = bt2.StreamClass()
+
+ def tearDown(self):
+ del self._sc
+
+ def _test_add_sc_ft_vs_event_class(self, set_ft_func):
+ cc = bt2.ClockClass('first_cc', 1000)
+ scft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ scft.append_field('salut', ft)
+ set_ft_func(scft)
+ cc = bt2.ClockClass('second_cc', 1000)
+ payloadft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ payloadft.append_field('zorg', ft)
+ ec = bt2.EventClass('ec', payload_field_type=payloadft)
+ self._sc.add_event_class(ec)
+ trace = bt2.Trace()
+
+ with self.assertRaises(bt2.Error):
+ trace.add_stream_class(self._sc)
+
+ def test_add_sc_packet_context_vs_event_class(self):
+ def func(ft):
+ self._sc.packet_context_field_type = ft
+
+ self._test_add_sc_ft_vs_event_class(func)
+
+ def test_add_sc_event_context_vs_event_class(self):
+ def func(ft):
+ self._sc.event_context_field_type = ft
+
+ self._test_add_sc_ft_vs_event_class(func)
+
+ def test_add_sc_event_header_vs_event_class(self):
+ def func(ft):
+ self._sc.event_header_field_type = ft
+
+ self._test_add_sc_ft_vs_event_class(func)
+
+ def test_add_sc_event_class_vs_event_class(self):
+ ehft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32)
+ ehft.append_field('id', ft)
+ self._sc.event_header_field_type = ehft
+ cc = bt2.ClockClass('first_cc', 1000)
+ payloadft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ payloadft.append_field('zorg', ft)
+ ec1 = bt2.EventClass('ec', payload_field_type=payloadft)
+ cc = bt2.ClockClass('second_cc', 1000)
+ payloadft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ payloadft.append_field('logi', ft)
+ ec2 = bt2.EventClass('ec', payload_field_type=payloadft)
+ self._sc.add_event_class(ec1)
+ self._sc.add_event_class(ec2)
+ trace = bt2.Trace()
+
+ with self.assertRaises(bt2.Error):
+ trace.add_stream_class(self._sc)
+
+ def _test_create_event_ft_vs_event_class(self, set_ft_func):
+ cc = bt2.ClockClass('first_cc', 1000)
+ scft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ scft.append_field('salut', ft)
+ set_ft_func(scft)
+ cc = bt2.ClockClass('second_cc', 1000)
+ payloadft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ payloadft.append_field('zorg', ft)
+ ec = bt2.EventClass('ec', payload_field_type=payloadft)
+ self._sc.add_event_class(ec)
+
+ with self.assertRaises(bt2.Error):
+ ev = ec()
+
+ def test_create_event_packet_context_vs_event_class(self):
+ def func(ft):
+ self._sc.packet_context_field_type = ft
+
+ self._test_create_event_ft_vs_event_class(func)
+
+ def test_create_event_event_context_vs_event_class(self):
+ def func(ft):
+ self._sc.event_context_field_type = ft
+
+ self._test_create_event_ft_vs_event_class(func)
+
+ def test_create_event_event_header_vs_event_class(self):
+ def func(ft):
+ self._sc.event_header_field_type = ft
+
+ self._test_create_event_ft_vs_event_class(func)
+
+ def test_create_event_event_class_vs_event_class(self):
+ ehft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32)
+ ehft.append_field('id', ft)
+ self._sc.event_header_field_type = ehft
+ cc = bt2.ClockClass('first_cc', 1000)
+ payloadft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ payloadft.append_field('zorg', ft)
+ ec1 = bt2.EventClass('ec', payload_field_type=payloadft)
+ cc = bt2.ClockClass('second_cc', 1000)
+ payloadft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ payloadft.append_field('logi', ft)
+ ec2 = bt2.EventClass('ec', payload_field_type=payloadft)
+ self._sc.add_event_class(ec1)
+ self._sc.add_event_class(ec2)
+
+ with self.assertRaises(bt2.Error):
+ ev = ec1()
+
+ def test_add_ec_after_add_sc(self):
+ cc = bt2.ClockClass('first_cc', 1000)
+ scft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ scft.append_field('salut', ft)
+ self._sc.packet_context_field_type = scft
+ trace = bt2.Trace()
+ trace.add_stream_class(self._sc)
+ cc = bt2.ClockClass('second_cc', 1000)
+ payloadft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ payloadft.append_field('zorg', ft)
+ ec = bt2.EventClass('ec', payload_field_type=payloadft)
+
+ with self.assertRaises(bt2.Error):
+ self._sc.add_event_class(ec)
+
+ def test_add_ec_after_add_sc_single_cc(self):
+ ehft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32)
+ ehft.append_field('id', ft)
+ self._sc.event_header_field_type = ehft
+ trace = bt2.Trace()
+ trace.add_stream_class(self._sc)
+ cc = bt2.ClockClass('first_cc', 1000)
+ payloadft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ payloadft.append_field('zorg', ft)
+ ec = bt2.EventClass('ec', payload_field_type=payloadft)
+ self._sc.add_event_class(ec)
+ cc = bt2.ClockClass('second_cc', 1000)
+ payloadft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ payloadft.append_field('lel', ft)
+ ec = bt2.EventClass('ec', payload_field_type=payloadft)
+
+ with self.assertRaises(bt2.Error):
+ self._sc.add_event_class(ec)
+
+ def test_add_ec_after_create_event(self):
+ ehft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32)
+ ehft.append_field('id', ft)
+ self._sc.event_header_field_type = ehft
+ cc = bt2.ClockClass('first_cc', 1000)
+ payloadft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ payloadft.append_field('zorg', ft)
+ ec1 = bt2.EventClass('ec', payload_field_type=payloadft)
+ self._sc.add_event_class(ec1)
+ ev = ec1()
+ cc = bt2.ClockClass('second_cc', 1000)
+ payloadft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ payloadft.append_field('logi', ft)
+ ec2 = bt2.EventClass('ec', payload_field_type=payloadft)
+
+ with self.assertRaises(bt2.Error):
+ self._sc.add_event_class(ec2)
+
+ def test_sc_clock_matches_expected_clock_class(self):
+ clock = bt2.CtfWriterClock('sc_clock')
+ self._sc.clock = clock
+ writer = bt2.CtfWriter('/tmp')
+ writer.add_clock(clock)
+ writer.trace.add_stream_class(self._sc)
+ cc = bt2.ClockClass('other_cc', 1000)
+ payloadft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ payloadft.append_field('zorg', ft)
+ ec = bt2.EventClass('ec', payload_field_type=payloadft)
+
+ with self.assertRaises(bt2.Error):
+ self._sc.add_event_class(ec)
--- /dev/null
+import unittest
+import bt2
+
+
+class TraceTestCase(unittest.TestCase):
+ def setUp(self):
+ self._trace = bt2.Trace()
+
+ def tearDown(self):
+ del self._trace
+
+ def _add_stream_class(self):
+ sc = bt2.StreamClass()
+ self._trace.add_stream_class(sc)
+
+ def test_packet_header_ft_no_clock_class_simple(self):
+ cc = bt2.ClockClass('hello', 1000)
+ phft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ phft.append_field('salut', ft)
+ self._trace.add_clock_class(cc)
+ self._trace.packet_header_field_type = phft
+
+ with self.assertRaises(bt2.Error):
+ self._add_stream_class()
+
+ def test_packet_header_ft_no_clock_class_struct(self):
+ cc = bt2.ClockClass('hello', 1000)
+ phft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ struct_ft = bt2.StructureFieldType()
+ struct_ft.append_field('salut', ft)
+ phft.append_field('boucane', struct_ft)
+ self._trace.add_clock_class(cc)
+ self._trace.packet_header_field_type = phft
+
+ with self.assertRaises(bt2.Error):
+ self._add_stream_class()
+
+ def test_packet_header_ft_no_clock_class_variant(self):
+ cc = bt2.ClockClass('hello', 1000)
+ phft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ tag_ft = bt2.EnumerationFieldType(size=32)
+ tag_ft.add_mapping('heille', 12)
+ variant_ft = bt2.VariantFieldType('tag', tag_ft)
+ variant_ft.append_field('heille', ft)
+ phft.append_field('tag', tag_ft)
+ phft.append_field('boucane', variant_ft)
+ self._trace.add_clock_class(cc)
+ self._trace.packet_header_field_type = phft
+
+ with self.assertRaises(bt2.Error):
+ self._add_stream_class()
+
+ def test_packet_header_ft_no_clock_class_array(self):
+ cc = bt2.ClockClass('hello', 1000)
+ phft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ array_ft = bt2.ArrayFieldType(ft, 23)
+ phft.append_field('boucane', array_ft)
+ self._trace.add_clock_class(cc)
+ self._trace.packet_header_field_type = phft
+
+ with self.assertRaises(bt2.Error):
+ self._add_stream_class()
+
+ def test_packet_header_ft_no_clock_class_sequence(self):
+ cc = bt2.ClockClass('hello', 1000)
+ phft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ len_ft = bt2.IntegerFieldType(32)
+ seq_ft = bt2.SequenceFieldType(ft, 'len')
+ phft.append_field('len', len_ft)
+ phft.append_field('boucane', seq_ft)
+ self._trace.add_clock_class(cc)
+ self._trace.packet_header_field_type = phft
+
+ with self.assertRaises(bt2.Error):
+ self._add_stream_class()
+
+ def test_packet_header_ft_no_clock_class_set_static(self):
+ cc = bt2.ClockClass('hello', 1000)
+ phft = bt2.StructureFieldType()
+ ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+ phft.append_field('salut', ft)
+ self._trace.add_clock_class(cc)
+ self._trace.packet_header_field_type = phft
+
+ with self.assertRaises(bt2.Error):
+ self._trace.set_is_static()
--- /dev/null
+#!/bin/bash
+#
+# Copyright (C) 2017 - Philippe Proulx <pproulx@efficios.com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; only version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+NO_SH_TAP=1
+. "@abs_top_builddir@/tests/utils/common.sh"
+
+PYTHON_BUILD_DIR="${BT_BUILD_PATH}/bindings/python/bt2/build/build_lib"
+TESTS_UTILS_PYTHON_DIR="${BT_SRC_PATH}/tests/utils/python"
+TESTRUNNER_PY="${BT_SRC_PATH}/tests/utils/python/testrunner.py"
+THIS_DIR="${BT_SRC_PATH}/tests/lib/trace-ir"
+
+if [ "x${MSYSTEM}" != "x" ]; then
+ export PATH="${BT_BUILD_PATH}/lib/.libs:${PATH}"
+else
+ export LD_LIBRARY_PATH="${BT_BUILD_PATH}/lib/.libs:${LD_LIBRARY_PATH}"
+fi
+
+PYTHONPATH="${PYTHON_BUILD_DIR}:${TESTS_UTILS_PYTHON_DIR}" \
+ "@PYTHON@" "${TESTRUNNER_PY}" "${THIS_DIR}"
+exit $?