X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Flib%2Ftrace-ir%2Ftrace.c;h=8cc005a785530654984cd837d5e2a7e7107212c4;hb=426de3806a9e0aae838d69bcc8e26762dd33c788;hp=72493a48589441a641955a7d2da9d0011f86ba1e;hpb=6871026b82224d83bb63cbb44cc33c16c766d96d;p=babeltrace.git diff --git a/src/lib/trace-ir/trace.c b/src/lib/trace-ir/trace.c index 72493a48..8cc005a7 100644 --- a/src/lib/trace-ir/trace.c +++ b/src/lib/trace-ir/trace.c @@ -1,38 +1,18 @@ /* + * SPDX-License-Identifier: MIT + * * Copyright 2017-2018 Philippe Proulx * Copyright 2014 Jérémie Galarneau - * - * 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 "LIB/TRACE" #include "lib/logging.h" -#include "lib/assert-pre.h" +#include "lib/assert-cond.h" #include -#include #include -#include "ctf-writer/functor.h" -#include "ctf-writer/clock.h" #include "compat/compiler.h" #include -#include #include "lib/value.h" #include #include "compat/endian.h" @@ -41,20 +21,14 @@ #include #include #include +#include #include #include "attributes.h" -#include "clock-class.h" -#include "event-class.h" -#include "event.h" -#include "field-class.h" -#include "field-wrapper.h" -#include "resolve-field-path.h" #include "stream-class.h" #include "stream.h" #include "trace-class.h" #include "trace.h" -#include "utils.h" #include "lib/value.h" #include "lib/func-status.h" @@ -63,8 +37,11 @@ struct bt_trace_destruction_listener_elem { void *data; }; -#define BT_ASSERT_PRE_DEV_TRACE_HOT(_trace) \ - BT_ASSERT_PRE_DEV_HOT((_trace), "Trace", ": %!+t", (_trace)) +#define BT_ASSERT_PRE_DEV_TRACE_HOT(_trace) \ + BT_ASSERT_PRE_DEV_HOT("trace", (_trace), "Trace", ": %!+t", (_trace)) + +#define DESTRUCTION_LISTENER_FUNC_NAME \ + "bt_trace_class_destruction_listener_func" static void destroy_trace(struct bt_object *obj) @@ -80,6 +57,8 @@ void destroy_trace(struct bt_object *obj) */ if (trace->destruction_listeners) { uint64_t i; + const struct bt_error *saved_error; + BT_LIB_LOGD("Calling trace destruction listener(s): %!+t", trace); /* @@ -94,24 +73,36 @@ void destroy_trace(struct bt_object *obj) */ trace->base.ref_count++; + saved_error = bt_current_thread_take_error(); + /* Call all the trace destruction listeners */ for (i = 0; i < trace->destruction_listeners->len; i++) { struct bt_trace_destruction_listener_elem elem = - g_array_index(trace->destruction_listeners, - struct bt_trace_destruction_listener_elem, i); + bt_g_array_index(trace->destruction_listeners, + struct bt_trace_destruction_listener_elem, i); if (elem.func) { elem.func(trace, elem.data); + BT_ASSERT_POST_NO_ERROR( + DESTRUCTION_LISTENER_FUNC_NAME); } /* * The destruction listener should not have kept a * reference to the trace. */ - BT_ASSERT_PRE(trace->base.ref_count == 1, "Destruction listener kept a reference to the trace being destroyed: %![trace-]+t", trace); + BT_ASSERT_POST(DESTRUCTION_LISTENER_FUNC_NAME, + "trace-reference-count-not-changed", + trace->base.ref_count == 1, + "Destruction listener kept a reference to the trace being destroyed: %![trace-]+t", + trace); } g_array_free(trace->destruction_listeners, TRUE); trace->destruction_listeners = NULL; + + if (saved_error) { + BT_CURRENT_THREAD_MOVE_ERROR_AND_RESET(saved_error); + } } if (trace->name.str) { @@ -143,10 +134,13 @@ void destroy_trace(struct bt_object *obj) g_free(trace); } +BT_EXPORT struct bt_trace *bt_trace_create(struct bt_trace_class *tc) { struct bt_trace *trace = NULL; + BT_ASSERT_PRE_NO_ERROR(); + BT_LIB_LOGD("Creating trace object: %![tc-]+T", tc); trace = g_new0(struct bt_trace, 1); if (!trace) { @@ -207,17 +201,20 @@ end: return trace; } +BT_EXPORT const char *bt_trace_get_name(const struct bt_trace *trace) { - BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace"); + BT_ASSERT_PRE_DEV_TRACE_NON_NULL(trace); return trace->name.value; } +BT_EXPORT enum bt_trace_set_name_status 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_NO_ERROR(); + BT_ASSERT_PRE_TRACE_NON_NULL(trace); + BT_ASSERT_PRE_NAME_NON_NULL(name); BT_ASSERT_PRE_DEV_TRACE_HOT(trace); g_string_assign(trace->name.str, name); trace->name.value = trace->name.str->str; @@ -225,23 +222,24 @@ enum bt_trace_set_name_status bt_trace_set_name(struct bt_trace *trace, return BT_FUNC_STATUS_OK; } +BT_EXPORT bt_uuid bt_trace_get_uuid(const struct bt_trace *trace) { - BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace"); + BT_ASSERT_PRE_DEV_TRACE_NON_NULL(trace); return trace->uuid.value; } +BT_EXPORT void 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_NON_NULL(trace); + BT_ASSERT_PRE_UUID_NON_NULL(uuid); BT_ASSERT_PRE_DEV_TRACE_HOT(trace); bt_uuid_copy(trace->uuid.uuid, uuid); trace->uuid.value = trace->uuid.uuid; BT_LIB_LOGD("Set trace's UUID: %!+t", trace); } -BT_ASSERT_FUNC static bool trace_has_environment_entry(const struct bt_trace *trace, const char *name) { @@ -261,8 +259,9 @@ enum bt_trace_set_environment_entry_status set_environment_entry( BT_ASSERT(trace); BT_ASSERT(name); BT_ASSERT(value); - BT_ASSERT_PRE(!trace->frozen || - !trace_has_environment_entry(trace, name), + BT_ASSERT_PRE("not-frozen:trace", + !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, @@ -281,15 +280,19 @@ enum bt_trace_set_environment_entry_status set_environment_entry( return ret; } +BT_EXPORT enum bt_trace_set_environment_entry_status 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"); + + BT_ASSERT_PRE_NO_ERROR(); + BT_ASSERT_PRE_TRACE_NON_NULL(trace); + BT_ASSERT_PRE_NAME_NON_NULL(name); + BT_ASSERT_PRE_NON_NULL("value", value, "Value"); + value_obj = bt_value_string_create_init(value); if (!value_obj) { BT_LIB_LOGE_APPEND_CAUSE( @@ -306,14 +309,18 @@ end: return ret; } +BT_EXPORT enum bt_trace_set_environment_entry_status 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"); + + BT_ASSERT_PRE_NO_ERROR(); + BT_ASSERT_PRE_TRACE_NON_NULL(trace); + BT_ASSERT_PRE_NAME_NON_NULL(name); + value_obj = bt_value_integer_signed_create_init(value); if (!value_obj) { BT_LIB_LOGE_APPEND_CAUSE( @@ -330,23 +337,22 @@ end: return ret; } +BT_EXPORT uint64_t bt_trace_get_environment_entry_count(const struct bt_trace *trace) { - int64_t ret; - - BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace"); - ret = bt_attributes_get_count(trace->environment); - BT_ASSERT(ret >= 0); - return (uint64_t) ret; + BT_ASSERT_PRE_DEV_TRACE_NON_NULL(trace); + return bt_attributes_get_count(trace->environment); } +BT_EXPORT void bt_trace_borrow_environment_entry_by_index_const( const struct bt_trace *trace, uint64_t index, const char **name, const struct bt_value **value) { - BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace"); - BT_ASSERT_PRE_DEV_NON_NULL(name, "Name"); - BT_ASSERT_PRE_DEV_NON_NULL(value, "Value"); + BT_ASSERT_PRE_DEV_TRACE_NON_NULL(trace); + BT_ASSERT_PRE_DEV_NAME_NON_NULL(name); + BT_ASSERT_PRE_DEV_NON_NULL("value-object-output", value, + "Value object (output)"); BT_ASSERT_PRE_DEV_VALID_INDEX(index, bt_attributes_get_count(trace->environment)); *value = bt_attributes_borrow_field_value(trace->environment, index); @@ -355,42 +361,47 @@ void bt_trace_borrow_environment_entry_by_index_const( BT_ASSERT(*name); } +BT_EXPORT const struct bt_value *bt_trace_borrow_environment_entry_value_by_name_const( const struct bt_trace *trace, const char *name) { - BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace"); - BT_ASSERT_PRE_DEV_NON_NULL(name, "Name"); + BT_ASSERT_PRE_DEV_TRACE_NON_NULL(trace); + BT_ASSERT_PRE_DEV_NAME_NON_NULL(name); return bt_attributes_borrow_field_value_by_name(trace->environment, name); } +BT_EXPORT uint64_t bt_trace_get_stream_count(const struct bt_trace *trace) { - BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace"); + BT_ASSERT_PRE_DEV_TRACE_NON_NULL(trace); return (uint64_t) trace->streams->len; } +BT_EXPORT struct bt_stream *bt_trace_borrow_stream_by_index( struct bt_trace *trace, uint64_t index) { - BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace"); + BT_ASSERT_PRE_DEV_TRACE_NON_NULL(trace); BT_ASSERT_PRE_DEV_VALID_INDEX(index, trace->streams->len); return g_ptr_array_index(trace->streams, index); } +BT_EXPORT const struct bt_stream *bt_trace_borrow_stream_by_index_const( const struct bt_trace *trace, uint64_t index) { return bt_trace_borrow_stream_by_index((void *) trace, index); } +BT_EXPORT 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_DEV_NON_NULL(trace, "Trace"); + BT_ASSERT_PRE_DEV_TRACE_NON_NULL(trace); for (i = 0; i < trace->streams->len; i++) { struct bt_stream *stream_candidate = @@ -406,12 +417,14 @@ end: return stream; } +BT_EXPORT const struct bt_stream *bt_trace_borrow_stream_by_id_const( const struct bt_trace *trace, uint64_t id) { return bt_trace_borrow_stream_by_id((void *) trace, id); } +BT_EXPORT enum bt_trace_add_listener_status bt_trace_add_destruction_listener( const struct bt_trace *c_trace, bt_trace_destruction_listener_func listener, @@ -424,13 +437,14 @@ enum bt_trace_add_listener_status bt_trace_add_destruction_listener( .data = data, }; - BT_ASSERT_PRE_NON_NULL(trace, "Trace"); - BT_ASSERT_PRE_NON_NULL(listener, "Listener"); + BT_ASSERT_PRE_NO_ERROR(); + BT_ASSERT_PRE_TRACE_NON_NULL(trace); + BT_ASSERT_PRE_LISTENER_FUNC_NON_NULL(listener); /* Find the next available spot */ for (i = 0; i < trace->destruction_listeners->len; i++) { struct bt_trace_destruction_listener_elem elem = - g_array_index(trace->destruction_listeners, + bt_g_array_index(trace->destruction_listeners, struct bt_trace_destruction_listener_elem, i); if (!elem.func) { @@ -457,22 +471,25 @@ static bool has_listener_id(const struct bt_trace *trace, uint64_t listener_id) { BT_ASSERT(listener_id < trace->destruction_listeners->len); - return (&g_array_index(trace->destruction_listeners, + return (&bt_g_array_index(trace->destruction_listeners, struct bt_trace_destruction_listener_elem, listener_id))->func; } +BT_EXPORT enum bt_trace_remove_listener_status bt_trace_remove_destruction_listener( const struct bt_trace *c_trace, bt_listener_id listener_id) { struct bt_trace *trace = (void *) c_trace; struct bt_trace_destruction_listener_elem *elem; - BT_ASSERT_PRE_NON_NULL(trace, "Trace"); - BT_ASSERT_PRE(has_listener_id(trace, listener_id), + BT_ASSERT_PRE_NO_ERROR(); + BT_ASSERT_PRE_TRACE_NON_NULL(trace); + BT_ASSERT_PRE("listener-id-exists", + has_listener_id(trace, listener_id), "Trace has no such trace destruction listener ID: " "%![trace-]+t, %" PRIu64, trace, listener_id); - elem = &g_array_index(trace->destruction_listeners, + elem = &bt_g_array_index(trace->destruction_listeners, struct bt_trace_destruction_listener_elem, listener_id); BT_ASSERT(elem->func); @@ -485,7 +502,6 @@ enum bt_trace_remove_listener_status bt_trace_remove_destruction_listener( return BT_FUNC_STATUS_OK; } -BT_HIDDEN void _bt_trace_freeze(const struct bt_trace *trace) { BT_ASSERT(trace); @@ -498,7 +514,6 @@ void _bt_trace_freeze(const struct bt_trace *trace) ((struct bt_trace *) trace)->frozen = true; } -BT_HIDDEN void bt_trace_add_stream(struct bt_trace *trace, struct bt_stream *stream) { guint count = 0; @@ -517,7 +532,6 @@ void bt_trace_add_stream(struct bt_trace *trace, struct bt_stream *stream) stream->class, GUINT_TO_POINTER(count + 1)); } -BT_HIDDEN uint64_t bt_trace_get_automatic_stream_id(const struct bt_trace *trace, const struct bt_stream_class *stream_class) { @@ -535,49 +549,55 @@ uint64_t bt_trace_get_automatic_stream_id(const struct bt_trace *trace, return id; } +BT_EXPORT struct bt_trace_class *bt_trace_borrow_class(struct bt_trace *trace) { - BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace"); + BT_ASSERT_PRE_DEV_TRACE_NON_NULL(trace); return trace->class; } +BT_EXPORT const struct bt_trace_class *bt_trace_borrow_class_const( const struct bt_trace *trace) { return bt_trace_borrow_class((void *) trace); } +BT_EXPORT const struct bt_value *bt_trace_borrow_user_attributes_const( const struct bt_trace *trace) { - BT_ASSERT_PRE_DEV_NON_NULL(trace, "Trace"); + BT_ASSERT_PRE_DEV_TRACE_NON_NULL(trace); return trace->user_attributes; } +BT_EXPORT struct bt_value *bt_trace_borrow_user_attributes(struct bt_trace *trace) { return (void *) bt_trace_borrow_user_attributes_const((void *) trace); } +BT_EXPORT void bt_trace_set_user_attributes( struct bt_trace *trace, const struct bt_value *user_attributes) { - BT_ASSERT_PRE_NON_NULL(trace, "Trace"); - BT_ASSERT_PRE_NON_NULL(user_attributes, "User attributes"); - BT_ASSERT_PRE(user_attributes->type == BT_VALUE_TYPE_MAP, - "User attributes object is not a map value object."); + BT_ASSERT_PRE_TRACE_NON_NULL(trace); + BT_ASSERT_PRE_USER_ATTRS_NON_NULL(user_attributes); + BT_ASSERT_PRE_USER_ATTRS_IS_MAP(user_attributes); BT_ASSERT_PRE_DEV_TRACE_HOT(trace); bt_object_put_ref_no_null_check(trace->user_attributes); trace->user_attributes = (void *) user_attributes; bt_object_get_ref_no_null_check(trace->user_attributes); } +BT_EXPORT void bt_trace_get_ref(const struct bt_trace *trace) { bt_object_get_ref(trace); } +BT_EXPORT void bt_trace_put_ref(const struct bt_trace *trace) { bt_object_put_ref(trace);