From: Mathieu Desnoyers Date: Mon, 5 Apr 2021 12:32:11 +0000 (-0400) Subject: Refactoring: add back constness of public API structures X-Git-Tag: v2.13.0-rc1~156 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=4e48b5d;p=lttng-ust.git Refactoring: add back constness of public API structures Probes defining type, enumeration label, enumeration description, event, and probe structures should be able to define them as "const", because those are indeed const data which never need to be changed by the tracer. In order to allow struct lttng_ust_probe_desc definition to be constant, move the "head", "lazy_init_head" and "lazy" fields to an internal structure, "struct lttng_ust_registered_probe". It is opaque from the point of view of the probe provider, but its pointer is now used as a cookie between registration and unregistration. Moving the list heads into an internal structure is an overall cleanup hiding private data from the public API. Use a similar scheme for registration of the context provider: internalize the "hlist" field into an internal registration structure (opaque from the point of view of the public API), which is now used as a cookie between registration and unregistration. This allows to fix an issue which was introduced by a prior refactoring of the code dealing with contexts: the RCU update of context callbacks was broken because the context fields were shared between the old and the new array of contexts, thus leading to non-atomic update of the 3 callback pointers. This is fixed by making struct lttng_ust_ctx private, and changing the array of pointers to context fields to an array of context fields. The functions lttng_ust_context_set_session_provider, lttng_ust_add_app_context_to_ctx_rcu, and lttng_ust_context_set_provider_rcu are now private. For all contexts except the "perf" context fields, define the context field as a static const variable rather than use memory allocation. This means freeing the event field and type is not required anymore, and the perf context field is handled through a destroy callback using the private data pointer. Move struct lttng_ust_ctx_field to an internal header. The only reason why it was public is because the callbacks expected it as an argument. Change the callbacks to receive a private data pointer instead to achieve the same goal without exposing our internal structures. The internal helpers lttng_ust_create_type_integer, lttng_ust_create_type_array_text and lttng_ust_destroy_type are removed, and replaced by internal macro helpers lttng_ust_static_type_integer, lttng_ust_static_type_array_text, lttng_ust_static_event_field, and lttng_ust_static_ctx_field, to facilitate static definitions in context code. Because there is no need to embed list and hlist nodes in the probe descriptor nor the context provider, there is no need to include those list headers from public APIs anymore. Signed-off-by: Mathieu Desnoyers Change-Id: I556e00d1d99a956b6f981dd2f5eae53589303f9d --- diff --git a/include/lttng/ust-events.h b/include/lttng/ust-events.h index 108e7752..ceb9cb37 100644 --- a/include/lttng/ust-events.h +++ b/include/lttng/ust-events.h @@ -9,8 +9,6 @@ #ifndef _LTTNG_UST_EVENTS_H #define _LTTNG_UST_EVENTS_H -#include -#include #include #include #include @@ -41,6 +39,7 @@ struct lttng_ust_channel_buffer; struct lttng_ust_session; struct lttng_ust_lib_ring_buffer_ctx; struct lttng_ust_event_field; +struct lttng_ust_registered_probe; /* * Data structures used by tracepoint event declarations, and by the @@ -171,14 +170,14 @@ struct lttng_ust_type_string { struct lttng_ust_type_enum { struct lttng_ust_type_common parent; uint32_t struct_size; - struct lttng_ust_enum_desc *desc; /* Enumeration mapping */ - struct lttng_ust_type_common *container_type; + const struct lttng_ust_enum_desc *desc; /* Enumeration mapping */ + const struct lttng_ust_type_common *container_type; }; struct lttng_ust_type_array { struct lttng_ust_type_common parent; uint32_t struct_size; - struct lttng_ust_type_common *elem_type; + const struct lttng_ust_type_common *elem_type; unsigned int length; /* Num. elems. */ unsigned int alignment; enum lttng_ust_string_encoding encoding; @@ -188,7 +187,7 @@ struct lttng_ust_type_sequence { struct lttng_ust_type_common parent; uint32_t struct_size; const char *length_name; /* Length field name. */ - struct lttng_ust_type_common *elem_type; + const struct lttng_ust_type_common *elem_type; unsigned int alignment; /* Alignment before elements. */ enum lttng_ust_string_encoding encoding; }; @@ -197,7 +196,7 @@ struct lttng_ust_type_struct { struct lttng_ust_type_common parent; uint32_t struct_size; unsigned int nr_fields; - struct lttng_ust_event_field **fields; /* Array of pointers to fields. */ + const struct lttng_ust_event_field **fields; /* Array of pointers to fields. */ unsigned int alignment; }; @@ -217,7 +216,7 @@ struct lttng_ust_enum_desc { uint32_t struct_size; const char *name; - struct lttng_ust_enum_entry **entries; + const struct lttng_ust_enum_entry **entries; unsigned int nr_entries; /* End of base ABI. Fields below should be used after checking struct_size. */ @@ -239,7 +238,7 @@ struct lttng_ust_event_field { uint32_t struct_size; const char *name; - struct lttng_ust_type_common *type; + const struct lttng_ust_type_common *type; unsigned int nowrite:1, /* do not write into trace */ nofilter:1; /* do not consider for filter */ @@ -257,16 +256,15 @@ struct lttng_ust_event_field { * at the end of the structure. */ struct lttng_ust_event_desc { - uint32_t struct_size; /* Size of this structure. */ + uint32_t struct_size; /* Size of this structure. */ const char *event_name; - struct lttng_ust_probe_desc *probe_desc; + const struct lttng_ust_probe_desc *probe_desc; void (*probe_callback)(void); - struct lttng_event_ctx *ctx; /* context */ - struct lttng_ust_event_field **fields; /* event payload */ + const struct lttng_ust_event_field **fields; /* event payload */ unsigned int nr_fields; const int **loglevel; - const char *signature; /* Argument types/names received */ + const char *signature; /* Argument types/names received */ const char **model_emf_uri; /* End of base ABI. Fields below should be used after checking struct_size. */ @@ -285,11 +283,8 @@ struct lttng_ust_probe_desc { uint32_t struct_size; /* Size of this structure. */ const char *provider_name; - struct lttng_ust_event_desc **event_desc; + const struct lttng_ust_event_desc **event_desc; unsigned int nr_events; - struct cds_list_head head; /* chain registered probes */ - struct cds_list_head lazy_init_head; - int lazy; /* lazy registration */ uint32_t major; uint32_t minor; @@ -307,7 +302,6 @@ struct lttng_ust_probe_desc { * removed. */ -struct lttng_ust_ctx; struct lttng_ust_event_common_private; enum lttng_ust_event_type { @@ -546,8 +540,15 @@ struct lttng_ust_session { /* End of base ABI. Fields below should be used after checking struct_size. */ }; -int lttng_ust_probe_register(struct lttng_ust_probe_desc *desc); -void lttng_ust_probe_unregister(struct lttng_ust_probe_desc *desc); +/* + * On successful registration of a probe, a pointer to an opaque + * structure is returned. This pointer should be passed to + * lttng_ust_probe_unregister for unregistration. + * lttng_ust_probe_register returns NULL on error. + */ +struct lttng_ust_registered_probe *lttng_ust_probe_register(const struct lttng_ust_probe_desc *desc); + +void lttng_ust_probe_unregister(struct lttng_ust_registered_probe *reg_probe); /* * Applications that change their procname and need the new value to be diff --git a/include/lttng/ust-tracepoint-event.h b/include/lttng/ust-tracepoint-event.h index fe96bf24..3408cb92 100644 --- a/include/lttng/ust-tracepoint-event.h +++ b/include/lttng/ust-tracepoint-event.h @@ -150,7 +150,7 @@ void __event_template_proto___##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args) /* Enumeration entry (single value) */ #undef ctf_enum_value #define ctf_enum_value(_string, _value) \ - __LTTNG_COMPOUND_LITERAL(struct lttng_ust_enum_entry, { \ + __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_enum_entry, { \ .struct_size = sizeof(struct lttng_ust_enum_entry), \ .start = { \ .value = lttng_ust_is_signed_type(__typeof__(_value)) ? \ @@ -168,7 +168,7 @@ void __event_template_proto___##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args) /* Enumeration entry (range) */ #undef ctf_enum_range #define ctf_enum_range(_string, _range_start, _range_end) \ - __LTTNG_COMPOUND_LITERAL(struct lttng_ust_enum_entry, { \ + __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_enum_entry, { \ .struct_size = sizeof(struct lttng_ust_enum_entry), \ .start = { \ .value = lttng_ust_is_signed_type(__typeof__(_range_start)) ? \ @@ -186,7 +186,7 @@ void __event_template_proto___##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args) /* Enumeration entry (automatic value; follows the rules of CTF) */ #undef ctf_enum_auto #define ctf_enum_auto(_string) \ - __LTTNG_COMPOUND_LITERAL(struct lttng_ust_enum_entry, { \ + __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_enum_entry, { \ .struct_size = sizeof(struct lttng_ust_enum_entry), \ .start = { \ .value = -1ULL, \ @@ -206,7 +206,7 @@ void __event_template_proto___##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args) #undef TRACEPOINT_ENUM #define TRACEPOINT_ENUM(_provider, _name, _values) \ - struct lttng_ust_enum_entry *__enum_values__##_provider##_##_name[] = { \ + const struct lttng_ust_enum_entry *__enum_values__##_provider##_##_name[] = { \ _values \ ctf_enum_value("", 0) /* Dummy, 0-len array forbidden by C99. */ \ }; @@ -257,7 +257,7 @@ void __event_template_proto___##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args) #undef _ctf_integer_ext #define _ctf_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \ - __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { \ + __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { \ .struct_size = sizeof(struct lttng_ust_event_field), \ .name = #_item, \ .type = lttng_ust_type_integer_define(_type, _byte_order, _base), \ @@ -267,7 +267,7 @@ void __event_template_proto___##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args) #undef _ctf_float #define _ctf_float(_type, _item, _src, _nowrite) \ - __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { \ + __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { \ .struct_size = sizeof(struct lttng_ust_event_field), \ .name = #_item, \ .type = lttng_ust_type_float_define(_type), \ @@ -279,10 +279,10 @@ void __event_template_proto___##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args) #define _ctf_array_encoded(_type, _item, _src, _byte_order, \ _length, _encoding, _nowrite, \ _elem_type_base) \ - __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { \ + __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { \ .struct_size = sizeof(struct lttng_ust_event_field), \ .name = #_item, \ - .type = (struct lttng_ust_type_common *) __LTTNG_COMPOUND_LITERAL(struct lttng_ust_type_array, { \ + .type = (const struct lttng_ust_type_common *) __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_type_array, { \ .parent = { \ .type = lttng_ust_type_array, \ }, \ @@ -300,17 +300,17 @@ void __event_template_proto___##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args) #define _ctf_sequence_encoded(_type, _item, _src, _byte_order, \ _length_type, _src_length, _encoding, _nowrite, \ _elem_type_base) \ - __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { \ + __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { \ .struct_size = sizeof(struct lttng_ust_event_field), \ .name = "_" #_item "_length", \ .type = lttng_ust_type_integer_define(_length_type, BYTE_ORDER, 10), \ .nowrite = _nowrite, \ .nofilter = 1, \ }), \ - __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { \ + __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { \ .struct_size = sizeof(struct lttng_ust_event_field), \ .name = #_item, \ - .type = (struct lttng_ust_type_common *) __LTTNG_COMPOUND_LITERAL(struct lttng_ust_type_sequence, { \ + .type = (const struct lttng_ust_type_common *) __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_type_sequence, { \ .parent = { \ .type = lttng_ust_type_sequence, \ }, \ @@ -326,10 +326,10 @@ void __event_template_proto___##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args) #undef _ctf_string #define _ctf_string(_item, _src, _nowrite) \ - __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { \ + __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { \ .struct_size = sizeof(struct lttng_ust_event_field), \ .name = #_item, \ - .type = (struct lttng_ust_type_common *) __LTTNG_COMPOUND_LITERAL(struct lttng_ust_type_string, { \ + .type = (const struct lttng_ust_type_common *) __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_type_string, { \ .parent = { \ .type = lttng_ust_type_string, \ }, \ @@ -345,10 +345,10 @@ void __event_template_proto___##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args) #undef _ctf_enum #define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \ - __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { \ + __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { \ .struct_size = sizeof(struct lttng_ust_event_field), \ .name = #_item, \ - .type = (struct lttng_ust_type_common *) __LTTNG_COMPOUND_LITERAL(struct lttng_ust_type_enum, { \ + .type = (const struct lttng_ust_type_common *) __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_type_enum, { \ .parent = { \ .type = lttng_ust_type_enum, \ }, \ @@ -365,14 +365,14 @@ void __event_template_proto___##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args) #undef _TRACEPOINT_EVENT_CLASS #define _TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \ - static struct lttng_ust_event_field *__event_fields___##_provider##___##_name[] = { \ + static const struct lttng_ust_event_field *__event_fields___##_provider##___##_name[] = { \ _fields \ ctf_integer(int, dummy, 0) /* Dummy, C99 forbids 0-len array. */ \ }; #undef TRACEPOINT_ENUM #define TRACEPOINT_ENUM(_provider, _name, _values) \ - static struct lttng_ust_enum_desc __enum_##_provider##_##_name = { \ + static const struct lttng_ust_enum_desc __enum_##_provider##_##_name = { \ .struct_size = sizeof(struct lttng_ust_enum_desc), \ .name = #_provider "_" #_name, \ .entries = __enum_values__##_provider##_##_name, \ @@ -1025,7 +1025,7 @@ LTTNG_TP_EXTERN_C const char *_model_emf_uri___##__provider##___##__name \ * symbol table. */ -extern struct lttng_ust_probe_desc _TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER) +extern const struct lttng_ust_probe_desc _TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER) __attribute__((visibility("hidden"))); /* @@ -1047,12 +1047,11 @@ static const int * \ static const char * \ __ref_model_emf_uri___##_provider##___##_name \ __attribute__((weakref ("_model_emf_uri___" #_provider "___" #_name)));\ -static struct lttng_ust_event_desc __event_desc___##_provider##_##_name = { \ +static const struct lttng_ust_event_desc __event_desc___##_provider##_##_name = { \ .struct_size = sizeof(struct lttng_ust_event_desc), \ .event_name = #_name, \ .probe_desc = &__probe_desc___##_provider, \ .probe_callback = (void (*)(void)) &__event_probe__##_provider##___##_template, \ - .ctx = NULL, \ .fields = __event_fields___##_provider##___##_template, \ .nr_fields = _TP_ARRAY_SIZE(__event_fields___##_provider##___##_template) - 1, \ .loglevel = &__ref_loglevel___##_provider##___##_name, \ @@ -1075,7 +1074,7 @@ static struct lttng_ust_event_desc __event_desc___##_provider##_##_name = { \ #define _TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \ &__event_desc___##_provider##_##_name, -static struct lttng_ust_event_desc *_TP_COMBINE_TOKENS(__event_desc___, TRACEPOINT_PROVIDER)[] = { +static const struct lttng_ust_event_desc *_TP_COMBINE_TOKENS(__event_desc___, TRACEPOINT_PROVIDER)[] = { #include TRACEPOINT_INCLUDE NULL, /* Dummy, C99 forbids 0-len array. */ }; @@ -1087,19 +1086,17 @@ static struct lttng_ust_event_desc *_TP_COMBINE_TOKENS(__event_desc___, TRACEPOI * Create a toplevel descriptor for the whole probe. */ -struct lttng_ust_probe_desc _TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER) = { +const struct lttng_ust_probe_desc _TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER) = { .struct_size = sizeof(struct lttng_ust_probe_desc), .provider_name = __tp_stringify(TRACEPOINT_PROVIDER), .event_desc = _TP_COMBINE_TOKENS(__event_desc___, TRACEPOINT_PROVIDER), .nr_events = _TP_ARRAY_SIZE(_TP_COMBINE_TOKENS(__event_desc___, TRACEPOINT_PROVIDER)) - 1, - .head = { NULL, NULL }, - .lazy_init_head = { NULL, NULL }, - .lazy = 0, .major = LTTNG_UST_PROVIDER_MAJOR, .minor = LTTNG_UST_PROVIDER_MINOR, }; static int _TP_COMBINE_TOKENS(__probe_register_refcount___, TRACEPOINT_PROVIDER); +static struct lttng_ust_registered_probe *_TP_COMBINE_TOKENS(__lttng_ust_probe_register_cookie___, TRACEPOINT_PROVIDER); /* * Stage 9 of tracepoint event generation. @@ -1120,7 +1117,7 @@ _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void) static void _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void) { - int ret; + struct lttng_ust_registered_probe *reg_probe; if (_TP_COMBINE_TOKENS(__probe_register_refcount___, TRACEPOINT_PROVIDER)++) { @@ -1135,11 +1132,13 @@ _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void) * error will appear. */ _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)(); - ret = lttng_ust_probe_register(&_TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER)); - if (ret) { - fprintf(stderr, "LTTng-UST: Error (%d) while registering tracepoint probe.\n", ret); + assert(!_TP_COMBINE_TOKENS(__lttng_ust_probe_register_cookie___, TRACEPOINT_PROVIDER)); + reg_probe = lttng_ust_probe_register(&_TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER)); + if (!reg_probe) { + fprintf(stderr, "LTTng-UST: Error while registering tracepoint probe.\n"); abort(); } + _TP_COMBINE_TOKENS(__lttng_ust_probe_register_cookie___, TRACEPOINT_PROVIDER) = reg_probe; } static void @@ -1152,7 +1151,8 @@ _TP_COMBINE_TOKENS(__lttng_events_exit__, TRACEPOINT_PROVIDER)(void) TRACEPOINT_PROVIDER)) { return; } - lttng_ust_probe_unregister(&_TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER)); + lttng_ust_probe_unregister(_TP_COMBINE_TOKENS(__lttng_ust_probe_register_cookie___, TRACEPOINT_PROVIDER)); + _TP_COMBINE_TOKENS(__lttng_ust_probe_register_cookie___, TRACEPOINT_PROVIDER) = NULL; } int _TP_COMBINE_TOKENS(__tracepoint_provider_, TRACEPOINT_PROVIDER) diff --git a/include/ust-comm.h b/include/ust-comm.h index 63647a3e..775b6bef 100644 --- a/include/ust-comm.h +++ b/include/ust-comm.h @@ -287,7 +287,7 @@ int ustcomm_register_event(int sock, int loglevel, const char *signature, /* event signature (input) */ size_t nr_fields, /* fields */ - struct lttng_ust_event_field **fields, + const struct lttng_ust_event_field **fields, const char *model_emf_uri, uint32_t *id) /* event id (output) */ __attribute__((visibility("hidden"))); @@ -300,7 +300,7 @@ int ustcomm_register_enum(int sock, int session_objd, /* session descriptor */ const char *enum_name, /* enum name (input) */ size_t nr_entries, /* entries */ - struct lttng_ust_enum_entry **entries, + const struct lttng_ust_enum_entry **entries, uint64_t *id) /* enum id (output) */ __attribute__((visibility("hidden"))); @@ -313,7 +313,7 @@ int ustcomm_register_channel(int sock, int session_objd, /* session descriptor */ int channel_objd, /* channel descriptor */ size_t nr_ctx_fields, - struct lttng_ust_ctx_field **ctx_fields, + struct lttng_ust_ctx_field *ctx_fields, uint32_t *chan_id, /* channel id (output) */ int *header_type) /* header type (output) */ __attribute__((visibility("hidden"))); diff --git a/include/ust-context-provider.h b/include/ust-context-provider.h index 094e9fd9..85beac90 100644 --- a/include/ust-context-provider.h +++ b/include/ust-context-provider.h @@ -13,10 +13,11 @@ #include #include -#include #include "ust-dynamic-type.h" +struct lttng_ust_registered_context_provider; + /* * Context value * @@ -37,57 +38,6 @@ struct lttng_ust_ctx_value { } u; }; -/* - * Context field - * - * IMPORTANT: this structure is part of the ABI between the probe and - * UST. Fields need to be only added at the end, never reordered, never - * removed. - * - * The field @struct_size should be used to determine the size of the - * structure. It should be queried before using additional fields added - * at the end of the structure. - */ - -struct lttng_ust_ctx_field { - uint32_t struct_size; - void *priv; - - struct lttng_ust_event_field *event_field; - size_t (*get_size)(struct lttng_ust_ctx_field *field, size_t offset); - void (*record)(struct lttng_ust_ctx_field *field, - struct lttng_ust_lib_ring_buffer_ctx *ctx, - struct lttng_ust_channel_buffer *chan); - void (*get_value)(struct lttng_ust_ctx_field *field, - struct lttng_ust_ctx_value *value); - void (*destroy)(struct lttng_ust_ctx_field *field); - - /* End of base ABI. Fields below should be used after checking struct_size. */ -}; - -/* - * All context fields for a given event/channel - * - * IMPORTANT: this structure is part of the ABI between the probe and - * UST. Fields need to be only added at the end, never reordered, never - * removed. - * - * The field @struct_size should be used to determine the size of the - * structure. It should be queried before using additional fields added - * at the end of the structure. - */ - -struct lttng_ust_ctx { - uint32_t struct_size; - - struct lttng_ust_ctx_field **fields; - unsigned int nr_fields; - unsigned int allocated_fields; - unsigned int largest_align; - - /* End of base ABI. Fields below should be used after checking struct_size. */ -}; - /* * Context provider * @@ -103,37 +53,23 @@ struct lttng_ust_ctx { struct lttng_ust_context_provider { uint32_t struct_size; - char *name; - size_t (*get_size)(struct lttng_ust_ctx_field *field, size_t offset); - void (*record)(struct lttng_ust_ctx_field *field, - struct lttng_ust_lib_ring_buffer_ctx *ctx, + const char *name; + size_t (*get_size)(void *priv, size_t offset); + void (*record)(void *priv, struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan); - void (*get_value)(struct lttng_ust_ctx_field *field, - struct lttng_ust_ctx_value *value); - struct cds_hlist_node node; + void (*get_value)(void *priv, struct lttng_ust_ctx_value *value); + void *priv; /* End of base ABI. Fields below should be used after checking struct_size. */ }; -int lttng_ust_context_provider_register(struct lttng_ust_context_provider *provider); -void lttng_ust_context_provider_unregister(struct lttng_ust_context_provider *provider); - -void lttng_ust_context_set_session_provider(const char *name, - size_t (*get_size)(struct lttng_ust_ctx_field *field, size_t offset), - void (*record)(struct lttng_ust_ctx_field *field, - struct lttng_ust_lib_ring_buffer_ctx *ctx, - struct lttng_ust_channel_buffer *chan), - void (*get_value)(struct lttng_ust_ctx_field *field, - struct lttng_ust_ctx_value *value)); +/* + * Returns an opaque pointer on success, which must be passed to + * lttng_ust_context_provider_unregister for unregistration. Returns + * NULL on error. + */ +struct lttng_ust_registered_context_provider *lttng_ust_context_provider_register(struct lttng_ust_context_provider *provider); -int lttng_ust_add_app_context_to_ctx_rcu(const char *name, struct lttng_ust_ctx **ctx); -int lttng_ust_context_set_provider_rcu(struct lttng_ust_ctx **_ctx, - const char *name, - size_t (*get_size)(struct lttng_ust_ctx_field *field, size_t offset), - void (*record)(struct lttng_ust_ctx_field *field, - struct lttng_ust_lib_ring_buffer_ctx *ctx, - struct lttng_ust_channel_buffer *chan), - void (*get_value)(struct lttng_ust_ctx_field *field, - struct lttng_ust_ctx_value *value)); +void lttng_ust_context_provider_unregister(struct lttng_ust_registered_context_provider *reg_provider); #endif /* _LTTNG_UST_CONTEXT_PROVIDER_H */ diff --git a/include/ust-dynamic-type.h b/include/ust-dynamic-type.h index 41c37788..e63fc4c4 100644 --- a/include/ust-dynamic-type.h +++ b/include/ust-dynamic-type.h @@ -26,13 +26,13 @@ enum lttng_ust_dynamic_type { }; int lttng_ust_dynamic_type_choices(size_t *nr_choices, - struct lttng_ust_event_field ***choices) + const struct lttng_ust_event_field ***choices) __attribute__((visibility("hidden"))); -struct lttng_ust_event_field *lttng_ust_dynamic_type_field(int64_t value) +const struct lttng_ust_event_field *lttng_ust_dynamic_type_field(int64_t value) __attribute__((visibility("hidden"))); -struct lttng_ust_event_field *lttng_ust_dynamic_type_tag_field(void) +const struct lttng_ust_event_field *lttng_ust_dynamic_type_tag_field(void) __attribute__((visibility("hidden"))); #endif /* _LTTNG_UST_DYNAMIC_TYPE_H */ diff --git a/liblttng-ust-comm/lttng-ust-comm.c b/liblttng-ust-comm/lttng-ust-comm.c index 998e5569..d5d193d7 100644 --- a/liblttng-ust-comm/lttng-ust-comm.c +++ b/liblttng-ust-comm/lttng-ust-comm.c @@ -37,16 +37,16 @@ static ssize_t count_fields_recursive(size_t nr_fields, - struct lttng_ust_event_field **lttng_fields); + const struct lttng_ust_event_field **lttng_fields); static int serialize_one_field(struct lttng_ust_session *session, struct ustctl_field *fields, size_t *iter_output, - struct lttng_ust_event_field *lf); + const struct lttng_ust_event_field *lf); static int serialize_fields(struct lttng_ust_session *session, struct ustctl_field *ustctl_fields, size_t *iter_output, size_t nr_lttng_fields, - struct lttng_ust_event_field **lttng_fields); + const struct lttng_ust_event_field **lttng_fields); /* * Human readable error message. @@ -864,7 +864,7 @@ int ustcomm_send_reg_msg(int sock, } static -ssize_t count_one_type(struct lttng_ust_type_common *lt) +ssize_t count_one_type(const struct lttng_ust_type_common *lt) { switch (lt->type) { case lttng_ust_type_integer: @@ -883,7 +883,7 @@ ssize_t count_one_type(struct lttng_ust_type_common *lt) case lttng_ust_type_dynamic: { - struct lttng_ust_event_field **choices; + const struct lttng_ust_event_field **choices; size_t nr_choices; int ret; @@ -906,7 +906,7 @@ ssize_t count_one_type(struct lttng_ust_type_common *lt) static ssize_t count_fields_recursive(size_t nr_fields, - struct lttng_ust_event_field **lttng_fields) + const struct lttng_ust_event_field **lttng_fields) { int i; ssize_t ret, count = 0; @@ -928,7 +928,7 @@ ssize_t count_fields_recursive(size_t nr_fields, static ssize_t count_ctx_fields_recursive(size_t nr_fields, - struct lttng_ust_ctx_field **lttng_fields) + struct lttng_ust_ctx_field *lttng_fields) { int i; ssize_t ret, count = 0; @@ -936,7 +936,7 @@ ssize_t count_ctx_fields_recursive(size_t nr_fields, for (i = 0; i < nr_fields; i++) { const struct lttng_ust_event_field *lf; - lf = lttng_fields[i]->event_field; + lf = lttng_fields[i].event_field; /* skip 'nowrite' fields */ if (lf->nowrite) continue; @@ -991,10 +991,10 @@ int serialize_dynamic_type(struct lttng_ust_session *session, struct ustctl_field *fields, size_t *iter_output, const char *field_name) { - struct lttng_ust_event_field **choices; + const struct lttng_ust_event_field **choices; char tag_field_name[LTTNG_UST_ABI_SYM_NAME_LEN]; - struct lttng_ust_type_common *tag_type; - struct lttng_ust_event_field *tag_field_generic; + const struct lttng_ust_type_common *tag_type; + const struct lttng_ust_event_field *tag_field_generic; struct lttng_ust_event_field tag_field = { .name = tag_field_name, .nowrite = 0, @@ -1048,7 +1048,7 @@ int serialize_dynamic_type(struct lttng_ust_session *session, static int serialize_one_type(struct lttng_ust_session *session, struct ustctl_field *fields, size_t *iter_output, - const char *field_name, struct lttng_ust_type_common *lt, + const char *field_name, const struct lttng_ust_type_common *lt, enum lttng_ust_string_encoding parent_encoding) { int ret; @@ -1083,7 +1083,7 @@ int serialize_one_type(struct lttng_ust_session *session, struct ustctl_field *uf = &fields[*iter_output]; struct ustctl_type *ut = &uf->type; struct ustctl_float_type *uft; - struct lttng_ust_type_float *lft; + const struct lttng_ust_type_float *lft; if (field_name) { strncpy(uf->name, field_name, LTTNG_UST_ABI_SYM_NAME_LEN); @@ -1243,7 +1243,7 @@ int serialize_one_type(struct lttng_ust_session *session, static int serialize_one_field(struct lttng_ust_session *session, struct ustctl_field *fields, size_t *iter_output, - struct lttng_ust_event_field *lf) + const struct lttng_ust_event_field *lf) { /* skip 'nowrite' fields */ if (lf->nowrite) @@ -1256,7 +1256,7 @@ static int serialize_fields(struct lttng_ust_session *session, struct ustctl_field *ustctl_fields, size_t *iter_output, size_t nr_lttng_fields, - struct lttng_ust_event_field **lttng_fields) + const struct lttng_ust_event_field **lttng_fields) { int ret; size_t i; @@ -1275,7 +1275,7 @@ int alloc_serialize_fields(struct lttng_ust_session *session, size_t *_nr_write_fields, struct ustctl_field **ustctl_fields, size_t nr_fields, - struct lttng_ust_event_field **lttng_fields) + const struct lttng_ust_event_field **lttng_fields) { struct ustctl_field *fields; int ret; @@ -1308,7 +1308,7 @@ error_type: static int serialize_entries(struct ustctl_enum_entry **_entries, size_t nr_entries, - struct lttng_ust_enum_entry **lttng_entries) + const struct lttng_ust_enum_entry **lttng_entries) { struct ustctl_enum_entry *entries; int i; @@ -1345,7 +1345,7 @@ int serialize_ctx_fields(struct lttng_ust_session *session, size_t *_nr_write_fields, struct ustctl_field **ustctl_fields, size_t nr_fields, - struct lttng_ust_ctx_field **lttng_fields) + struct lttng_ust_ctx_field *lttng_fields) { struct ustctl_field *fields; int ret; @@ -1364,7 +1364,7 @@ int serialize_ctx_fields(struct lttng_ust_session *session, for (i = 0; i < nr_fields; i++) { ret = serialize_one_field(session, fields, &iter_output, - lttng_fields[i]->event_field); + lttng_fields[i].event_field); if (ret) goto error_type; } @@ -1389,7 +1389,7 @@ int ustcomm_register_event(int sock, int loglevel, const char *signature, /* event signature (input) */ size_t nr_fields, /* fields */ - struct lttng_ust_event_field **lttng_fields, + const struct lttng_ust_event_field **lttng_fields, const char *model_emf_uri, uint32_t *id) /* event id (output) */ { @@ -1528,7 +1528,7 @@ int ustcomm_register_enum(int sock, int session_objd, /* session descriptor */ const char *enum_name, /* enum name (input) */ size_t nr_entries, /* entries */ - struct lttng_ust_enum_entry **lttng_entries, + const struct lttng_ust_enum_entry **lttng_entries, uint64_t *id) { ssize_t len; @@ -1633,7 +1633,7 @@ int ustcomm_register_channel(int sock, int session_objd, /* session descriptor */ int channel_objd, /* channel descriptor */ size_t nr_ctx_fields, - struct lttng_ust_ctx_field **ctx_fields, + struct lttng_ust_ctx_field *ctx_fields, uint32_t *chan_id, /* channel id (output) */ int *header_type) /* header type (output) */ { diff --git a/liblttng-ust-java-agent/jni/common/lttng_ust_context.c b/liblttng-ust-java-agent/jni/common/lttng_ust_context.c index 51b7c8e5..7ba4403a 100644 --- a/liblttng-ust-java-agent/jni/common/lttng_ust_context.c +++ b/liblttng-ust-java-agent/jni/common/lttng_ust_context.c @@ -44,6 +44,12 @@ struct lttng_ust_jni_ctx_entry { } value; } __attribute__((packed)); +struct lttng_ust_jni_provider { + struct lttng_ust_registered_context_provider *reg_provider; + char *name; + struct lttng_ust_context_provider provider; +}; + /* TLS passing context info from JNI to callbacks. */ __thread struct lttng_ust_jni_tls lttng_ust_context_info_tls; @@ -73,14 +79,14 @@ static struct lttng_ust_jni_ctx_entry *lookup_ctx_by_name(const char *ctx_name) return NULL; } -static size_t get_size_cb(struct lttng_ust_ctx_field *field, size_t offset) +static size_t get_size_cb(void *priv, size_t offset) { struct lttng_ust_jni_ctx_entry *jctx; size_t size = 0; - const char *ctx_name = field->event_field->name; + struct lttng_ust_jni_provider *jni_provider = (struct lttng_ust_jni_provider *) priv; + const char *ctx_name = jni_provider->name; enum lttng_ust_jni_type jni_type; - size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(char)); size += sizeof(char); /* tag */ jctx = lookup_ctx_by_name(ctx_name); @@ -135,12 +141,13 @@ static size_t get_size_cb(struct lttng_ust_ctx_field *field, size_t offset) } -static void record_cb(struct lttng_ust_ctx_field *field, +static void record_cb(void *priv, struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *lttng_chan_buf) { struct lttng_ust_jni_ctx_entry *jctx; - const char *ctx_name = field->event_field->name; + struct lttng_ust_jni_provider *jni_provider = (struct lttng_ust_jni_provider *) priv; + const char *ctx_name = jni_provider->name; enum lttng_ust_jni_type jni_type; char sel_char; @@ -240,11 +247,11 @@ static void record_cb(struct lttng_ust_ctx_field *field, } } -static void get_value_cb(struct lttng_ust_ctx_field *field, - struct lttng_ust_ctx_value *value) +static void get_value_cb(void *priv, struct lttng_ust_ctx_value *value) { + struct lttng_ust_jni_provider *jni_provider = (struct lttng_ust_jni_provider *) priv; struct lttng_ust_jni_ctx_entry *jctx; - const char *ctx_name = field->event_field->name; + const char *ctx_name = jni_provider->name; enum lttng_ust_jni_type jni_type; jctx = lookup_ctx_by_name(ctx_name); @@ -318,6 +325,7 @@ JNIEXPORT jlong JNICALL Java_org_lttng_ust_agent_context_LttngContextApi_registe const char *provider_name_jstr; char *provider_name_cstr; struct lttng_ust_context_provider *provider; + struct lttng_ust_jni_provider *jni_provider; /* * Note: a "jlong" is 8 bytes on all architectures, whereas a * C "long" varies. @@ -334,26 +342,30 @@ JNIEXPORT jlong JNICALL Java_org_lttng_ust_agent_context_LttngContextApi_registe if (!provider_name_cstr) { goto error_strdup; } - provider = zmalloc(sizeof(*provider)); - if (!provider) { + jni_provider = zmalloc(sizeof(*jni_provider)); + if (!jni_provider) { goto error_provider; } + provider = &jni_provider->provider; provider->struct_size = sizeof(*provider); - provider->name = provider_name_cstr; + jni_provider->name = provider_name_cstr; + provider->name = jni_provider->name; provider->get_size = get_size_cb; provider->record = record_cb; provider->get_value = get_value_cb; + provider->priv = jni_provider; - if (lttng_ust_context_provider_register(provider)) { + jni_provider->reg_provider = lttng_ust_context_provider_register(provider); + if (!jni_provider->reg_provider) { goto error_register; } - provider_ref = (jlong) (long) provider; + provider_ref = (jlong) (long) jni_provider; return provider_ref; /* Error handling. */ error_register: - free(provider); + free(jni_provider); error_provider: free(provider_name_cstr); error_strdup: @@ -371,15 +383,15 @@ JNIEXPORT void JNICALL Java_org_lttng_ust_agent_context_LttngContextApi_unregist jobject jobj __attribute__((unused)), jlong provider_ref) { - struct lttng_ust_context_provider *provider = - (struct lttng_ust_context_provider*) (unsigned long) provider_ref; + struct lttng_ust_jni_provider *jni_provider = + (struct lttng_ust_jni_provider *) (unsigned long) provider_ref; - if (!provider) { + if (!jni_provider) { return; } - lttng_ust_context_provider_unregister(provider); + lttng_ust_context_provider_unregister(jni_provider->reg_provider); - free(provider->name); - free(provider); + free(jni_provider->name); + free(jni_provider); } diff --git a/liblttng-ust/context-internal.h b/liblttng-ust/context-internal.h index 15a69559..209ffd43 100644 --- a/liblttng-ust/context-internal.h +++ b/liblttng-ust/context-internal.h @@ -25,21 +25,15 @@ int lttng_find_context(struct lttng_ust_ctx *ctx, const char *name) int lttng_get_context_index(struct lttng_ust_ctx *ctx, const char *name) __attribute__((visibility("hidden"))); -struct lttng_ust_ctx_field *lttng_append_context(struct lttng_ust_ctx **ctx_p) - __attribute__((visibility("hidden"))); - -void lttng_context_update(struct lttng_ust_ctx *ctx) - __attribute__((visibility("hidden"))); - -void lttng_remove_context_field(struct lttng_ust_ctx **ctx_p, - struct lttng_ust_ctx_field *field) +void lttng_destroy_context(struct lttng_ust_ctx *ctx) __attribute__((visibility("hidden"))); -void lttng_destroy_context(struct lttng_ust_ctx *ctx) +int lttng_ust_context_append_rcu(struct lttng_ust_ctx **ctx_p, + const struct lttng_ust_ctx_field *f) __attribute__((visibility("hidden"))); -int lttng_context_add_rcu(struct lttng_ust_ctx **ctx_p, - struct lttng_ust_ctx_field *f) +int lttng_ust_context_append(struct lttng_ust_ctx **ctx_p, + const struct lttng_ust_ctx_field *f) __attribute__((visibility("hidden"))); int lttng_context_is_app(const char *name) diff --git a/liblttng-ust/context-provider-internal.h b/liblttng-ust/context-provider-internal.h index b129153b..27d79ce1 100644 --- a/liblttng-ust/context-provider-internal.h +++ b/liblttng-ust/context-provider-internal.h @@ -11,12 +11,13 @@ #include void lttng_ust_context_set_event_notifier_group_provider(const char *name, - size_t (*get_size)(struct lttng_ust_ctx_field *field, size_t offset), - void (*record)(struct lttng_ust_ctx_field *field, + size_t (*get_size)(void *priv, size_t offset), + void (*record)(void *priv, struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan), - void (*get_value)(struct lttng_ust_ctx_field *field, - struct lttng_ust_ctx_value *value)) + void (*get_value)(void *priv, + struct lttng_ust_ctx_value *value), + void *priv) __attribute__((visibility("hidden"))); #endif /* _LTTNG_UST_CONTEXT_PROVIDER_INTERNAL_H */ diff --git a/liblttng-ust/event-notifier-notification.c b/liblttng-ust/event-notifier-notification.c index b9b0a7c6..b3e2c94f 100644 --- a/liblttng-ust/event-notifier-notification.c +++ b/liblttng-ust/event-notifier-notification.c @@ -64,7 +64,7 @@ void capture_enum(struct lttng_msgpack_writer *writer, static int64_t capture_sequence_element_signed(uint8_t *ptr, - struct lttng_ust_type_integer *integer_type) + const struct lttng_ust_type_integer *integer_type) { int64_t value; unsigned int size = integer_type->size; @@ -113,7 +113,7 @@ int64_t capture_sequence_element_signed(uint8_t *ptr, static uint64_t capture_sequence_element_unsigned(uint8_t *ptr, - struct lttng_ust_type_integer *integer_type) + const struct lttng_ust_type_integer *integer_type) { uint64_t value; unsigned int size = integer_type->size; @@ -164,8 +164,8 @@ static void capture_sequence(struct lttng_msgpack_writer *writer, struct lttng_interpreter_output *output) { - struct lttng_ust_type_integer *integer_type; - struct lttng_ust_type_common *nested_type; + const struct lttng_ust_type_integer *integer_type; + const struct lttng_ust_type_common *nested_type; uint8_t *ptr; bool signedness; int i; diff --git a/liblttng-ust/lttng-bytecode-interpreter.c b/liblttng-ust/lttng-bytecode-interpreter.c index 56b06884..cb128a69 100644 --- a/liblttng-ust/lttng-bytecode-interpreter.c +++ b/liblttng-ust/lttng-bytecode-interpreter.c @@ -219,18 +219,18 @@ static int context_get_index(struct lttng_ust_ctx *ctx, uint32_t idx) { - struct lttng_ust_ctx_field *ctx_field; - struct lttng_ust_event_field *field; + const struct lttng_ust_ctx_field *ctx_field; + const struct lttng_ust_event_field *field; struct lttng_ust_ctx_value v; - ctx_field = ctx->fields[idx]; + ctx_field = &ctx->fields[idx]; field = ctx_field->event_field; ptr->type = LOAD_OBJECT; ptr->field = field; switch (field->type->type) { case lttng_ust_type_integer: - ctx_field->get_value(ctx_field, &v); + ctx_field->get_value(ctx_field->priv, &v); if (lttng_ust_get_type_integer(field->type)->signedness) { ptr->object_type = OBJECT_TYPE_S64; ptr->u.s64 = v.u.s64; @@ -246,7 +246,7 @@ static int context_get_index(struct lttng_ust_ctx *ctx, const struct lttng_ust_type_integer *itype; itype = lttng_ust_get_type_integer(lttng_ust_get_type_enum(field->type)->container_type); - ctx_field->get_value(ctx_field, &v); + ctx_field->get_value(ctx_field->priv, &v); if (itype->signedness) { ptr->object_type = OBJECT_TYPE_SIGNED_ENUM; ptr->u.s64 = v.u.s64; @@ -268,7 +268,7 @@ static int context_get_index(struct lttng_ust_ctx *ctx, return -EINVAL; } ptr->object_type = OBJECT_TYPE_STRING; - ctx_field->get_value(ctx_field, &v); + ctx_field->get_value(ctx_field->priv, &v); ptr->ptr = v.u.str; break; case lttng_ust_type_sequence: @@ -281,22 +281,22 @@ static int context_get_index(struct lttng_ust_ctx *ctx, return -EINVAL; } ptr->object_type = OBJECT_TYPE_STRING; - ctx_field->get_value(ctx_field, &v); + ctx_field->get_value(ctx_field->priv, &v); ptr->ptr = v.u.str; break; case lttng_ust_type_string: ptr->object_type = OBJECT_TYPE_STRING; - ctx_field->get_value(ctx_field, &v); + ctx_field->get_value(ctx_field->priv, &v); ptr->ptr = v.u.str; break; case lttng_ust_type_float: ptr->object_type = OBJECT_TYPE_DOUBLE; - ctx_field->get_value(ctx_field, &v); + ctx_field->get_value(ctx_field->priv, &v); ptr->u.d = v.u.d; ptr->ptr = &ptr->u.d; break; case lttng_ust_type_dynamic: - ctx_field->get_value(ctx_field, &v); + ctx_field->get_value(ctx_field->priv, &v); switch (v.sel) { case LTTNG_UST_DYNAMIC_TYPE_NONE: return -EINVAL; @@ -2132,13 +2132,13 @@ int lttng_bytecode_interpret(struct lttng_ust_bytecode_runtime *ust_bytecode, { struct load_op *insn = (struct load_op *) pc; struct field_ref *ref = (struct field_ref *) insn->data; - struct lttng_ust_ctx_field *ctx_field; + const struct lttng_ust_ctx_field *ctx_field; struct lttng_ust_ctx_value v; dbg_printf("get context ref offset %u type dynamic\n", ref->offset); - ctx_field = ctx->fields[ref->offset]; - ctx_field->get_value(ctx_field, &v); + ctx_field = &ctx->fields[ref->offset]; + ctx_field->get_value(ctx_field->priv, &v); estack_push(stack, top, ax, bx, ax_t, bx_t); switch (v.sel) { case LTTNG_UST_DYNAMIC_TYPE_NONE: @@ -2180,13 +2180,13 @@ int lttng_bytecode_interpret(struct lttng_ust_bytecode_runtime *ust_bytecode, { struct load_op *insn = (struct load_op *) pc; struct field_ref *ref = (struct field_ref *) insn->data; - struct lttng_ust_ctx_field *ctx_field; + const struct lttng_ust_ctx_field *ctx_field; struct lttng_ust_ctx_value v; dbg_printf("get context ref offset %u type string\n", ref->offset); - ctx_field = ctx->fields[ref->offset]; - ctx_field->get_value(ctx_field, &v); + ctx_field = &ctx->fields[ref->offset]; + ctx_field->get_value(ctx_field->priv, &v); estack_push(stack, top, ax, bx, ax_t, bx_t); estack_ax(stack, top)->u.s.str = v.u.str; if (unlikely(!estack_ax(stack, top)->u.s.str)) { @@ -2207,13 +2207,13 @@ int lttng_bytecode_interpret(struct lttng_ust_bytecode_runtime *ust_bytecode, { struct load_op *insn = (struct load_op *) pc; struct field_ref *ref = (struct field_ref *) insn->data; - struct lttng_ust_ctx_field *ctx_field; + const struct lttng_ust_ctx_field *ctx_field; struct lttng_ust_ctx_value v; dbg_printf("get context ref offset %u type s64\n", ref->offset); - ctx_field = ctx->fields[ref->offset]; - ctx_field->get_value(ctx_field, &v); + ctx_field = &ctx->fields[ref->offset]; + ctx_field->get_value(ctx_field->priv, &v); estack_push(stack, top, ax, bx, ax_t, bx_t); estack_ax_v = v.u.s64; estack_ax_t = REG_S64; @@ -2226,13 +2226,13 @@ int lttng_bytecode_interpret(struct lttng_ust_bytecode_runtime *ust_bytecode, { struct load_op *insn = (struct load_op *) pc; struct field_ref *ref = (struct field_ref *) insn->data; - struct lttng_ust_ctx_field *ctx_field; + const struct lttng_ust_ctx_field *ctx_field; struct lttng_ust_ctx_value v; dbg_printf("get context ref offset %u type double\n", ref->offset); - ctx_field = ctx->fields[ref->offset]; - ctx_field->get_value(ctx_field, &v); + ctx_field = &ctx->fields[ref->offset]; + ctx_field->get_value(ctx_field->priv, &v); estack_push(stack, top, ax, bx, ax_t, bx_t); memcpy(&estack_ax(stack, top)->u.d, &v.u.d, sizeof(struct literal_double)); estack_ax_t = REG_DOUBLE; diff --git a/liblttng-ust/lttng-bytecode-specialize.c b/liblttng-ust/lttng-bytecode-specialize.c index 44eafb85..31bc3d05 100644 --- a/liblttng-ust/lttng-bytecode-specialize.c +++ b/liblttng-ust/lttng-bytecode-specialize.c @@ -254,8 +254,8 @@ static int specialize_get_index(struct bytecode_runtime *runtime, switch (stack_top->load.object_type) { case OBJECT_TYPE_ARRAY: { - struct lttng_ust_type_integer *integer_type; - struct lttng_ust_event_field *field; + const struct lttng_ust_type_integer *integer_type; + const struct lttng_ust_event_field *field; uint32_t elem_len, num_elems; int signedness; @@ -294,8 +294,8 @@ static int specialize_get_index(struct bytecode_runtime *runtime, } case OBJECT_TYPE_SEQUENCE: { - struct lttng_ust_type_integer *integer_type; - struct lttng_ust_event_field *field; + const struct lttng_ust_type_integer *integer_type; + const struct lttng_ust_event_field *field; uint32_t elem_len; int signedness; @@ -379,7 +379,7 @@ static int specialize_context_lookup_name(struct lttng_ust_ctx *ctx, return lttng_get_context_index(ctx, name); } -static int specialize_load_object(struct lttng_ust_event_field *field, +static int specialize_load_object(const struct lttng_ust_event_field *field, struct vstack_load *load, bool is_context) { load->type = LOAD_OBJECT; @@ -394,7 +394,7 @@ static int specialize_load_object(struct lttng_ust_event_field *field, break; case lttng_ust_type_enum: { - struct lttng_ust_type_integer *itype; + const struct lttng_ust_type_integer *itype; itype = lttng_ust_get_type_integer(lttng_ust_get_type_enum(field->type)->container_type); if (itype->signedness) @@ -459,8 +459,8 @@ static int specialize_context_lookup(struct lttng_ust_ctx *ctx, struct vstack_load *load) { int idx, ret; - struct lttng_ust_ctx_field *ctx_field; - struct lttng_ust_event_field *field; + const struct lttng_ust_ctx_field *ctx_field; + const struct lttng_ust_event_field *field; struct bytecode_get_index_data gid; ssize_t data_offset; @@ -468,7 +468,7 @@ static int specialize_context_lookup(struct lttng_ust_ctx *ctx, if (idx < 0) { return -ENOENT; } - ctx_field = ctx->fields[idx]; + ctx_field = &ctx->fields[idx]; field = ctx_field->event_field; ret = specialize_load_object(field, load, true); if (ret) @@ -498,8 +498,8 @@ static int specialize_app_context_lookup(struct lttng_ust_ctx **pctx, const char *orig_name; char *name = NULL; int idx, ret; - struct lttng_ust_ctx_field *ctx_field; - struct lttng_ust_event_field *field; + const struct lttng_ust_ctx_field *ctx_field; + const struct lttng_ust_event_field *field; struct bytecode_get_index_data gid; ssize_t data_offset; @@ -523,7 +523,7 @@ static int specialize_app_context_lookup(struct lttng_ust_ctx **pctx, if (idx < 0) return -ENOENT; } - ctx_field = (*pctx)->fields[idx]; + ctx_field = &(*pctx)->fields[idx]; field = ctx_field->event_field; ret = specialize_load_object(field, load, true); if (ret) @@ -548,7 +548,7 @@ end: return ret; } -static int specialize_payload_lookup(struct lttng_ust_event_desc *event_desc, +static int specialize_payload_lookup(const struct lttng_ust_event_desc *event_desc, struct bytecode_runtime *runtime, struct load_op *insn, struct vstack_load *load) @@ -558,7 +558,7 @@ static int specialize_payload_lookup(struct lttng_ust_event_desc *event_desc, unsigned int i, nr_fields; bool found = false; uint32_t field_offset = 0; - struct lttng_ust_event_field *field; + const struct lttng_ust_event_field *field; int ret; struct bytecode_get_index_data gid; ssize_t data_offset; @@ -625,7 +625,7 @@ end: return ret; } -int lttng_bytecode_specialize(struct lttng_ust_event_desc *event_desc, +int lttng_bytecode_specialize(const struct lttng_ust_event_desc *event_desc, struct bytecode_runtime *bytecode) { void *pc, *next_pc, *start_pc; diff --git a/liblttng-ust/lttng-bytecode.c b/liblttng-ust/lttng-bytecode.c index 387fc4b9..ea5827a4 100644 --- a/liblttng-ust/lttng-bytecode.c +++ b/liblttng-ust/lttng-bytecode.c @@ -179,7 +179,7 @@ int apply_field_reloc(const struct lttng_ust_event_desc *event_desc, const char *field_name, enum bytecode_op bytecode_op) { - struct lttng_ust_event_field **fields, *field = NULL; + const struct lttng_ust_event_field **fields, *field = NULL; unsigned int nr_fields, i; struct load_op *op; uint32_t field_offset = 0; @@ -288,7 +288,7 @@ int apply_context_reloc(struct bytecode_runtime *runtime, enum bytecode_op bytecode_op) { struct load_op *op; - struct lttng_ust_ctx_field *ctx_field; + const struct lttng_ust_ctx_field *ctx_field; int idx; struct lttng_ust_ctx **pctx = runtime->p.pctx; @@ -316,7 +316,7 @@ int apply_context_reloc(struct bytecode_runtime *runtime, return -EINVAL; /* Get context return type */ - ctx_field = (*pctx)->fields[idx]; + ctx_field = &(*pctx)->fields[idx]; op = (struct load_op *) &runtime->code[reloc_offset]; switch (bytecode_op) { @@ -426,7 +426,7 @@ int bytecode_is_linked(struct lttng_ust_bytecode_node *bytecode, * bytecode runtime. */ static -int link_bytecode(struct lttng_ust_event_desc *event_desc, +int link_bytecode(const struct lttng_ust_event_desc *event_desc, struct lttng_ust_ctx **ctx, struct lttng_ust_bytecode_node *bytecode, struct cds_list_head *bytecode_runtime_head, @@ -519,7 +519,7 @@ void lttng_bytecode_sync_state(struct lttng_ust_bytecode_runtime *runtime) * This function is called after we confirmed that name enabler and the * instance are name matching (or glob pattern matching). */ -void lttng_enabler_link_bytecode(struct lttng_ust_event_desc *event_desc, +void lttng_enabler_link_bytecode(const struct lttng_ust_event_desc *event_desc, struct lttng_ust_ctx **ctx, struct cds_list_head *instance_bytecode_head, struct cds_list_head *enabler_bytecode_head) diff --git a/liblttng-ust/lttng-bytecode.h b/liblttng-ust/lttng-bytecode.h index 29ae7b20..ffbaf187 100644 --- a/liblttng-ust/lttng-bytecode.h +++ b/liblttng-ust/lttng-bytecode.h @@ -120,7 +120,7 @@ struct bytecode_get_index_data { * interpreter needs to find it from the event fields and types to * support variants. */ - struct lttng_ust_event_field *field; + const struct lttng_ust_event_field *field; struct { size_t len; enum object_type type; @@ -132,7 +132,7 @@ struct bytecode_get_index_data { struct vstack_load { enum load_type type; enum object_type object_type; - struct lttng_ust_event_field *field; + const struct lttng_ust_event_field *field; bool rev_bo; /* reverse byte order */ }; @@ -310,7 +310,7 @@ struct lttng_interpreter_output { size_t nr_elem; /* Inner type. */ - struct lttng_ust_type_common *nested_type; + const struct lttng_ust_type_common *nested_type; } sequence; } u; }; @@ -324,7 +324,7 @@ void lttng_bytecode_sync_state(struct lttng_ust_bytecode_runtime *runtime) int lttng_bytecode_validate(struct bytecode_runtime *bytecode) __attribute__((visibility("hidden"))); -int lttng_bytecode_specialize(struct lttng_ust_event_desc *event_desc, +int lttng_bytecode_specialize(const struct lttng_ust_event_desc *event_desc, struct bytecode_runtime *bytecode) __attribute__((visibility("hidden"))); diff --git a/liblttng-ust/lttng-context-cgroup-ns.c b/liblttng-ust/lttng-context-cgroup-ns.c index 51991cc6..fece0808 100644 --- a/liblttng-ust/lttng-context-cgroup-ns.c +++ b/liblttng-ust/lttng-context-cgroup-ns.c @@ -91,7 +91,7 @@ void lttng_context_cgroup_ns_reset(void) } static -size_t cgroup_ns_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t cgroup_ns_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -102,7 +102,7 @@ size_t cgroup_ns_get_size(struct lttng_ust_ctx_field *field __attribute__((unuse } static -void cgroup_ns_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void cgroup_ns_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -114,50 +114,38 @@ void cgroup_ns_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void cgroup_ns_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void cgroup_ns_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.s64 = get_cgroup_ns(); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("cgroup_ns", + lttng_ust_static_type_integer(sizeof(ino_t) * CHAR_BIT, + lttng_ust_rb_alignof(ino_t) * CHAR_BIT, + lttng_ust_is_signed_type(ino_t), + BYTE_ORDER, 10), + false, false), + cgroup_ns_get_size, + cgroup_ns_record, + cgroup_ns_get_value, + NULL, NULL); + int lttng_add_cgroup_ns_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(ino_t) * CHAR_BIT, - lttng_ust_rb_alignof(ino_t) * CHAR_BIT, - lttng_ust_is_signed_type(ino_t), - BYTE_ORDER, 10); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "cgroup_ns")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("cgroup_ns"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = cgroup_ns_get_size; - field->record = cgroup_ns_record; - field->get_value = cgroup_ns_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-cpu-id.c b/liblttng-ust/lttng-context-cpu-id.c index 9fa4c371..358dff98 100644 --- a/liblttng-ust/lttng-context-cpu-id.c +++ b/liblttng-ust/lttng-context-cpu-id.c @@ -25,7 +25,7 @@ #include "context-internal.h" static -size_t cpu_id_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t cpu_id_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -36,7 +36,7 @@ size_t cpu_id_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)) } static -void cpu_id_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void cpu_id_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -47,49 +47,37 @@ void cpu_id_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void cpu_id_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void cpu_id_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.s64 = lttng_ust_get_cpu(); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("cpu_id", + lttng_ust_static_type_integer(sizeof(int) * CHAR_BIT, + lttng_ust_rb_alignof(int) * CHAR_BIT, + lttng_ust_is_signed_type(int), + BYTE_ORDER, 10), + false, false), + cpu_id_get_size, + cpu_id_record, + cpu_id_get_value, + NULL, NULL); + int lttng_add_cpu_id_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(int) * CHAR_BIT, - lttng_ust_rb_alignof(int) * CHAR_BIT, - lttng_ust_is_signed_type(int), - BYTE_ORDER, 10); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "cpu_id")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("cpu_id"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = cpu_id_get_size; - field->record = cpu_id_record; - field->get_value = cpu_id_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-ip.c b/liblttng-ust/lttng-context-ip.c index bdf2f123..e9cc969f 100644 --- a/liblttng-ust/lttng-context-ip.c +++ b/liblttng-ust/lttng-context-ip.c @@ -18,7 +18,7 @@ #include "context-internal.h" static -size_t ip_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t ip_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -29,7 +29,7 @@ size_t ip_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void ip_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void ip_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -39,42 +39,30 @@ void ip_record(struct lttng_ust_ctx_field *field __attribute__((unused)), chan->ops->event_write(ctx, &ip, sizeof(ip), lttng_ust_rb_alignof(ip)); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("ip", + lttng_ust_static_type_integer(sizeof(void *) * CHAR_BIT, + lttng_ust_rb_alignof(void *) * CHAR_BIT, + lttng_ust_is_signed_type(void *), + BYTE_ORDER, 10), + false, false), + ip_get_size, + ip_record, + NULL, NULL, NULL); + int lttng_add_ip_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(void *) * CHAR_BIT, - lttng_ust_rb_alignof(void *) * CHAR_BIT, - lttng_ust_is_signed_type(void *), - BYTE_ORDER, 16); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "ip")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("ip"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = ip_get_size; - field->record = ip_record; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-ipc-ns.c b/liblttng-ust/lttng-context-ipc-ns.c index 464887bb..2ec62416 100644 --- a/liblttng-ust/lttng-context-ipc-ns.c +++ b/liblttng-ust/lttng-context-ipc-ns.c @@ -90,7 +90,7 @@ void lttng_context_ipc_ns_reset(void) } static -size_t ipc_ns_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t ipc_ns_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -101,7 +101,7 @@ size_t ipc_ns_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)) } static -void ipc_ns_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void ipc_ns_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -112,50 +112,38 @@ void ipc_ns_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void ipc_ns_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void ipc_ns_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.s64 = get_ipc_ns(); } +const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("ipc_ns", + lttng_ust_static_type_integer(sizeof(ino_t) * CHAR_BIT, + lttng_ust_rb_alignof(ino_t) * CHAR_BIT, + lttng_ust_is_signed_type(ino_t), + BYTE_ORDER, 10), + false, false), + ipc_ns_get_size, + ipc_ns_record, + ipc_ns_get_value, + NULL, NULL); + int lttng_add_ipc_ns_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(ino_t) * CHAR_BIT, - lttng_ust_rb_alignof(ino_t) * CHAR_BIT, - lttng_ust_is_signed_type(ino_t), - BYTE_ORDER, 10); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "ipc_ns")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("ipc_ns"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = ipc_ns_get_size; - field->record = ipc_ns_record; - field->get_value = ipc_ns_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-mnt-ns.c b/liblttng-ust/lttng-context-mnt-ns.c index 8d4bdb1d..61812625 100644 --- a/liblttng-ust/lttng-context-mnt-ns.c +++ b/liblttng-ust/lttng-context-mnt-ns.c @@ -73,7 +73,7 @@ void lttng_context_mnt_ns_reset(void) } static -size_t mnt_ns_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t mnt_ns_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -84,7 +84,7 @@ size_t mnt_ns_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)) } static -void mnt_ns_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void mnt_ns_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -95,49 +95,37 @@ void mnt_ns_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void mnt_ns_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void mnt_ns_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.s64 = get_mnt_ns(); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("mnt_ns", + lttng_ust_static_type_integer(sizeof(ino_t) * CHAR_BIT, + lttng_ust_rb_alignof(ino_t) * CHAR_BIT, + lttng_ust_is_signed_type(ino_t), + BYTE_ORDER, 10), + false, false), + mnt_ns_get_size, + mnt_ns_record, + mnt_ns_get_value, + NULL, NULL); + int lttng_add_mnt_ns_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(ino_t) * CHAR_BIT, - lttng_ust_rb_alignof(ino_t) * CHAR_BIT, - lttng_ust_is_signed_type(ino_t), - BYTE_ORDER, 10); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "mnt_ns")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("mnt_ns"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = mnt_ns_get_size; - field->record = mnt_ns_record; - field->get_value = mnt_ns_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-net-ns.c b/liblttng-ust/lttng-context-net-ns.c index 004d3978..76707cba 100644 --- a/liblttng-ust/lttng-context-net-ns.c +++ b/liblttng-ust/lttng-context-net-ns.c @@ -90,7 +90,7 @@ void lttng_context_net_ns_reset(void) } static -size_t net_ns_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t net_ns_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -101,7 +101,7 @@ size_t net_ns_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)) } static -void net_ns_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void net_ns_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -112,50 +112,38 @@ void net_ns_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void net_ns_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void net_ns_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.s64 = get_net_ns(); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("net_ns", + lttng_ust_static_type_integer(sizeof(ino_t) * CHAR_BIT, + lttng_ust_rb_alignof(ino_t) * CHAR_BIT, + lttng_ust_is_signed_type(ino_t), + BYTE_ORDER, 10), + false, false), + net_ns_get_size, + net_ns_record, + net_ns_get_value, + NULL, NULL); + int lttng_add_net_ns_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(ino_t) * CHAR_BIT, - lttng_ust_rb_alignof(ino_t) * CHAR_BIT, - lttng_ust_is_signed_type(ino_t), - BYTE_ORDER, 10); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "net_ns")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("net_ns"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = net_ns_get_size; - field->record = net_ns_record; - field->get_value = net_ns_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-perf-counters.c b/liblttng-ust/lttng-context-perf-counters.c index dac953ff..6f620911 100644 --- a/liblttng-ust/lttng-context-perf-counters.c +++ b/liblttng-ust/lttng-context-perf-counters.c @@ -61,6 +61,7 @@ struct lttng_perf_counter_thread { struct lttng_perf_counter_field { struct perf_event_attr attr; struct cds_list_head thread_field_list; /* Per-field list of thread fields */ + char *name; }; static pthread_key_t perf_counter_key; @@ -158,7 +159,7 @@ void lttng_perf_unlock(void) } static -size_t perf_counter_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t perf_counter_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -428,32 +429,32 @@ struct lttng_perf_counter_thread_field * } static -uint64_t wrapper_perf_counter_read(struct lttng_ust_ctx_field *field) +uint64_t wrapper_perf_counter_read(void *priv) { struct lttng_perf_counter_field *perf_field; struct lttng_perf_counter_thread_field *perf_thread_field; - perf_field = (struct lttng_perf_counter_field *) field->priv; + perf_field = (struct lttng_perf_counter_field *) priv; perf_thread_field = get_thread_field(perf_field); return arch_read_perf_counter(perf_thread_field); } static -void perf_counter_record(struct lttng_ust_ctx_field *field, +void perf_counter_record(void *priv, struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { uint64_t value; - value = wrapper_perf_counter_read(field); + value = wrapper_perf_counter_read(priv); chan->ops->event_write(ctx, &value, sizeof(value), lttng_ust_rb_alignof(value)); } static -void perf_counter_get_value(struct lttng_ust_ctx_field *field, +void perf_counter_get_value(void *priv, struct lttng_ust_ctx_value *value) { - value->u.s64 = wrapper_perf_counter_read(field); + value->u.s64 = wrapper_perf_counter_read(priv); } /* Called with perf lock held */ @@ -484,13 +485,13 @@ void lttng_destroy_perf_thread_key(void *_key) /* Called with UST lock held */ static -void lttng_destroy_perf_counter_field(struct lttng_ust_ctx_field *field) +void lttng_destroy_perf_counter_ctx_field(void *priv) { struct lttng_perf_counter_field *perf_field; struct lttng_perf_counter_thread_field *pos, *p; - free((char *) field->event_field->name); - perf_field = (struct lttng_perf_counter_field *) field->priv; + perf_field = (struct lttng_perf_counter_field *) priv; + free(perf_field->name); /* * This put is performed when no threads can concurrently * perform a "get" concurrently, thanks to urcu-bp grace @@ -524,59 +525,51 @@ int perf_get_exclude_kernel(void) #endif /* LTTNG_UST_ARCH_ARMV7 */ +static const struct lttng_ust_type_common *ust_type = + lttng_ust_static_type_integer(sizeof(uint64_t) * CHAR_BIT, + lttng_ust_rb_alignof(uint64_t) * CHAR_BIT, + lttng_ust_is_signed_type(uint64_t), + BYTE_ORDER, 10); + /* Called with UST lock held */ int lttng_add_perf_counter_to_ctx(uint32_t type, uint64_t config, const char *name, struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *ust_type; + struct lttng_ust_ctx_field ctx_field; + struct lttng_ust_event_field *event_field; struct lttng_perf_counter_field *perf_field; char *name_alloc; int ret; + if (lttng_find_context(*ctx, name)) { + ret = -EEXIST; + goto find_error; + } name_alloc = strdup(name); if (!name_alloc) { ret = -ENOMEM; goto name_alloc_error; } + event_field = zmalloc(sizeof(*event_field)); + if (!event_field) { + ret = -ENOMEM; + goto event_field_alloc_error; + } + event_field->name = name_alloc; + event_field->type = ust_type; + perf_field = zmalloc(sizeof(*perf_field)); if (!perf_field) { ret = -ENOMEM; goto perf_field_alloc_error; } - ust_type = lttng_ust_create_type_integer(sizeof(uint64_t) * CHAR_BIT, - lttng_ust_rb_alignof(uint64_t) * CHAR_BIT, - lttng_ust_is_signed_type(uint64_t), - BYTE_ORDER, 10); - if (!ust_type) { - ret = -ENOMEM; - goto type_alloc_error; - } - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto append_context_error; - } - if (lttng_find_context(*ctx, name_alloc)) { - ret = -EEXIST; - goto find_error; - } - - field->destroy = lttng_destroy_perf_counter_field; - - field->event_field->name = name_alloc; - field->event_field->type = ust_type; - field->get_size = perf_counter_get_size; - field->record = perf_counter_record; - field->get_value = perf_counter_get_value; - perf_field->attr.type = type; perf_field->attr.config = config; perf_field->attr.exclude_kernel = perf_get_exclude_kernel(); CDS_INIT_LIST_HEAD(&perf_field->thread_field_list); - field->priv = perf_field; + perf_field->name = name_alloc; /* Ensure that this perf counter can be used in this process. */ ret = open_perf_fd(&perf_field->attr); @@ -586,25 +579,29 @@ int lttng_add_perf_counter_to_ctx(uint32_t type, } close_perf_fd(ret); - /* - * Contexts can only be added before tracing is started, so we - * don't have to synchronize against concurrent threads using - * the field here. - */ + ctx_field.event_field = event_field; + ctx_field.get_size = perf_counter_get_size; + ctx_field.record = perf_counter_record; + ctx_field.get_value = perf_counter_get_value; + ctx_field.destroy = lttng_destroy_perf_counter_ctx_field; + ctx_field.priv = perf_field; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, &ctx_field); + if (ret) { + ret = -ENOMEM; + goto append_context_error; + } return 0; -setup_error: -find_error: - lttng_remove_context_field(ctx, field); append_context_error: - lttng_ust_destroy_type(ust_type); -type_alloc_error: +setup_error: free(perf_field); perf_field_alloc_error: + free(event_field); +event_field_alloc_error: free(name_alloc); name_alloc_error: +find_error: return ret; } diff --git a/liblttng-ust/lttng-context-pid-ns.c b/liblttng-ust/lttng-context-pid-ns.c index 10b0c1b2..4e42e6b5 100644 --- a/liblttng-ust/lttng-context-pid-ns.c +++ b/liblttng-ust/lttng-context-pid-ns.c @@ -76,7 +76,7 @@ void lttng_context_pid_ns_reset(void) } static -size_t pid_ns_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t pid_ns_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -87,7 +87,7 @@ size_t pid_ns_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)) } static -void pid_ns_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void pid_ns_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -98,49 +98,37 @@ void pid_ns_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void pid_ns_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void pid_ns_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.s64 = get_pid_ns(); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("pid_ns", + lttng_ust_static_type_integer(sizeof(ino_t) * CHAR_BIT, + lttng_ust_rb_alignof(ino_t) * CHAR_BIT, + lttng_ust_is_signed_type(ino_t), + BYTE_ORDER, 10), + false, false), + pid_ns_get_size, + pid_ns_record, + pid_ns_get_value, + NULL, NULL); + int lttng_add_pid_ns_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(ino_t) * CHAR_BIT, - lttng_ust_rb_alignof(ino_t) * CHAR_BIT, - lttng_ust_is_signed_type(ino_t), - BYTE_ORDER, 10); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "pid_ns")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("pid_ns"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = pid_ns_get_size; - field->record = pid_ns_record; - field->get_value = pid_ns_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-procname.c b/liblttng-ust/lttng-context-procname.c index 0edde6e8..96a1b2ca 100644 --- a/liblttng-ust/lttng-context-procname.c +++ b/liblttng-ust/lttng-context-procname.c @@ -66,14 +66,14 @@ void lttng_ust_context_procname_reset(void) } static -size_t procname_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t procname_get_size(void *priv __attribute__((unused)), size_t offset __attribute__((unused))) { return LTTNG_UST_ABI_PROCNAME_LEN; } static -void procname_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void procname_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -84,47 +84,35 @@ void procname_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void procname_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void procname_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.str = wrapper_getprocname(); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("procname", + lttng_ust_static_type_array_text(LTTNG_UST_ABI_PROCNAME_LEN), + false, false), + procname_get_size, + procname_record, + procname_get_value, + NULL, NULL); + int lttng_add_procname_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_array_text(LTTNG_UST_ABI_PROCNAME_LEN); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "procname")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("procname"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = procname_get_size; - field->record = procname_record; - field->get_value = procname_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-provider.c b/liblttng-ust/lttng-context-provider.c index c3f50e80..bc2b23e6 100644 --- a/liblttng-ust/lttng-context-provider.c +++ b/liblttng-ust/lttng-context-provider.c @@ -20,6 +20,12 @@ #include "context-provider-internal.h" #include +struct lttng_ust_registered_context_provider { + const struct lttng_ust_context_provider *provider; + + struct cds_hlist_node node; +}; + #define CONTEXT_PROVIDER_HT_BITS 12 #define CONTEXT_PROVIDER_HT_SIZE (1U << CONTEXT_PROVIDER_HT_BITS) struct context_provider_ht { @@ -28,12 +34,12 @@ struct context_provider_ht { static struct context_provider_ht context_provider_ht; -static struct lttng_ust_context_provider * +static const struct lttng_ust_context_provider * lookup_provider_by_name(const char *name) { struct cds_hlist_head *head; struct cds_hlist_node *node; - struct lttng_ust_context_provider *provider; + struct lttng_ust_registered_context_provider *reg_provider; uint32_t hash; const char *end; size_t len; @@ -46,69 +52,70 @@ static struct lttng_ust_context_provider * len = strlen(name); hash = jhash(name, len, 0); head = &context_provider_ht.table[hash & (CONTEXT_PROVIDER_HT_SIZE - 1)]; - cds_hlist_for_each_entry(provider, node, head, node) { - if (!strncmp(provider->name, name, len)) - return provider; + cds_hlist_for_each_entry(reg_provider, node, head, node) { + if (!strncmp(reg_provider->provider->name, name, len)) + return reg_provider->provider; } return NULL; } -int lttng_ust_context_provider_register(struct lttng_ust_context_provider *provider) +struct lttng_ust_registered_context_provider *lttng_ust_context_provider_register(struct lttng_ust_context_provider *provider) { + struct lttng_ust_registered_context_provider *reg_provider = NULL; struct cds_hlist_head *head; size_t name_len = strlen(provider->name); uint32_t hash; - int ret = 0; lttng_ust_fixup_tls(); /* Provider name starts with "$app.". */ if (strncmp("$app.", provider->name, strlen("$app.")) != 0) - return -EINVAL; + return NULL; /* Provider name cannot contain a colon character. */ if (strchr(provider->name, ':')) - return -EINVAL; - if (ust_lock()) { - ret = -EBUSY; + return NULL; + if (ust_lock()) goto end; - } - if (lookup_provider_by_name(provider->name)) { - ret = -EBUSY; + if (lookup_provider_by_name(provider->name)) goto end; - } + reg_provider = zmalloc(sizeof(struct lttng_ust_registered_context_provider)); + if (!reg_provider) + goto end; + reg_provider->provider = provider; hash = jhash(provider->name, name_len, 0); head = &context_provider_ht.table[hash & (CONTEXT_PROVIDER_HT_SIZE - 1)]; - cds_hlist_add_head(&provider->node, head); + cds_hlist_add_head(®_provider->node, head); lttng_ust_context_set_session_provider(provider->name, provider->get_size, provider->record, - provider->get_value); + provider->get_value, provider->priv); lttng_ust_context_set_event_notifier_group_provider(provider->name, provider->get_size, provider->record, - provider->get_value); + provider->get_value, provider->priv); end: ust_unlock(); - return ret; + return reg_provider; } -void lttng_ust_context_provider_unregister(struct lttng_ust_context_provider *provider) +void lttng_ust_context_provider_unregister(struct lttng_ust_registered_context_provider *reg_provider) { lttng_ust_fixup_tls(); if (ust_lock()) goto end; - lttng_ust_context_set_session_provider(provider->name, + lttng_ust_context_set_session_provider(reg_provider->provider->name, lttng_ust_dummy_get_size, lttng_ust_dummy_record, - lttng_ust_dummy_get_value); + lttng_ust_dummy_get_value, NULL); - lttng_ust_context_set_event_notifier_group_provider(provider->name, + lttng_ust_context_set_event_notifier_group_provider(reg_provider->provider->name, lttng_ust_dummy_get_size, lttng_ust_dummy_record, - lttng_ust_dummy_get_value); + lttng_ust_dummy_get_value, NULL); - cds_hlist_del(&provider->node); + cds_hlist_del(®_provider->node); end: ust_unlock(); + free(reg_provider); } /* @@ -122,8 +129,10 @@ end: int lttng_ust_add_app_context_to_ctx_rcu(const char *name, struct lttng_ust_ctx **ctx) { - struct lttng_ust_context_provider *provider; + const struct lttng_ust_context_provider *provider; struct lttng_ust_ctx_field *new_field = NULL; + struct lttng_ust_event_field *event_field = NULL; + struct lttng_ust_type_common *type = NULL; int ret; if (*ctx && lttng_find_context(*ctx, name)) @@ -133,23 +142,24 @@ int lttng_ust_add_app_context_to_ctx_rcu(const char *name, ret = -ENOMEM; goto error_field_alloc; } - new_field->struct_size = sizeof(struct lttng_ust_ctx_field); - new_field->event_field = zmalloc(sizeof(struct lttng_ust_event_field)); - if (!new_field->event_field) { + event_field = zmalloc(sizeof(struct lttng_ust_event_field)); + if (!event_field) { ret = -ENOMEM; goto error_event_field_alloc; } - new_field->event_field->name = strdup(name); - if (!new_field->event_field->name) { + event_field->name = strdup(name); + if (!event_field->name) { ret = -ENOMEM; goto error_field_name_alloc; } - new_field->event_field->type = zmalloc(sizeof(struct lttng_ust_type_common)); - if (!new_field->event_field->type) { + type = zmalloc(sizeof(struct lttng_ust_type_common)); + if (!type) { ret = -ENOMEM; goto error_field_type_alloc; } - new_field->event_field->type->type = lttng_ust_type_dynamic; + type->type = lttng_ust_type_dynamic; + event_field->type = type; + new_field->event_field = event_field; /* * If provider is not found, we add the context anyway, but * it will provide a dummy context. @@ -169,11 +179,11 @@ int lttng_ust_add_app_context_to_ctx_rcu(const char *name, * ctx array. Ownership of new_field is passed to the callee on * success. */ - ret = lttng_context_add_rcu(ctx, new_field); + ret = lttng_ust_context_append_rcu(ctx, new_field); if (ret) { - free(new_field->event_field->type); + free(type); free((char *) new_field->event_field->name); - free(new_field->event_field); + free(event_field); free(new_field); return ret; } @@ -182,7 +192,7 @@ int lttng_ust_add_app_context_to_ctx_rcu(const char *name, error_field_type_alloc: free((char *) new_field->event_field->name); error_field_name_alloc: - free(new_field->event_field); + free(event_field); error_event_field_alloc: free(new_field); error_field_alloc: diff --git a/liblttng-ust/lttng-context-pthread-id.c b/liblttng-ust/lttng-context-pthread-id.c index a032b26a..da02d1a8 100644 --- a/liblttng-ust/lttng-context-pthread-id.c +++ b/liblttng-ust/lttng-context-pthread-id.c @@ -17,7 +17,7 @@ #include "context-internal.h" static -size_t pthread_id_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t pthread_id_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -28,7 +28,7 @@ size_t pthread_id_get_size(struct lttng_ust_ctx_field *field __attribute__((unus } static -void pthread_id_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void pthread_id_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -39,49 +39,37 @@ void pthread_id_record(struct lttng_ust_ctx_field *field __attribute__((unused)) } static -void pthread_id_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void pthread_id_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.s64 = (unsigned long) pthread_self(); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("pthread_id", + lttng_ust_static_type_integer(sizeof(unsigned long) * CHAR_BIT, + lttng_ust_rb_alignof(unsigned long) * CHAR_BIT, + lttng_ust_is_signed_type(unsigned long), + BYTE_ORDER, 10), + false, false), + pthread_id_get_size, + pthread_id_record, + pthread_id_get_value, + NULL, NULL); + int lttng_add_pthread_id_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(unsigned long) * CHAR_BIT, - lttng_ust_rb_alignof(unsigned long) * CHAR_BIT, - lttng_ust_is_signed_type(unsigned long), - BYTE_ORDER, 10); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "pthread_id")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("pthread_id"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = pthread_id_get_size; - field->record = pthread_id_record; - field->get_value = pthread_id_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-time-ns.c b/liblttng-ust/lttng-context-time-ns.c index a8a30df8..cb907c4a 100644 --- a/liblttng-ust/lttng-context-time-ns.c +++ b/liblttng-ust/lttng-context-time-ns.c @@ -89,7 +89,7 @@ void lttng_context_time_ns_reset(void) } static -size_t time_ns_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t time_ns_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -100,7 +100,7 @@ size_t time_ns_get_size(struct lttng_ust_ctx_field *field __attribute__((unused) } static -void time_ns_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void time_ns_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -111,50 +111,38 @@ void time_ns_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void time_ns_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void time_ns_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.s64 = get_time_ns(); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("time_ns", + lttng_ust_static_type_integer(sizeof(ino_t) * CHAR_BIT, + lttng_ust_rb_alignof(ino_t) * CHAR_BIT, + lttng_ust_is_signed_type(ino_t), + BYTE_ORDER, 10), + false, false), + time_ns_get_size, + time_ns_record, + time_ns_get_value, + NULL, NULL); + int lttng_add_time_ns_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(ino_t) * CHAR_BIT, - lttng_ust_rb_alignof(ino_t) * CHAR_BIT, - lttng_ust_is_signed_type(ino_t), - BYTE_ORDER, 10); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "time_ns")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("time_ns"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = time_ns_get_size; - field->record = time_ns_record; - field->get_value = time_ns_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-user-ns.c b/liblttng-ust/lttng-context-user-ns.c index 53303d0f..9d31da5e 100644 --- a/liblttng-ust/lttng-context-user-ns.c +++ b/liblttng-ust/lttng-context-user-ns.c @@ -73,7 +73,7 @@ void lttng_context_user_ns_reset(void) } static -size_t user_ns_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t user_ns_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -84,7 +84,7 @@ size_t user_ns_get_size(struct lttng_ust_ctx_field *field __attribute__((unused) } static -void user_ns_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void user_ns_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -95,49 +95,37 @@ void user_ns_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void user_ns_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void user_ns_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.s64 = get_user_ns(); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("user_ns", + lttng_ust_static_type_integer(sizeof(ino_t) * CHAR_BIT, + lttng_ust_rb_alignof(ino_t) * CHAR_BIT, + lttng_ust_is_signed_type(ino_t), + BYTE_ORDER, 10), + false, false), + user_ns_get_size, + user_ns_record, + user_ns_get_value, + NULL, NULL); + int lttng_add_user_ns_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(ino_t) * CHAR_BIT, - lttng_ust_rb_alignof(ino_t) * CHAR_BIT, - lttng_ust_is_signed_type(ino_t), - BYTE_ORDER, 10); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "user_ns")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("user_ns"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = user_ns_get_size; - field->record = user_ns_record; - field->get_value = user_ns_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-uts-ns.c b/liblttng-ust/lttng-context-uts-ns.c index 5ac0205f..5ba06f6e 100644 --- a/liblttng-ust/lttng-context-uts-ns.c +++ b/liblttng-ust/lttng-context-uts-ns.c @@ -91,7 +91,7 @@ void lttng_context_uts_ns_reset(void) } static -size_t uts_ns_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t uts_ns_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -102,7 +102,7 @@ size_t uts_ns_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)) } static -void uts_ns_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void uts_ns_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -113,50 +113,38 @@ void uts_ns_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void uts_ns_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void uts_ns_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.s64 = get_uts_ns(); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("uts_ns", + lttng_ust_static_type_integer(sizeof(ino_t) * CHAR_BIT, + lttng_ust_rb_alignof(ino_t) * CHAR_BIT, + lttng_ust_is_signed_type(ino_t), + BYTE_ORDER, 10), + false, false), + uts_ns_get_size, + uts_ns_record, + uts_ns_get_value, + NULL, NULL); + int lttng_add_uts_ns_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(ino_t) * CHAR_BIT, - lttng_ust_rb_alignof(ino_t) * CHAR_BIT, - lttng_ust_is_signed_type(ino_t), - BYTE_ORDER, 10); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "uts_ns")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("uts_ns"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = uts_ns_get_size; - field->record = uts_ns_record; - field->get_value = uts_ns_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-vegid.c b/liblttng-ust/lttng-context-vegid.c index 6b7d0698..97618ce0 100644 --- a/liblttng-ust/lttng-context-vegid.c +++ b/liblttng-ust/lttng-context-vegid.c @@ -62,7 +62,7 @@ void lttng_context_vegid_reset(void) } static -size_t vegid_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t vegid_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -73,7 +73,7 @@ size_t vegid_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void vegid_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void vegid_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -84,49 +84,37 @@ void vegid_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void vegid_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void vegid_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.s64 = get_vegid(); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("vegid", + lttng_ust_static_type_integer(sizeof(gid_t) * CHAR_BIT, + lttng_ust_rb_alignof(gid_t) * CHAR_BIT, + lttng_ust_is_signed_type(gid_t), + BYTE_ORDER, 10), + false, false), + vegid_get_size, + vegid_record, + vegid_get_value, + NULL, NULL); + int lttng_add_vegid_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(gid_t) * CHAR_BIT, - lttng_ust_rb_alignof(gid_t) * CHAR_BIT, - lttng_ust_is_signed_type(gid_t), - BYTE_ORDER, 10); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "vegid")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("vegid"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = vegid_get_size; - field->record = vegid_record; - field->get_value = vegid_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-veuid.c b/liblttng-ust/lttng-context-veuid.c index 506422e9..5c2a1d83 100644 --- a/liblttng-ust/lttng-context-veuid.c +++ b/liblttng-ust/lttng-context-veuid.c @@ -62,7 +62,7 @@ void lttng_context_veuid_reset(void) } static -size_t veuid_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t veuid_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -73,7 +73,7 @@ size_t veuid_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void veuid_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void veuid_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -84,49 +84,37 @@ void veuid_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void veuid_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void veuid_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.s64 = get_veuid(); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("veuid", + lttng_ust_static_type_integer(sizeof(uid_t) * CHAR_BIT, + lttng_ust_rb_alignof(uid_t) * CHAR_BIT, + lttng_ust_is_signed_type(uid_t), + BYTE_ORDER, 10), + false, false), + veuid_get_size, + veuid_record, + veuid_get_value, + NULL, NULL); + int lttng_add_veuid_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(uid_t) * CHAR_BIT, - lttng_ust_rb_alignof(uid_t) * CHAR_BIT, - lttng_ust_is_signed_type(uid_t), - BYTE_ORDER, 10); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "veuid")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("veuid"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = veuid_get_size; - field->record = veuid_record; - field->get_value = veuid_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-vgid.c b/liblttng-ust/lttng-context-vgid.c index 17026112..e43d5bc2 100644 --- a/liblttng-ust/lttng-context-vgid.c +++ b/liblttng-ust/lttng-context-vgid.c @@ -62,7 +62,7 @@ void lttng_context_vgid_reset(void) } static -size_t vgid_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t vgid_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -73,7 +73,7 @@ size_t vgid_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void vgid_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void vgid_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -84,49 +84,37 @@ void vgid_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void vgid_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void vgid_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.s64 = get_vgid(); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("vgid", + lttng_ust_static_type_integer(sizeof(gid_t) * CHAR_BIT, + lttng_ust_rb_alignof(gid_t) * CHAR_BIT, + lttng_ust_is_signed_type(gid_t), + BYTE_ORDER, 10), + false, false), + vgid_get_size, + vgid_record, + vgid_get_value, + NULL, NULL); + int lttng_add_vgid_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(gid_t) * CHAR_BIT, - lttng_ust_rb_alignof(gid_t) * CHAR_BIT, - lttng_ust_is_signed_type(gid_t), - BYTE_ORDER, 10); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "vgid")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("vgid"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = vgid_get_size; - field->record = vgid_record; - field->get_value = vgid_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-vpid.c b/liblttng-ust/lttng-context-vpid.c index 9f20d8cb..8bf4841e 100644 --- a/liblttng-ust/lttng-context-vpid.c +++ b/liblttng-ust/lttng-context-vpid.c @@ -46,7 +46,7 @@ void lttng_context_vpid_reset(void) } static -size_t vpid_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t vpid_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -57,7 +57,7 @@ size_t vpid_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void vpid_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void vpid_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -67,49 +67,37 @@ void vpid_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void vpid_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void vpid_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.s64 = wrapper_getvpid(); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("vpid", + lttng_ust_static_type_integer(sizeof(pid_t) * CHAR_BIT, + lttng_ust_rb_alignof(pid_t) * CHAR_BIT, + lttng_ust_is_signed_type(pid_t), + BYTE_ORDER, 10), + false, false), + vpid_get_size, + vpid_record, + vpid_get_value, + NULL, NULL); + int lttng_add_vpid_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(pid_t) * CHAR_BIT, - lttng_ust_rb_alignof(pid_t) * CHAR_BIT, - lttng_ust_is_signed_type(pid_t), - BYTE_ORDER, 10); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "vpid")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("vpid"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = vpid_get_size; - field->record = vpid_record; - field->get_value = vpid_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-vsgid.c b/liblttng-ust/lttng-context-vsgid.c index 387e931b..92785420 100644 --- a/liblttng-ust/lttng-context-vsgid.c +++ b/liblttng-ust/lttng-context-vsgid.c @@ -66,7 +66,7 @@ void lttng_context_vsgid_reset(void) } static -size_t vsgid_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t vsgid_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -77,7 +77,7 @@ size_t vsgid_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void vsgid_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void vsgid_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -88,49 +88,37 @@ void vsgid_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void vsgid_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void vsgid_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.s64 = get_vsgid(); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("vsgid", + lttng_ust_static_type_integer(sizeof(gid_t) * CHAR_BIT, + lttng_ust_rb_alignof(gid_t) * CHAR_BIT, + lttng_ust_is_signed_type(gid_t), + BYTE_ORDER, 10), + false, false), + vsgid_get_size, + vsgid_record, + vsgid_get_value, + NULL, NULL); + int lttng_add_vsgid_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(gid_t) * CHAR_BIT, - lttng_ust_rb_alignof(gid_t) * CHAR_BIT, - lttng_ust_is_signed_type(gid_t), - BYTE_ORDER, 10); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "vsgid")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("vsgid"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = vsgid_get_size; - field->record = vsgid_record; - field->get_value = vsgid_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-vsuid.c b/liblttng-ust/lttng-context-vsuid.c index f1fe8e21..fa7f3a10 100644 --- a/liblttng-ust/lttng-context-vsuid.c +++ b/liblttng-ust/lttng-context-vsuid.c @@ -66,7 +66,7 @@ void lttng_context_vsuid_reset(void) } static -size_t vsuid_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t vsuid_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -77,7 +77,7 @@ size_t vsuid_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void vsuid_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void vsuid_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -88,49 +88,37 @@ void vsuid_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void vsuid_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void vsuid_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.s64 = get_vsuid(); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("vsuid", + lttng_ust_static_type_integer(sizeof(uid_t) * CHAR_BIT, + lttng_ust_rb_alignof(uid_t) * CHAR_BIT, + lttng_ust_is_signed_type(uid_t), + BYTE_ORDER, 10), + false, false), + vsuid_get_size, + vsuid_record, + vsuid_get_value, + NULL, NULL); + int lttng_add_vsuid_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(uid_t) * CHAR_BIT, - lttng_ust_rb_alignof(uid_t) * CHAR_BIT, - lttng_ust_is_signed_type(uid_t), - BYTE_ORDER, 10); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "vsuid")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("vsuid"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = vsuid_get_size; - field->record = vsuid_record; - field->get_value = vsuid_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-vtid.c b/liblttng-ust/lttng-context-vtid.c index a7e7679b..3530d266 100644 --- a/liblttng-ust/lttng-context-vtid.c +++ b/liblttng-ust/lttng-context-vtid.c @@ -37,7 +37,7 @@ void lttng_context_vtid_reset(void) } static -size_t vtid_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t vtid_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -61,7 +61,7 @@ pid_t wrapper_getvtid(void) } static -void vtid_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void vtid_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -71,50 +71,38 @@ void vtid_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void vtid_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void vtid_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.s64 = wrapper_getvtid(); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("vtid", + lttng_ust_static_type_integer(sizeof(pid_t) * CHAR_BIT, + lttng_ust_rb_alignof(pid_t) * CHAR_BIT, + lttng_ust_is_signed_type(pid_t), + BYTE_ORDER, 10), + false, false), + vtid_get_size, + vtid_record, + vtid_get_value, + NULL, NULL); + int lttng_add_vtid_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(pid_t) * CHAR_BIT, - lttng_ust_rb_alignof(pid_t) * CHAR_BIT, - lttng_ust_is_signed_type(pid_t), - BYTE_ORDER, 10); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "vtid")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("vtid"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = vtid_get_size; - field->record = vtid_record; - field->get_value = vtid_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context-vuid.c b/liblttng-ust/lttng-context-vuid.c index d945e309..775f2cbf 100644 --- a/liblttng-ust/lttng-context-vuid.c +++ b/liblttng-ust/lttng-context-vuid.c @@ -62,7 +62,7 @@ void lttng_context_vuid_reset(void) } static -size_t vuid_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t vuid_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -73,7 +73,7 @@ size_t vuid_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void vuid_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void vuid_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -84,49 +84,37 @@ void vuid_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void vuid_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void vuid_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->u.s64 = get_vuid(); } +static const struct lttng_ust_ctx_field *ctx_field = lttng_ust_static_ctx_field( + lttng_ust_static_event_field("vuid", + lttng_ust_static_type_integer(sizeof(uid_t) * CHAR_BIT, + lttng_ust_rb_alignof(uid_t) * CHAR_BIT, + lttng_ust_is_signed_type(uid_t), + BYTE_ORDER, 10), + false, false), + vuid_get_size, + vuid_record, + vuid_get_value, + NULL, NULL); + int lttng_add_vuid_to_ctx(struct lttng_ust_ctx **ctx) { - struct lttng_ust_ctx_field *field; - struct lttng_ust_type_common *type; int ret; - type = lttng_ust_create_type_integer(sizeof(uid_t) * CHAR_BIT, - lttng_ust_rb_alignof(uid_t) * CHAR_BIT, - lttng_ust_is_signed_type(uid_t), - BYTE_ORDER, 10); - if (!type) - return -ENOMEM; - field = lttng_append_context(ctx); - if (!field) { - ret = -ENOMEM; - goto error_context; - } - if (lttng_find_context(*ctx, "vuid")) { + if (lttng_find_context(*ctx, ctx_field->event_field->name)) { ret = -EEXIST; goto error_find_context; } - field->event_field->name = strdup("vuid"); - if (!field->event_field->name) { - ret = -ENOMEM; - goto error_name; - } - field->event_field->type = type; - field->get_size = vuid_get_size; - field->record = vuid_record; - field->get_value = vuid_get_value; - lttng_context_update(*ctx); + ret = lttng_ust_context_append(ctx, ctx_field); + if (ret) + return ret; return 0; -error_name: error_find_context: - lttng_remove_context_field(ctx, field); -error_context: - lttng_ust_destroy_type(type); return ret; } diff --git a/liblttng-ust/lttng-context.c b/liblttng-ust/lttng-context.c index ca88bb1d..7e558067 100644 --- a/liblttng-ust/lttng-context.c +++ b/liblttng-ust/lttng-context.c @@ -32,6 +32,8 @@ int lttng_find_context(struct lttng_ust_ctx *ctx, const char *name) unsigned int i; const char *subname; + if (!ctx) + return 0; if (strncmp(name, "$ctx.", strlen("$ctx.")) == 0) { subname = name + strlen("$ctx."); } else { @@ -39,9 +41,9 @@ int lttng_find_context(struct lttng_ust_ctx *ctx, const char *name) } for (i = 0; i < ctx->nr_fields; i++) { /* Skip allocated (but non-initialized) contexts */ - if (!ctx->fields[i]->event_field->name) + if (!ctx->fields[i].event_field->name) continue; - if (!strcmp(ctx->fields[i]->event_field->name, subname)) + if (!strcmp(ctx->fields[i].event_field->name, subname)) return 1; } return 0; @@ -61,9 +63,9 @@ int lttng_get_context_index(struct lttng_ust_ctx *ctx, const char *name) } for (i = 0; i < ctx->nr_fields; i++) { /* Skip allocated (but non-initialized) contexts */ - if (!ctx->fields[i]->event_field->name) + if (!ctx->fields[i].event_field->name) continue; - if (!strcmp(ctx->fields[i]->event_field->name, subname)) + if (!strcmp(ctx->fields[i].event_field->name, subname)) return i; } return -1; @@ -75,9 +77,9 @@ static int lttng_find_context_provider(struct lttng_ust_ctx *ctx, const char *na for (i = 0; i < ctx->nr_fields; i++) { /* Skip allocated (but non-initialized) contexts */ - if (!ctx->fields[i]->event_field->name) + if (!ctx->fields[i].event_field->name) continue; - if (!strncmp(ctx->fields[i]->event_field->name, name, + if (!strncmp(ctx->fields[i].event_field->name, name, strlen(name))) return 1; } @@ -86,10 +88,10 @@ static int lttng_find_context_provider(struct lttng_ust_ctx *ctx, const char *na /* * Note: as we append context information, the pointer location may change. - * lttng_add_context leaves the new last context initialized to NULL. + * lttng_ust_context_add_field leaves the new last context initialized to NULL. */ static -int lttng_add_context(struct lttng_ust_ctx **ctx_p) +int lttng_ust_context_add_field(struct lttng_ust_ctx **ctx_p) { struct lttng_ust_ctx *ctx; @@ -97,18 +99,17 @@ int lttng_add_context(struct lttng_ust_ctx **ctx_p) *ctx_p = zmalloc(sizeof(struct lttng_ust_ctx)); if (!*ctx_p) return -ENOMEM; - (*ctx_p)->struct_size = sizeof(struct lttng_ust_ctx); (*ctx_p)->largest_align = 1; } ctx = *ctx_p; if (ctx->nr_fields + 1 > ctx->allocated_fields) { - struct lttng_ust_ctx_field **new_fields; + struct lttng_ust_ctx_field *new_fields; ctx->allocated_fields = max_t(size_t, 1, 2 * ctx->allocated_fields); new_fields = zmalloc(ctx->allocated_fields * sizeof(*new_fields)); if (!new_fields) return -ENOMEM; - /* Copy pointers */ + /* Copy elements */ if (ctx->fields) memcpy(new_fields, ctx->fields, sizeof(*ctx->fields) * ctx->nr_fields); free(ctx->fields); @@ -118,79 +119,7 @@ int lttng_add_context(struct lttng_ust_ctx **ctx_p) return 0; } -struct lttng_ust_ctx_field *lttng_append_context(struct lttng_ust_ctx **ctx_p) -{ - struct lttng_ust_ctx_field *field; - int ret; - - field = zmalloc(sizeof(struct lttng_ust_ctx_field)); - if (!field) - goto error_alloc_field; - field->struct_size = sizeof(struct lttng_ust_ctx_field); - field->event_field = zmalloc(sizeof(struct lttng_ust_event_field)); - if (!field->event_field) - goto error_alloc_event_field; - field->event_field->struct_size = sizeof(struct lttng_ust_event_field); - - ret = lttng_add_context(ctx_p); - if (ret) - goto error_add_context; - (*ctx_p)->fields[(*ctx_p)->nr_fields - 1] = field; - return field; - -error_add_context: - free(field->event_field); -error_alloc_event_field: - free(field); -error_alloc_field: - return NULL; -} - -/* - * Takes ownership of @f on success. - */ -int lttng_context_add_rcu(struct lttng_ust_ctx **ctx_p, - struct lttng_ust_ctx_field *f) -{ - struct lttng_ust_ctx *old_ctx = *ctx_p, *new_ctx = NULL; - struct lttng_ust_ctx_field **new_fields = NULL; - int ret; - - if (old_ctx) { - new_ctx = zmalloc(sizeof(struct lttng_ust_ctx)); - if (!new_ctx) - return -ENOMEM; - new_ctx->struct_size = sizeof(struct lttng_ust_ctx); - *new_ctx = *old_ctx; - new_fields = zmalloc(new_ctx->allocated_fields * sizeof(*new_fields)); - if (!new_fields) { - free(new_ctx); - return -ENOMEM; - } - /* Copy pointers */ - memcpy(new_fields, old_ctx->fields, - sizeof(*old_ctx->fields) * old_ctx->nr_fields); - new_ctx->fields = new_fields; - } - ret = lttng_add_context(&new_ctx); - if (ret) { - free(new_fields); - free(new_ctx); - return ret; - } - /* Taking ownership of f. */ - (*ctx_p)->fields[(*ctx_p)->nr_fields - 1] = f; - lttng_context_update(new_ctx); - lttng_ust_rcu_assign_pointer(*ctx_p, new_ctx); - lttng_ust_urcu_synchronize_rcu(); - if (old_ctx) { - free(old_ctx->fields); - free(old_ctx); - } - return 0; -} - -static size_t get_type_max_align(struct lttng_ust_type_common *type) +static size_t get_type_max_align(const struct lttng_ust_type_common *type) { switch (type->type) { case lttng_ust_type_integer: @@ -211,7 +140,7 @@ static size_t get_type_max_align(struct lttng_ust_type_common *type) { unsigned int i; size_t field_align = 0; - struct lttng_ust_type_struct *struct_type = lttng_ust_get_type_struct(type); + const struct lttng_ust_type_struct *struct_type = lttng_ust_get_type_struct(type); for (i = 0; i < struct_type->nr_fields; i++) { field_align = max_t(size_t, @@ -230,6 +159,7 @@ static size_t get_type_max_align(struct lttng_ust_type_common *type) * lttng_context_update() should be called at least once between context * modification and trace start. */ +static void lttng_context_update(struct lttng_ust_ctx *ctx) { int i; @@ -238,28 +168,63 @@ void lttng_context_update(struct lttng_ust_ctx *ctx) for (i = 0; i < ctx->nr_fields; i++) { size_t field_align = 8; - field_align = get_type_max_align(ctx->fields[i]->event_field->type); + field_align = get_type_max_align(ctx->fields[i].event_field->type); largest_align = max_t(size_t, largest_align, field_align); } ctx->largest_align = largest_align >> 3; /* bits to bytes */ } -/* - * Remove last context field. - */ -void lttng_remove_context_field(struct lttng_ust_ctx **ctx_p, - struct lttng_ust_ctx_field *field) +int lttng_ust_context_append_rcu(struct lttng_ust_ctx **ctx_p, + const struct lttng_ust_ctx_field *f) { - struct lttng_ust_ctx *ctx; + struct lttng_ust_ctx *old_ctx = *ctx_p, *new_ctx = NULL; + struct lttng_ust_ctx_field *new_fields = NULL; + int ret; - ctx = *ctx_p; - ctx->nr_fields--; - assert(ctx->fields[ctx->nr_fields] == field); - lttng_ust_destroy_type(field->event_field->type); - free((char *) field->event_field->name); - free(field->event_field); - free(field); - ctx->fields[ctx->nr_fields] = NULL; + if (old_ctx) { + new_ctx = zmalloc(sizeof(struct lttng_ust_ctx)); + if (!new_ctx) + return -ENOMEM; + *new_ctx = *old_ctx; + new_fields = zmalloc(new_ctx->allocated_fields * sizeof(*new_fields)); + if (!new_fields) { + free(new_ctx); + return -ENOMEM; + } + /* Copy elements */ + memcpy(new_fields, old_ctx->fields, + sizeof(*old_ctx->fields) * old_ctx->nr_fields); + new_ctx->fields = new_fields; + } + ret = lttng_ust_context_add_field(&new_ctx); + if (ret) { + free(new_fields); + free(new_ctx); + return ret; + } + /* Taking ownership of f. */ + new_ctx->fields[new_ctx->nr_fields - 1] = *f; + lttng_context_update(new_ctx); + lttng_ust_rcu_assign_pointer(*ctx_p, new_ctx); + lttng_ust_urcu_synchronize_rcu(); + if (old_ctx) { + free(old_ctx->fields); + free(old_ctx); + } + return 0; +} + +int lttng_ust_context_append(struct lttng_ust_ctx **ctx_p, + const struct lttng_ust_ctx_field *f) +{ + int ret; + + ret = lttng_ust_context_add_field(ctx_p); + if (ret) + return ret; + (*ctx_p)->fields[(*ctx_p)->nr_fields - 1] = *f; + lttng_context_update(*ctx_p); + return 0; } void lttng_destroy_context(struct lttng_ust_ctx *ctx) @@ -269,12 +234,8 @@ void lttng_destroy_context(struct lttng_ust_ctx *ctx) if (!ctx) return; for (i = 0; i < ctx->nr_fields; i++) { - if (ctx->fields[i]->destroy) - ctx->fields[i]->destroy(ctx->fields[i]); - lttng_ust_destroy_type(ctx->fields[i]->event_field->type); - free((char *) ctx->fields[i]->event_field->name); - free(ctx->fields[i]->event_field); - free(ctx->fields[i]); + if (ctx->fields[i].destroy) + ctx->fields[i].destroy(&ctx->fields[i]); } free(ctx->fields); free(ctx); @@ -294,16 +255,15 @@ void lttng_destroy_context(struct lttng_ust_ctx *ctx) */ int lttng_ust_context_set_provider_rcu(struct lttng_ust_ctx **_ctx, const char *name, - size_t (*get_size)(struct lttng_ust_ctx_field *field, size_t offset), - void (*record)(struct lttng_ust_ctx_field *field, - struct lttng_ust_lib_ring_buffer_ctx *ctx, + size_t (*get_size)(void *priv, size_t offset), + void (*record)(void *priv, struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan), - void (*get_value)(struct lttng_ust_ctx_field *field, - struct lttng_ust_ctx_value *value)) + void (*get_value)(void *priv, struct lttng_ust_ctx_value *value), + void *priv) { int i, ret; struct lttng_ust_ctx *ctx = *_ctx, *new_ctx; - struct lttng_ust_ctx_field **new_fields; + struct lttng_ust_ctx_field *new_fields; if (!ctx || !lttng_find_context_provider(ctx, name)) return 0; @@ -313,23 +273,23 @@ int lttng_ust_context_set_provider_rcu(struct lttng_ust_ctx **_ctx, new_ctx = zmalloc(sizeof(*new_ctx)); if (!new_ctx) return -ENOMEM; - new_ctx->struct_size = sizeof(*new_ctx); *new_ctx = *ctx; new_fields = zmalloc(sizeof(*new_fields) * ctx->allocated_fields); if (!new_fields) { ret = -ENOMEM; goto field_error; } - /* Copy pointers */ + /* Copy elements */ memcpy(new_fields, ctx->fields, sizeof(*new_fields) * ctx->allocated_fields); for (i = 0; i < ctx->nr_fields; i++) { - if (strncmp(new_fields[i]->event_field->name, + if (strncmp(new_fields[i].event_field->name, name, strlen(name)) != 0) continue; - new_fields[i]->get_size = get_size; - new_fields[i]->record = record; - new_fields[i]->get_value = get_value; + new_fields[i].get_size = get_size; + new_fields[i].record = record; + new_fields[i].get_value = get_value; + new_fields[i].priv = priv; } new_ctx->fields = new_fields; lttng_ust_rcu_assign_pointer(*_ctx, new_ctx); diff --git a/liblttng-ust/lttng-events.c b/liblttng-ust/lttng-events.c index 16fb9f44..b61a2293 100644 --- a/liblttng-ust/lttng-events.c +++ b/liblttng-ust/lttng-events.c @@ -268,7 +268,7 @@ static void register_event(struct lttng_ust_event_common *event) { int ret; - struct lttng_ust_event_desc *desc; + const struct lttng_ust_event_desc *desc; char name[LTTNG_UST_ABI_SYM_NAME_LEN]; assert(event->priv->registered == 0); @@ -286,7 +286,7 @@ static void unregister_event(struct lttng_ust_event_common *event) { int ret; - struct lttng_ust_event_desc *desc; + const struct lttng_ust_event_desc *desc; char name[LTTNG_UST_ABI_SYM_NAME_LEN]; assert(event->priv->registered == 1); @@ -420,7 +420,7 @@ void lttng_enabler_destroy(struct lttng_enabler *enabler) } static -int lttng_enum_create(struct lttng_ust_enum_desc *desc, +int lttng_enum_create(const struct lttng_ust_enum_desc *desc, struct lttng_ust_session *session) { const char *enum_name = desc->name; @@ -478,13 +478,13 @@ exist: } static -int lttng_create_enum_check(struct lttng_ust_type_common *type, +int lttng_create_enum_check(const struct lttng_ust_type_common *type, struct lttng_ust_session *session) { switch (type->type) { case lttng_ust_type_enum: { - struct lttng_ust_enum_desc *enum_desc; + const struct lttng_ust_enum_desc *enum_desc; int ret; enum_desc = lttng_ust_get_type_enum(type)->desc; @@ -497,8 +497,8 @@ int lttng_create_enum_check(struct lttng_ust_type_common *type, } case lttng_ust_type_dynamic: { - struct lttng_ust_event_field *tag_field_generic; - struct lttng_ust_enum_desc *enum_desc; + const struct lttng_ust_event_field *tag_field_generic; + const struct lttng_ust_enum_desc *enum_desc; int ret; tag_field_generic = lttng_ust_dynamic_type_tag_field(); @@ -519,7 +519,7 @@ int lttng_create_enum_check(struct lttng_ust_type_common *type, static int lttng_create_all_event_enums(size_t nr_fields, - struct lttng_ust_event_field **event_fields, + const struct lttng_ust_event_field **event_fields, struct lttng_ust_session *session) { size_t i; @@ -527,7 +527,7 @@ int lttng_create_all_event_enums(size_t nr_fields, /* For each field, ensure enum is part of the session. */ for (i = 0; i < nr_fields; i++) { - struct lttng_ust_type_common *type = event_fields[i]->type; + const struct lttng_ust_type_common *type = event_fields[i]->type; ret = lttng_create_enum_check(type, session); if (ret) @@ -538,7 +538,7 @@ int lttng_create_all_event_enums(size_t nr_fields, static int lttng_create_all_ctx_enums(size_t nr_fields, - struct lttng_ust_ctx_field **ctx_fields, + struct lttng_ust_ctx_field *ctx_fields, struct lttng_ust_session *session) { size_t i; @@ -546,7 +546,7 @@ int lttng_create_all_ctx_enums(size_t nr_fields, /* For each field, ensure enum is part of the session. */ for (i = 0; i < nr_fields; i++) { - struct lttng_ust_type_common *type = ctx_fields[i]->event_field->type; + const struct lttng_ust_type_common *type = ctx_fields[i].event_field->type; ret = lttng_create_enum_check(type, session); if (ret) @@ -593,7 +593,7 @@ int lttng_session_enable(struct lttng_ust_session *session) */ cds_list_for_each_entry(chan, &session->priv->chan_head, node) { struct lttng_ust_ctx *ctx; - struct lttng_ust_ctx_field **fields = NULL; + struct lttng_ust_ctx_field *fields = NULL; size_t nr_fields = 0; uint32_t chan_id; @@ -697,7 +697,7 @@ static inline struct cds_hlist_head *borrow_hash_table_bucket( struct cds_hlist_head *hash_table, unsigned int hash_table_size, - struct lttng_ust_event_desc *desc) + const struct lttng_ust_event_desc *desc) { char name[LTTNG_UST_ABI_SYM_NAME_LEN]; size_t name_len; @@ -714,7 +714,7 @@ struct cds_hlist_head *borrow_hash_table_bucket( * Supports event creation while tracing session is active. */ static -int lttng_event_recorder_create(struct lttng_ust_event_desc *desc, +int lttng_event_recorder_create(const struct lttng_ust_event_desc *desc, struct lttng_ust_channel_buffer *chan) { char name[LTTNG_UST_ABI_SYM_NAME_LEN]; @@ -826,7 +826,7 @@ socket_error: } static -int lttng_event_notifier_create(struct lttng_ust_event_desc *desc, +int lttng_event_notifier_create(const struct lttng_ust_event_desc *desc, uint64_t token, uint64_t error_counter_index, struct lttng_event_notifier_group *event_notifier_group) { @@ -899,7 +899,7 @@ error: } static -int lttng_desc_match_star_glob_enabler(struct lttng_ust_event_desc *desc, +int lttng_desc_match_star_glob_enabler(const struct lttng_ust_event_desc *desc, struct lttng_enabler *enabler) { char name[LTTNG_UST_ABI_SYM_NAME_LEN]; @@ -924,7 +924,7 @@ int lttng_desc_match_star_glob_enabler(struct lttng_ust_event_desc *desc, } static -int lttng_desc_match_event_enabler(struct lttng_ust_event_desc *desc, +int lttng_desc_match_event_enabler(const struct lttng_ust_event_desc *desc, struct lttng_enabler *enabler) { char name[LTTNG_UST_ABI_SYM_NAME_LEN]; @@ -948,7 +948,7 @@ int lttng_desc_match_event_enabler(struct lttng_ust_event_desc *desc, } static -int lttng_desc_match_enabler(struct lttng_ust_event_desc *desc, +int lttng_desc_match_enabler(const struct lttng_ust_event_desc *desc, struct lttng_enabler *enabler) { switch (enabler->format_type) { @@ -1042,8 +1042,8 @@ static void lttng_create_event_recorder_if_missing(struct lttng_event_enabler *event_enabler) { struct lttng_ust_session *session = event_enabler->chan->parent->session; - struct lttng_ust_probe_desc *probe_desc; - struct lttng_ust_event_desc *desc; + struct lttng_ust_registered_probe *reg_probe; + const struct lttng_ust_event_desc *desc; struct lttng_ust_event_recorder_private *event_recorder_priv; int i; struct cds_list_head *probe_list; @@ -1054,7 +1054,9 @@ void lttng_create_event_recorder_if_missing(struct lttng_event_enabler *event_en * our enabler, create an associated lttng_event if not * already present. */ - cds_list_for_each_entry(probe_desc, probe_list, head) { + cds_list_for_each_entry(reg_probe, probe_list, head) { + const struct lttng_ust_probe_desc *probe_desc = reg_probe->desc; + for (i = 0; i < probe_desc->nr_events; i++) { int ret; bool found = false; @@ -1096,7 +1098,7 @@ void lttng_create_event_recorder_if_missing(struct lttng_event_enabler *event_en } static -void probe_provider_event_for_each(struct lttng_ust_probe_desc *provider_desc, +void probe_provider_event_for_each(const struct lttng_ust_probe_desc *provider_desc, void (*event_func)(struct lttng_ust_event_common *event)) { struct cds_hlist_node *node, *tmp_node; @@ -1111,7 +1113,7 @@ void probe_provider_event_for_each(struct lttng_ust_probe_desc *provider_desc, * sessions to queue the unregistration of the events. */ for (i = 0; i < provider_desc->nr_events; i++) { - struct lttng_ust_event_desc *event_desc; + const struct lttng_ust_event_desc *event_desc; struct lttng_event_notifier_group *event_notifier_group; struct lttng_ust_event_recorder_private *event_recorder_priv; struct lttng_ust_event_notifier_private *event_notifier_priv; @@ -1178,8 +1180,8 @@ void _event_enum_destroy(struct lttng_ust_event_common *event) /* Destroy enums of the current event. */ for (i = 0; i < event_recorder->parent->priv->desc->nr_fields; i++) { - struct lttng_ust_enum_desc *enum_desc; - struct lttng_ust_event_field *field; + const struct lttng_ust_enum_desc *enum_desc; + const struct lttng_ust_event_field *field; struct lttng_enum *curr_enum; field = event_recorder->parent->priv->desc->fields[i]; @@ -1213,7 +1215,7 @@ void _event_enum_destroy(struct lttng_ust_event_common *event) * ust_lock held. */ void lttng_probe_provider_unregister_events( - struct lttng_ust_probe_desc *provider_desc) + const struct lttng_ust_probe_desc *provider_desc) { /* * Iterate over all events in the probe provider descriptions and sessions @@ -1751,7 +1753,7 @@ void lttng_session_sync_event_enablers(struct lttng_ust_session *session) /* Support for event notifier is introduced by probe provider major version 2. */ static -bool lttng_ust_probe_supports_event_notifier(struct lttng_ust_probe_desc *probe_desc) +bool lttng_ust_probe_supports_event_notifier(const struct lttng_ust_probe_desc *probe_desc) { return probe_desc->major >= 2; } @@ -1761,17 +1763,19 @@ void lttng_create_event_notifier_if_missing( struct lttng_event_notifier_enabler *event_notifier_enabler) { struct lttng_event_notifier_group *event_notifier_group = event_notifier_enabler->group; - struct lttng_ust_probe_desc *probe_desc; + struct lttng_ust_registered_probe *reg_probe; struct cds_list_head *probe_list; int i; probe_list = lttng_get_probe_list_head(); - cds_list_for_each_entry(probe_desc, probe_list, head) { + cds_list_for_each_entry(reg_probe, probe_list, head) { + const struct lttng_ust_probe_desc *probe_desc = reg_probe->desc; + for (i = 0; i < probe_desc->nr_events; i++) { int ret; bool found = false; - struct lttng_ust_event_desc *desc; + const struct lttng_ust_event_desc *desc; struct lttng_ust_event_notifier_private *event_notifier_priv; struct cds_hlist_head *head; struct cds_hlist_node *node; @@ -1998,12 +2002,11 @@ void lttng_session_lazy_sync_event_enablers(struct lttng_ust_session *session) * context (either app context callbacks, or dummy callbacks). */ void lttng_ust_context_set_session_provider(const char *name, - size_t (*get_size)(struct lttng_ust_ctx_field *field, size_t offset), - void (*record)(struct lttng_ust_ctx_field *field, - struct lttng_ust_lib_ring_buffer_ctx *ctx, + size_t (*get_size)(void *priv, size_t offset), + void (*record)(void *priv, struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan), - void (*get_value)(struct lttng_ust_ctx_field *field, - struct lttng_ust_ctx_value *value)) + void (*get_value)(void *priv, struct lttng_ust_ctx_value *value), + void *priv) { struct lttng_ust_session_private *session_priv; @@ -2013,18 +2016,18 @@ void lttng_ust_context_set_session_provider(const char *name, int ret; ret = lttng_ust_context_set_provider_rcu(&session_priv->ctx, - name, get_size, record, get_value); + name, get_size, record, get_value, priv); if (ret) abort(); cds_list_for_each_entry(chan, &session_priv->chan_head, node) { ret = lttng_ust_context_set_provider_rcu(&chan->ctx, - name, get_size, record, get_value); + name, get_size, record, get_value, priv); if (ret) abort(); } cds_list_for_each_entry(event_recorder_priv, &session_priv->events_head, node) { ret = lttng_ust_context_set_provider_rcu(&event_recorder_priv->ctx, - name, get_size, record, get_value); + name, get_size, record, get_value, priv); if (ret) abort(); } @@ -2039,12 +2042,11 @@ void lttng_ust_context_set_session_provider(const char *name, * context (either app context callbacks, or dummy callbacks). */ void lttng_ust_context_set_event_notifier_group_provider(const char *name, - size_t (*get_size)(struct lttng_ust_ctx_field *field, size_t offset), - void (*record)(struct lttng_ust_ctx_field *field, - struct lttng_ust_lib_ring_buffer_ctx *ctx, + size_t (*get_size)(void *priv, size_t offset), + void (*record)(void *priv, struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan), - void (*get_value)(struct lttng_ust_ctx_field *field, - struct lttng_ust_ctx_value *value)) + void (*get_value)(void *priv, struct lttng_ust_ctx_value *value), + void *priv) { struct lttng_event_notifier_group *event_notifier_group; @@ -2053,7 +2055,7 @@ void lttng_ust_context_set_event_notifier_group_provider(const char *name, ret = lttng_ust_context_set_provider_rcu( &event_notifier_group->ctx, - name, get_size, record, get_value); + name, get_size, record, get_value, priv); if (ret) abort(); } diff --git a/liblttng-ust/lttng-probes.c b/liblttng-ust/lttng-probes.c index 95a1c12b..03fbe36b 100644 --- a/liblttng-ust/lttng-probes.c +++ b/liblttng-ust/lttng-probes.c @@ -45,7 +45,7 @@ static int lazy_nesting; * right probe, and that the resulting name is not too long. */ static -bool check_event_provider(struct lttng_ust_probe_desc *probe_desc) +bool check_event_provider(const struct lttng_ust_probe_desc *probe_desc) { int i; @@ -70,9 +70,9 @@ bool check_event_provider(struct lttng_ust_probe_desc *probe_desc) * Called under ust lock. */ static -void lttng_lazy_probe_register(struct lttng_ust_probe_desc *desc) +void lttng_lazy_probe_register(struct lttng_ust_registered_probe *reg_probe) { - struct lttng_ust_probe_desc *iter; + struct lttng_ust_registered_probe *iter; struct cds_list_head *probe_list; /* @@ -87,18 +87,18 @@ void lttng_lazy_probe_register(struct lttng_ust_probe_desc *desc) */ probe_list = &_probe_list; cds_list_for_each_entry_reverse(iter, probe_list, head) { - BUG_ON(iter == desc); /* Should never be in the list twice */ - if (iter < desc) { + BUG_ON(iter == reg_probe); /* Should never be in the list twice */ + if (iter < reg_probe) { /* We belong to the location right after iter. */ - cds_list_add(&desc->head, &iter->head); - goto desc_added; + cds_list_add(®_probe->head, &iter->head); + goto probe_added; } } /* We should be added at the head of the list */ - cds_list_add(&desc->head, probe_list); -desc_added: + cds_list_add(®_probe->head, probe_list); +probe_added: DBG("just registered probe %s containing %u events", - desc->provider_name, desc->nr_events); + reg_probe->desc->provider_name, reg_probe->desc->nr_events); } /* @@ -107,7 +107,7 @@ desc_added: static void fixup_lazy_probes(void) { - struct lttng_ust_probe_desc *iter, *tmp; + struct lttng_ust_registered_probe *iter, *tmp; int ret; lazy_nesting++; @@ -133,7 +133,7 @@ struct cds_list_head *lttng_get_probe_list_head(void) } static -int check_provider_version(struct lttng_ust_probe_desc *desc) +int check_provider_version(const struct lttng_ust_probe_desc *desc) { /* * Check tracepoint provider version compatibility. @@ -161,10 +161,9 @@ int check_provider_version(struct lttng_ust_probe_desc *desc) } } - -int lttng_ust_probe_register(struct lttng_ust_probe_desc *desc) +struct lttng_ust_registered_probe *lttng_ust_probe_register(const struct lttng_ust_probe_desc *desc) { - int ret = 0; + struct lttng_ust_registered_probe *reg_probe = NULL; lttng_ust_fixup_tls(); @@ -173,14 +172,19 @@ int lttng_ust_probe_register(struct lttng_ust_probe_desc *desc) * on caller. The version check just prints an error. */ if (!check_provider_version(desc)) - return 0; + return NULL; if (!check_event_provider(desc)) - return 0; + return NULL; ust_lock_nocheck(); - cds_list_add(&desc->lazy_init_head, &lazy_probe_init); - desc->lazy = 1; + reg_probe = zmalloc(sizeof(struct lttng_ust_registered_probe)); + if (!reg_probe) + goto end; + reg_probe->desc = desc; + cds_list_add(®_probe->lazy_init_head, &lazy_probe_init); + reg_probe->lazy = 1; + DBG("adding probe %s containing %u events to lazy registration list", desc->provider_name, desc->nr_events); /* @@ -192,28 +196,30 @@ int lttng_ust_probe_register(struct lttng_ust_probe_desc *desc) fixup_lazy_probes(); lttng_fix_pending_event_notifiers(); - +end: ust_unlock(); - return ret; + return reg_probe; } -void lttng_ust_probe_unregister(struct lttng_ust_probe_desc *desc) +void lttng_ust_probe_unregister(struct lttng_ust_registered_probe *reg_probe) { lttng_ust_fixup_tls(); - if (!check_provider_version(desc)) + if (!reg_probe) + return; + if (!check_provider_version(reg_probe->desc)) return; ust_lock_nocheck(); - if (!desc->lazy) - cds_list_del(&desc->head); + if (!reg_probe->lazy) + cds_list_del(®_probe->head); else - cds_list_del(&desc->lazy_init_head); - - lttng_probe_provider_unregister_events(desc); - DBG("just unregistered probes of provider %s", desc->provider_name); + cds_list_del(®_probe->lazy_init_head); + lttng_probe_provider_unregister_events(reg_probe->desc); + DBG("just unregistered probes of provider %s", reg_probe->desc->provider_name); ust_unlock(); + free(reg_probe); } void lttng_probes_prune_event_list(struct lttng_ust_tracepoint_list *list) @@ -231,13 +237,15 @@ void lttng_probes_prune_event_list(struct lttng_ust_tracepoint_list *list) */ int lttng_probes_get_event_list(struct lttng_ust_tracepoint_list *list) { - struct lttng_ust_probe_desc *probe_desc; - int i; + struct lttng_ust_registered_probe *reg_probe; struct cds_list_head *probe_list; + int i; probe_list = lttng_get_probe_list_head(); CDS_INIT_LIST_HEAD(&list->head); - cds_list_for_each_entry(probe_desc, probe_list, head) { + cds_list_for_each_entry(reg_probe, probe_list, head) { + const struct lttng_ust_probe_desc *probe_desc = reg_probe->desc; + for (i = 0; i < probe_desc->nr_events; i++) { const struct lttng_ust_event_desc *event_desc = probe_desc->event_desc[i]; @@ -305,13 +313,15 @@ void lttng_probes_prune_field_list(struct lttng_ust_field_list *list) */ int lttng_probes_get_field_list(struct lttng_ust_field_list *list) { - struct lttng_ust_probe_desc *probe_desc; - int i; + struct lttng_ust_registered_probe *reg_probe; struct cds_list_head *probe_list; + int i; probe_list = lttng_get_probe_list_head(); CDS_INIT_LIST_HEAD(&list->head); - cds_list_for_each_entry(probe_desc, probe_list, head) { + cds_list_for_each_entry(reg_probe, probe_list, head) { + const struct lttng_ust_probe_desc *probe_desc = reg_probe->desc; + for (i = 0; i < probe_desc->nr_events; i++) { const struct lttng_ust_event_desc *event_desc = probe_desc->event_desc[i]; diff --git a/liblttng-ust/lttng-ring-buffer-client-template.h b/liblttng-ust/lttng-ring-buffer-client-template.h index d4f25fcc..eee49d63 100644 --- a/liblttng-ust/lttng-ring-buffer-client-template.h +++ b/liblttng-ust/lttng-ring-buffer-client-template.h @@ -115,9 +115,9 @@ void ctx_get_struct_size(struct lttng_ust_ctx *ctx, size_t *ctx_len, } for (i = 0; i < ctx->nr_fields; i++) { if (mode == APP_CTX_ENABLED) { - offset += ctx->fields[i]->get_size(ctx->fields[i], offset); + offset += ctx->fields[i].get_size(&ctx->fields[i], offset); } else { - if (lttng_context_is_app(ctx->fields[i]->event_field->name)) { + if (lttng_context_is_app(ctx->fields[i].event_field->name)) { /* * Before UST 2.8, we cannot use the * application context, because we @@ -128,9 +128,9 @@ void ctx_get_struct_size(struct lttng_ust_ctx *ctx, size_t *ctx_len, * concurrently with application context * register/unregister. */ - offset += lttng_ust_dummy_get_size(ctx->fields[i], offset); + offset += lttng_ust_dummy_get_size(&ctx->fields[i], offset); } else { - offset += ctx->fields[i]->get_size(ctx->fields[i], offset); + offset += ctx->fields[i].get_size(&ctx->fields[i], offset); } } } @@ -150,9 +150,9 @@ void ctx_record(struct lttng_ust_lib_ring_buffer_ctx *bufctx, lttng_ust_lib_ring_buffer_align_ctx(bufctx, ctx->largest_align); for (i = 0; i < ctx->nr_fields; i++) { if (mode == APP_CTX_ENABLED) { - ctx->fields[i]->record(ctx->fields[i], bufctx, chan); + ctx->fields[i].record(&ctx->fields[i], bufctx, chan); } else { - if (lttng_context_is_app(ctx->fields[i]->event_field->name)) { + if (lttng_context_is_app(ctx->fields[i].event_field->name)) { /* * Before UST 2.8, we cannot use the * application context, because we @@ -163,9 +163,9 @@ void ctx_record(struct lttng_ust_lib_ring_buffer_ctx *bufctx, * concurrently with application context * register/unregister. */ - lttng_ust_dummy_record(ctx->fields[i], bufctx, chan); + lttng_ust_dummy_record(&ctx->fields[i], bufctx, chan); } else { - ctx->fields[i]->record(ctx->fields[i], bufctx, chan); + ctx->fields[i].record(&ctx->fields[i], bufctx, chan); } } } diff --git a/liblttng-ust/lttng-tracer-core.h b/liblttng-ust/lttng-tracer-core.h index 669e877d..7714dbf4 100644 --- a/liblttng-ust/lttng-tracer-core.h +++ b/liblttng-ust/lttng-tracer-core.h @@ -87,16 +87,14 @@ void lttng_ust_sockinfo_session_enabled(void *owner) ssize_t lttng_ust_read(int fd, void *buf, size_t len) __attribute__((visibility("hidden"))); -size_t lttng_ust_dummy_get_size(struct lttng_ust_ctx_field *field, size_t offset) +size_t lttng_ust_dummy_get_size(void *priv, size_t offset) __attribute__((visibility("hidden"))); -void lttng_ust_dummy_record(struct lttng_ust_ctx_field *field, - struct lttng_ust_lib_ring_buffer_ctx *ctx, +void lttng_ust_dummy_record(void *priv, struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) __attribute__((visibility("hidden"))); -void lttng_ust_dummy_get_value(struct lttng_ust_ctx_field *field, - struct lttng_ust_ctx_value *value) +void lttng_ust_dummy_get_value(void *priv, struct lttng_ust_ctx_value *value) __attribute__((visibility("hidden"))); void lttng_event_notifier_notification_send( diff --git a/liblttng-ust/lttng-ust-dynamic-type.c b/liblttng-ust/lttng-ust-dynamic-type.c index c94d6cc4..30128699 100644 --- a/liblttng-ust/lttng-ust-dynamic-type.c +++ b/liblttng-ust/lttng-ust-dynamic-type.c @@ -31,7 +31,7 @@ .string = (_string), \ }), -static struct lttng_ust_enum_entry *dt_enum[_NR_LTTNG_UST_DYNAMIC_TYPES] = { +static const struct lttng_ust_enum_entry *dt_enum[_NR_LTTNG_UST_DYNAMIC_TYPES] = { [LTTNG_UST_DYNAMIC_TYPE_NONE] = ctf_enum_value("_none", 0) [LTTNG_UST_DYNAMIC_TYPE_S8] = ctf_enum_value("_int8", 1) [LTTNG_UST_DYNAMIC_TYPE_S16] = ctf_enum_value("_int16", 2) @@ -52,8 +52,8 @@ static struct lttng_ust_enum_desc dt_enum_desc = { .nr_entries = LTTNG_ARRAY_SIZE(dt_enum), }; -struct lttng_ust_event_field *dt_var_fields[_NR_LTTNG_UST_DYNAMIC_TYPES] = { - [LTTNG_UST_DYNAMIC_TYPE_NONE] = __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { +const struct lttng_ust_event_field *dt_var_fields[_NR_LTTNG_UST_DYNAMIC_TYPES] = { + [LTTNG_UST_DYNAMIC_TYPE_NONE] = __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { .struct_size = sizeof(struct lttng_ust_event_field), .name = "none", .type = (struct lttng_ust_type_common *) __LTTNG_COMPOUND_LITERAL(struct lttng_ust_type_struct, { @@ -66,67 +66,67 @@ struct lttng_ust_event_field *dt_var_fields[_NR_LTTNG_UST_DYNAMIC_TYPES] = { }), .nowrite = 0, }), - [LTTNG_UST_DYNAMIC_TYPE_S8] = __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { + [LTTNG_UST_DYNAMIC_TYPE_S8] = __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { .struct_size = sizeof(struct lttng_ust_event_field), .name = "int8", .type = lttng_ust_type_integer_define(int8_t, BYTE_ORDER, 10), .nowrite = 0, }), - [LTTNG_UST_DYNAMIC_TYPE_S16] = __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { + [LTTNG_UST_DYNAMIC_TYPE_S16] = __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { .struct_size = sizeof(struct lttng_ust_event_field), .name = "int16", .type = lttng_ust_type_integer_define(int16_t, BYTE_ORDER, 10), .nowrite = 0, }), - [LTTNG_UST_DYNAMIC_TYPE_S32] = __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { + [LTTNG_UST_DYNAMIC_TYPE_S32] = __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { .struct_size = sizeof(struct lttng_ust_event_field), .name = "int32", .type = lttng_ust_type_integer_define(int32_t, BYTE_ORDER, 10), .nowrite = 0, }), - [LTTNG_UST_DYNAMIC_TYPE_S64] = __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { + [LTTNG_UST_DYNAMIC_TYPE_S64] = __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { .struct_size = sizeof(struct lttng_ust_event_field), .name = "int64", .type = lttng_ust_type_integer_define(int64_t, BYTE_ORDER, 10), .nowrite = 0, }), - [LTTNG_UST_DYNAMIC_TYPE_U8] = __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { + [LTTNG_UST_DYNAMIC_TYPE_U8] = __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { .struct_size = sizeof(struct lttng_ust_event_field), .name = "uint8", .type = lttng_ust_type_integer_define(uint8_t, BYTE_ORDER, 10), .nowrite = 0, }), - [LTTNG_UST_DYNAMIC_TYPE_U16] = __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { + [LTTNG_UST_DYNAMIC_TYPE_U16] = __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { .struct_size = sizeof(struct lttng_ust_event_field), .name = "uint16", .type = lttng_ust_type_integer_define(uint16_t, BYTE_ORDER, 10), .nowrite = 0, }), - [LTTNG_UST_DYNAMIC_TYPE_U32] = __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { + [LTTNG_UST_DYNAMIC_TYPE_U32] = __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { .struct_size = sizeof(struct lttng_ust_event_field), .name = "uint32", .type = lttng_ust_type_integer_define(uint32_t, BYTE_ORDER, 10), .nowrite = 0, }), - [LTTNG_UST_DYNAMIC_TYPE_U64] = __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { + [LTTNG_UST_DYNAMIC_TYPE_U64] = __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { .struct_size = sizeof(struct lttng_ust_event_field), .name = "uint64", .type = lttng_ust_type_integer_define(uint64_t, BYTE_ORDER, 10), .nowrite = 0, }), - [LTTNG_UST_DYNAMIC_TYPE_FLOAT] = __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { + [LTTNG_UST_DYNAMIC_TYPE_FLOAT] = __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { .struct_size = sizeof(struct lttng_ust_event_field), .name = "float", .type = lttng_ust_type_float_define(float), .nowrite = 0, }), - [LTTNG_UST_DYNAMIC_TYPE_DOUBLE] = __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { + [LTTNG_UST_DYNAMIC_TYPE_DOUBLE] = __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { .struct_size = sizeof(struct lttng_ust_event_field), .name = "double", .type = lttng_ust_type_float_define(double), .nowrite = 0, }), - [LTTNG_UST_DYNAMIC_TYPE_STRING] = __LTTNG_COMPOUND_LITERAL(struct lttng_ust_event_field, { + [LTTNG_UST_DYNAMIC_TYPE_STRING] = __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { .struct_size = sizeof(struct lttng_ust_event_field), .name = "string", .type = (struct lttng_ust_type_common *) __LTTNG_COMPOUND_LITERAL(struct lttng_ust_type_string, { @@ -140,7 +140,7 @@ struct lttng_ust_event_field *dt_var_fields[_NR_LTTNG_UST_DYNAMIC_TYPES] = { }), }; -static struct lttng_ust_event_field dt_enum_field = { +static const struct lttng_ust_event_field dt_enum_field = { .struct_size = sizeof(struct lttng_ust_event_field), .name = NULL, .type = (struct lttng_ust_type_common *) __LTTNG_COMPOUND_LITERAL(struct lttng_ust_type_enum, { @@ -154,21 +154,21 @@ static struct lttng_ust_event_field dt_enum_field = { .nowrite = 0, }; -struct lttng_ust_event_field *lttng_ust_dynamic_type_field(int64_t value) +const struct lttng_ust_event_field *lttng_ust_dynamic_type_field(int64_t value) { if (value >= _NR_LTTNG_UST_DYNAMIC_TYPES || value < 0) return NULL; return dt_var_fields[value]; } -int lttng_ust_dynamic_type_choices(size_t *nr_choices, struct lttng_ust_event_field ***choices) +int lttng_ust_dynamic_type_choices(size_t *nr_choices, const struct lttng_ust_event_field ***choices) { *nr_choices = _NR_LTTNG_UST_DYNAMIC_TYPES; *choices = dt_var_fields; return 0; } -struct lttng_ust_event_field *lttng_ust_dynamic_type_tag_field(void) +const struct lttng_ust_event_field *lttng_ust_dynamic_type_tag_field(void) { return &dt_enum_field; } diff --git a/liblttng-ust/ust-core.c b/liblttng-ust/ust-core.c index 6569c6f4..2633832b 100644 --- a/liblttng-ust/ust-core.c +++ b/liblttng-ust/ust-core.c @@ -90,7 +90,7 @@ void lttng_counter_transport_unregister(struct lttng_counter_transport *transpor * Needed by comm layer. */ struct lttng_enum *lttng_ust_enum_get_from_desc(struct lttng_ust_session *session, - struct lttng_ust_enum_desc *enum_desc) + const struct lttng_ust_enum_desc *enum_desc) { struct lttng_enum *_enum; struct cds_hlist_head *head; @@ -108,7 +108,7 @@ struct lttng_enum *lttng_ust_enum_get_from_desc(struct lttng_ust_session *sessio return NULL; } -size_t lttng_ust_dummy_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), +size_t lttng_ust_dummy_get_size(void *priv __attribute__((unused)), size_t offset) { size_t size = 0; @@ -118,7 +118,7 @@ size_t lttng_ust_dummy_get_size(struct lttng_ust_ctx_field *field __attribute__( return size; } -void lttng_ust_dummy_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void lttng_ust_dummy_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan) { @@ -127,7 +127,7 @@ void lttng_ust_dummy_record(struct lttng_ust_ctx_field *field __attribute__((unu chan->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(sel_char)); } -void lttng_ust_dummy_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void lttng_ust_dummy_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { value->sel = LTTNG_UST_DYNAMIC_TYPE_NONE; diff --git a/liblttng-ust/ust-events-internal.h b/liblttng-ust/ust-events-internal.h index 786b650d..d84d32ee 100644 --- a/liblttng-ust/ust-events-internal.h +++ b/liblttng-ust/ust-events-internal.h @@ -266,7 +266,7 @@ struct lttng_counter_transport { struct lttng_ust_event_common_private { struct lttng_ust_event_common *pub; /* Public event interface */ - struct lttng_ust_event_desc *desc; + const struct lttng_ust_event_desc *desc; /* Backward references: list of lttng_enabler_ref (ref to enablers) */ struct cds_list_head enablers_ref_head; int registered; /* has reg'd tracepoint probe */ @@ -340,7 +340,7 @@ struct lttng_ust_session_private { }; struct lttng_enum { - struct lttng_ust_enum_desc *desc; + const struct lttng_ust_enum_desc *desc; struct lttng_ust_session *session; struct cds_list_head node; /* Enum list in session */ struct cds_hlist_node hlist; /* Session ht of enums */ @@ -419,163 +419,137 @@ struct lttng_ust_abi_channel_config { int unused11:1; }; +/* Global (filter), event and channel contexts. */ +struct lttng_ust_ctx { + struct lttng_ust_ctx_field *fields; + unsigned int nr_fields; + unsigned int allocated_fields; + unsigned int largest_align; +}; + +struct lttng_ust_registered_probe { + const struct lttng_ust_probe_desc *desc; + + struct cds_list_head head; /* chain registered probes */ + struct cds_list_head lazy_init_head; + int lazy; /* lazy registration */ +}; + +/* + * Context field + */ + +struct lttng_ust_ctx_field { + const struct lttng_ust_event_field *event_field; + size_t (*get_size)(void *priv, size_t offset); + void (*record)(void *priv, struct lttng_ust_lib_ring_buffer_ctx *ctx, + struct lttng_ust_channel_buffer *chan); + void (*get_value)(void *priv, struct lttng_ust_ctx_value *value); + void (*destroy)(void *priv); + void *priv; +}; + static inline -struct lttng_ust_type_integer *lttng_ust_get_type_integer(struct lttng_ust_type_common *type) +const struct lttng_ust_type_integer *lttng_ust_get_type_integer(const struct lttng_ust_type_common *type) { if (type->type != lttng_ust_type_integer) return NULL; - return caa_container_of(type, struct lttng_ust_type_integer, parent); + return caa_container_of(type, const struct lttng_ust_type_integer, parent); } static inline -struct lttng_ust_type_float *lttng_ust_get_type_float(struct lttng_ust_type_common *type) +const struct lttng_ust_type_float *lttng_ust_get_type_float(const struct lttng_ust_type_common *type) { if (type->type != lttng_ust_type_float) return NULL; - return caa_container_of(type, struct lttng_ust_type_float, parent); + return caa_container_of(type, const struct lttng_ust_type_float, parent); } static inline -struct lttng_ust_type_string *lttng_ust_get_type_string(struct lttng_ust_type_common *type) +const struct lttng_ust_type_string *lttng_ust_get_type_string(const struct lttng_ust_type_common *type) { if (type->type != lttng_ust_type_string) return NULL; - return caa_container_of(type, struct lttng_ust_type_string, parent); + return caa_container_of(type, const struct lttng_ust_type_string, parent); } static inline -struct lttng_ust_type_enum *lttng_ust_get_type_enum(struct lttng_ust_type_common *type) +const struct lttng_ust_type_enum *lttng_ust_get_type_enum(const struct lttng_ust_type_common *type) { if (type->type != lttng_ust_type_enum) return NULL; - return caa_container_of(type, struct lttng_ust_type_enum, parent); + return caa_container_of(type, const struct lttng_ust_type_enum, parent); } static inline -struct lttng_ust_type_array *lttng_ust_get_type_array(struct lttng_ust_type_common *type) +const struct lttng_ust_type_array *lttng_ust_get_type_array(const struct lttng_ust_type_common *type) { if (type->type != lttng_ust_type_array) return NULL; - return caa_container_of(type, struct lttng_ust_type_array, parent); + return caa_container_of(type, const struct lttng_ust_type_array, parent); } static inline -struct lttng_ust_type_sequence *lttng_ust_get_type_sequence(struct lttng_ust_type_common *type) +const struct lttng_ust_type_sequence *lttng_ust_get_type_sequence(const struct lttng_ust_type_common *type) { if (type->type != lttng_ust_type_sequence) return NULL; - return caa_container_of(type, struct lttng_ust_type_sequence, parent); + return caa_container_of(type, const struct lttng_ust_type_sequence, parent); } static inline -struct lttng_ust_type_struct *lttng_ust_get_type_struct(struct lttng_ust_type_common *type) +const struct lttng_ust_type_struct *lttng_ust_get_type_struct(const struct lttng_ust_type_common *type) { if (type->type != lttng_ust_type_struct) return NULL; - return caa_container_of(type, struct lttng_ust_type_struct, parent); + return caa_container_of(type, const struct lttng_ust_type_struct, parent); } -/* Create dynamically allocated types. */ -static inline -struct lttng_ust_type_common *lttng_ust_create_type_integer(unsigned int size, - unsigned short alignment, bool signedness, unsigned int byte_order, - unsigned int base) -{ - struct lttng_ust_type_integer *integer_type; - - integer_type = zmalloc(sizeof(struct lttng_ust_type_integer)); - if (!integer_type) - return NULL; - integer_type->parent.type = lttng_ust_type_integer; - integer_type->struct_size = sizeof(struct lttng_ust_type_integer); - integer_type->size = size; - integer_type->alignment = alignment; - integer_type->signedness = signedness; - integer_type->reverse_byte_order = byte_order != BYTE_ORDER; - integer_type->base = base; - return (struct lttng_ust_type_common *) integer_type; -} - -static inline -struct lttng_ust_type_common *lttng_ust_create_type_array_text(unsigned int length) -{ - struct lttng_ust_type_array *array_type; - - array_type = zmalloc(sizeof(struct lttng_ust_type_array)); - if (!array_type) - return NULL; - array_type->parent.type = lttng_ust_type_array; - array_type->struct_size = sizeof(struct lttng_ust_type_array); - array_type->length = length; - array_type->alignment = 0; - array_type->encoding = lttng_ust_string_encoding_UTF8; - array_type->elem_type = lttng_ust_create_type_integer(sizeof(char) * CHAR_BIT, - lttng_ust_rb_alignof(char) * CHAR_BIT, lttng_ust_is_signed_type(char), - BYTE_ORDER, 10); - if (!array_type->elem_type) - goto error_elem; - return (struct lttng_ust_type_common *) array_type; - -error_elem: - free(array_type); - return NULL; -} - -/* - * Destroy dynamically allocated types, including nested types. - * For enumerations, it does not free the enumeration mapping description. - */ -static inline -void lttng_ust_destroy_type(struct lttng_ust_type_common *type) -{ - if (!type) - return; - - switch (type->type) { - case lttng_ust_type_integer: - case lttng_ust_type_string: - case lttng_ust_type_float: - case lttng_ust_type_dynamic: - free(type); - break; - case lttng_ust_type_enum: - { - struct lttng_ust_type_enum *enum_type = (struct lttng_ust_type_enum *) type; - - lttng_ust_destroy_type(enum_type->container_type); - free(enum_type); - break; - } - case lttng_ust_type_array: - { - struct lttng_ust_type_array *array_type = (struct lttng_ust_type_array *) type; - - lttng_ust_destroy_type(array_type->elem_type); - free(array_type); - break; - } - case lttng_ust_type_sequence: - { - struct lttng_ust_type_sequence *sequence_type = (struct lttng_ust_type_sequence *) type; - - lttng_ust_destroy_type(sequence_type->elem_type); - free(sequence_type); - break; - } - case lttng_ust_type_struct: - { - struct lttng_ust_type_struct *struct_type = (struct lttng_ust_type_struct *) type; - unsigned int i; - - for (i = 0; i < struct_type->nr_fields; i++) - lttng_ust_destroy_type(struct_type->fields[i]->type); - free(struct_type); - break; - } - default: - abort(); - } -} +#define lttng_ust_static_type_integer(_size, _alignment, _signedness, _byte_order, _base) \ + ((const struct lttng_ust_type_common *) __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_type_integer, { \ + .parent = { \ + .type = lttng_ust_type_integer, \ + }, \ + .struct_size = sizeof(struct lttng_ust_type_integer), \ + .size = (_size), \ + .alignment = (_alignment), \ + .signedness = (_signedness), \ + .reverse_byte_order = (_byte_order) != BYTE_ORDER, \ + .base = (_base), \ + })) + +#define lttng_ust_static_type_array_text(_length) \ + ((const struct lttng_ust_type_common *) __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_type_array, { \ + .parent = { \ + .type = lttng_ust_type_array, \ + }, \ + .struct_size = sizeof(struct lttng_ust_type_array), \ + .length = (_length), \ + .alignment = 0, \ + .encoding = lttng_ust_string_encoding_UTF8, \ + .elem_type = lttng_ust_static_type_integer(sizeof(char) * CHAR_BIT, \ + lttng_ust_rb_alignof(char) * CHAR_BIT, lttng_ust_is_signed_type(char), \ + BYTE_ORDER, 10), \ + })) + +#define lttng_ust_static_event_field(_name, _type, _nowrite, _nofilter) \ + __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_event_field, { \ + .struct_size = sizeof(struct lttng_ust_event_field), \ + .name = (_name), \ + .type = (_type), \ + .nowrite = (_nowrite), \ + .nofilter = (_nofilter), \ + }) + +#define lttng_ust_static_ctx_field(_event_field, _get_size, _record, _get_value, _destroy, _priv) \ + __LTTNG_COMPOUND_LITERAL(const struct lttng_ust_ctx_field, { \ + .event_field = (_event_field), \ + .get_size = (_get_size), \ + .record = (_record), \ + .get_value = (_get_value), \ + .destroy = (_destroy), \ + .priv = (_priv), \ + }) static inline struct lttng_enabler *lttng_event_enabler_as_enabler( @@ -656,7 +630,7 @@ int lttng_event_enabler_attach_exclusion(struct lttng_event_enabler *enabler, * This function goes over all bytecode programs of the enabler (event or * event_notifier enabler) to ensure each is linked to the provided instance. */ -void lttng_enabler_link_bytecode(struct lttng_ust_event_desc *event_desc, +void lttng_enabler_link_bytecode(const struct lttng_ust_event_desc *event_desc, struct lttng_ust_ctx **ctx, struct cds_list_head *instance_bytecode_runtime_head, struct cds_list_head *enabler_bytecode_runtime_head) @@ -855,7 +829,7 @@ struct lttng_transport *lttng_ust_transport_find(const char *name); /* This is ABI between liblttng-ust and liblttng-ust-dl */ void lttng_ust_dl_update(void *ip); -void lttng_probe_provider_unregister_events(struct lttng_ust_probe_desc *desc) +void lttng_probe_provider_unregister_events(const struct lttng_ust_probe_desc *desc) __attribute__((visibility("hidden"))); int lttng_fix_pending_events(void) @@ -865,7 +839,7 @@ struct cds_list_head *lttng_get_probe_list_head(void) __attribute__((visibility("hidden"))); struct lttng_enum *lttng_ust_enum_get_from_desc(struct lttng_ust_session *session, - struct lttng_ust_enum_desc *enum_desc) + const struct lttng_ust_enum_desc *enum_desc) __attribute__((visibility("hidden"))); int lttng_abi_create_root_handle(void) @@ -908,4 +882,24 @@ void lttng_ust_format_event_name(const struct lttng_ust_event_desc *desc, char *name) __attribute__((visibility("hidden"))); +int lttng_ust_add_app_context_to_ctx_rcu(const char *name, struct lttng_ust_ctx **ctx) + __attribute__((visibility("hidden"))); + +int lttng_ust_context_set_provider_rcu(struct lttng_ust_ctx **_ctx, + const char *name, + size_t (*get_size)(void *priv, size_t offset), + void (*record)(void *priv, struct lttng_ust_lib_ring_buffer_ctx *ctx, + struct lttng_ust_channel_buffer *chan), + void (*get_value)(void *priv, struct lttng_ust_ctx_value *value), + void *priv) + __attribute__((visibility("hidden"))); + +void lttng_ust_context_set_session_provider(const char *name, + size_t (*get_size)(void *priv, size_t offset), + void (*record)(void *priv, struct lttng_ust_lib_ring_buffer_ctx *ctx, + struct lttng_ust_channel_buffer *chan), + void (*get_value)(void *priv, struct lttng_ust_ctx_value *value), + void *priv) + __attribute__((visibility("hidden"))); + #endif /* _LTTNG_UST_EVENTS_INTERNAL_H */ diff --git a/tests/compile/test-app-ctx/hello.c b/tests/compile/test-app-ctx/hello.c index bff2bdb5..9cc8f1a8 100644 --- a/tests/compile/test-app-ctx/hello.c +++ b/tests/compile/test-app-ctx/hello.c @@ -42,7 +42,7 @@ void test_inc_count(void) } static -size_t test_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), size_t offset) +size_t test_get_size(void *priv __attribute__((unused)), size_t offset) { int sel = test_count % _NR_LTTNG_UST_DYNAMIC_TYPES; size_t size = 0; @@ -103,7 +103,7 @@ size_t test_get_size(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void test_record(struct lttng_ust_ctx_field *field __attribute__((unused)), +void test_record(void *priv __attribute__((unused)), struct lttng_ust_lib_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *lttng_chan_buf) { @@ -196,7 +196,7 @@ void test_record(struct lttng_ust_ctx_field *field __attribute__((unused)), } static -void test_get_value(struct lttng_ust_ctx_field *field __attribute__((unused)), +void test_get_value(void *priv __attribute__((unused)), struct lttng_ust_ctx_value *value) { int sel = test_count % _NR_LTTNG_UST_DYNAMIC_TYPES; @@ -289,6 +289,7 @@ int init_int_handler(void) int main(int argc, char **argv) { + struct lttng_ust_registered_context_provider *reg_provider; int i, netint; long values[] = { 1, 2, 3 }; char text[10] = "test"; @@ -302,7 +303,8 @@ int main(int argc, char **argv) if (argc == 2) delay = atoi(argv[1]); - if (lttng_ust_context_provider_register(&myprovider)) + reg_provider = lttng_ust_context_provider_register(&myprovider); + if (!reg_provider) abort(); fprintf(stderr, "Hello, World!\n"); @@ -317,7 +319,7 @@ int main(int argc, char **argv) test_inc_count(); //usleep(100000); } - lttng_ust_context_provider_unregister(&myprovider); + lttng_ust_context_provider_unregister(reg_provider); fprintf(stderr, " done.\n"); return 0; }