#ifndef _LTTNG_UST_EVENTS_H
#define _LTTNG_UST_EVENTS_H
-#include <urcu/list.h>
-#include <urcu/hlist.h>
#include <stddef.h>
#include <stdint.h>
#include <lttng/ust-abi.h>
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
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;
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;
};
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;
};
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. */
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 */
* 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. */
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;
* removed.
*/
-struct lttng_ust_ctx;
struct lttng_ust_event_common_private;
enum lttng_ust_event_type {
/* 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
/* 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)) ? \
/* 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)) ? \
/* 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, \
#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. */ \
};
#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), \
#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), \
#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, \
}, \
#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, \
}, \
#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, \
}, \
#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, \
}, \
#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, \
* 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")));
/*
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, \
#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. */
};
* 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.
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)++) {
* 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
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)
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")));
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")));
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")));
#include <stddef.h>
#include <lttng/ust-events.h>
-#include <urcu/hlist.h>
#include "ust-dynamic-type.h"
+struct lttng_ust_registered_context_provider;
+
/*
* Context 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
*
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 */
};
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 */
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.
}
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:
case lttng_ust_type_dynamic:
{
- struct lttng_ust_event_field **choices;
+ const struct lttng_ust_event_field **choices;
size_t nr_choices;
int ret;
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;
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;
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;
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,
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;
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);
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)
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;
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;
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;
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;
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;
}
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) */
{
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;
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) */
{
} 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;
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);
}
-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;
}
}
-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);
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.
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:
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);
}
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)
#include <lttng/ust-events.h>
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 */
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;
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;
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;
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;
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;
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:
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;
{
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:
{
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)) {
{
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;
{
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;
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;
}
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;
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;
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)
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;
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)
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;
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)
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)
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;
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;
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;
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;
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) {
* 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,
* 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)
* 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;
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 */
};
size_t nr_elem;
/* Inner type. */
- struct lttng_ust_type_common *nested_type;
+ const struct lttng_ust_type_common *nested_type;
} sequence;
} u;
};
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")));
}
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;
}
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)
{
}
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;
}
#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;
}
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)
{
}
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;
}
#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;
}
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)
{
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;
}
}
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;
}
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)
{
}
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;
}
}
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;
}
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)
{
}
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;
}
}
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;
}
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)
{
}
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;
}
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;
}
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;
}
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 */
/* 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
#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);
}
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;
}
}
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;
}
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)
{
}
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;
}
}
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)
{
}
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;
}
#include "context-provider-internal.h"
#include <ust-helper.h>
+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 {
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;
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);
}
/*
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))
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.
* 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;
}
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:
#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;
}
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)
{
}
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;
}
}
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;
}
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)
{
}
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;
}
}
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;
}
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)
{
}
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;
}
}
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;
}
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)
{
}
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;
}
}
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;
}
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)
{
}
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;
}
}
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;
}
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)
{
}
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;
}
}
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;
}
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)
{
}
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;
}
}
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;
}
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)
{
}
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;
}
}
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;
}
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)
{
}
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;
}
}
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;
}
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)
{
}
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;
}
}
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;
}
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)
{
}
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;
}
}
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;
}
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)
{
}
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;
}
unsigned int i;
const char *subname;
+ if (!ctx)
+ return 0;
if (strncmp(name, "$ctx.", strlen("$ctx.")) == 0) {
subname = name + strlen("$ctx.");
} else {
}
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;
}
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;
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;
}
/*
* 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;
*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);
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:
{
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,
* 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;
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)
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);
*/
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;
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);
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);
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);
}
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;
}
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;
}
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();
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;
/* 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)
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;
/* 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)
*/
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;
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;
* 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];
}
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)
{
}
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];
}
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];
}
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) {
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;
* 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;
}
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;
* 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;
/* 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];
* 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
/* 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;
}
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;
* 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;
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();
}
* 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;
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();
}
* 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;
* 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;
/*
*/
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);
}
/*
static
void fixup_lazy_probes(void)
{
- struct lttng_ust_probe_desc *iter, *tmp;
+ struct lttng_ust_registered_probe *iter, *tmp;
int ret;
lazy_nesting++;
}
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.
}
}
-
-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();
* 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);
/*
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)
*/
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];
*/
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];
}
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
* 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);
}
}
}
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
* 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);
}
}
}
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(
.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)
.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, {
}),
.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, {
}),
};
-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, {
.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;
}
* 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;
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;
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)
{
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;
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 */
};
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 */
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(
* 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)
/* 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)
__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)
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 */
}
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;
}
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)
{
}
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;
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";
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");
test_inc_count();
//usleep(100000);
}
- lttng_ust_context_provider_unregister(&myprovider);
+ lttng_ust_context_provider_unregister(reg_provider);
fprintf(stderr, " done.\n");
return 0;
}