From 1ddfd6412d2a160eb5b8e97ebbfd0a9dbc88faa0 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Sun, 8 Jul 2012 13:35:48 -0400 Subject: [PATCH] Filter: prepare filter stack data Signed-off-by: Mathieu Desnoyers --- include/lttng/ust-events.h | 7 ++- include/lttng/ust-tracepoint-event.h | 80 +++++++++++++++++++++++++++- liblttng-ust/ltt-events.c | 7 ++- liblttng-ust/ltt-probes.c | 2 +- liblttng-ust/lttng-ust-abi.c | 4 +- 5 files changed, 91 insertions(+), 9 deletions(-) diff --git a/include/lttng/ust-events.h b/include/lttng/ust-events.h index 5edfbb99..91d5839b 100644 --- a/include/lttng/ust-events.h +++ b/include/lttng/ust-events.h @@ -293,7 +293,8 @@ struct ltt_event { struct ltt_channel *chan; int enabled; const struct lttng_event_desc *desc; - void (*filter)(struct ltt_event *event); + int (*filter)(void *filter_data, const char *filter_stack_data); + void *filter_data; struct lttng_ctx *ctx; enum lttng_ust_instrumentation instrumentation; union { @@ -413,7 +414,9 @@ struct ltt_channel *ltt_global_channel_create(struct ltt_session *session, int ltt_event_create(struct ltt_channel *chan, struct lttng_ust_event *event_param, - void (*filter)(struct ltt_event *event), + int (*filter)(void *filter_data, + const char *filter_stack_data), + void *filter_data, struct ltt_event **event); int ltt_channel_enable(struct ltt_channel *channel); diff --git a/include/lttng/ust-tracepoint-event.h b/include/lttng/ust-tracepoint-event.h index 853b5990..98715bf4 100644 --- a/include/lttng/ust-tracepoint-event.h +++ b/include/lttng/ust-tracepoint-event.h @@ -291,6 +291,69 @@ static inline size_t __event_get_size__##_provider##___##_name(size_t *__dynamic #include TRACEPOINT_INCLUDE +/* + * Stage 3.1 of tracepoint event generation. + * + * Create static inline function that layout the filter stack data. + */ + +/* Reset all macros within TRACEPOINT_EVENT */ +#include + +#undef ctf_integer_ext +#define ctf_integer_ext(_type, _item, _src, _byte_order, _base) \ + if (lttng_is_signed_type(_type)) \ + *(int64_t *) __stack_data = (int64_t) (_type) (_src); \ + else \ + *(uint64_t *) __stack_data = (uint64_t) (_type) (_src); \ + __stack_data += sizeof(int64_t); + +#undef ctf_float +#define ctf_float(_type, _item, _src) \ + *(double *) __stack_data = (double) (_type) (_src); \ + __stack_data += sizeof(double); + +#undef ctf_array_encoded +#define ctf_array_encoded(_type, _item, _src, _length, _encoding) \ + *(unsigned long *) __stack_data = (unsigned long) (_length); \ + __stack_data += sizeof(unsigned long); \ + *(const void **) __stack_data = (_src); \ + __stack_data += sizeof(void *); + +#undef ctf_sequence_encoded +#define ctf_sequence_encoded(_type, _item, _src, _length_type, \ + _src_length, _encoding) \ + *(unsigned long *) __stack_data = (unsigned long) (_src_length); \ + __stack_data += sizeof(unsigned long); \ + *(const void **) __stack_data = (_src); \ + __stack_data += sizeof(void *); + +#undef ctf_string +#define ctf_string(_item, _src) \ + *(unsigned long *) __stack_data = (unsigned long) (strlen(_src) + 1); \ + __stack_data += sizeof(unsigned long); \ + *(const void **) __stack_data = (_src); \ + __stack_data += sizeof(void *); + +#undef TP_ARGS +#define TP_ARGS(...) __VA_ARGS__ + +#undef TP_FIELDS +#define TP_FIELDS(...) __VA_ARGS__ + +#undef TRACEPOINT_EVENT_CLASS +#define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \ +static inline \ +void __event_prepare_filter_stack__##_provider##___##_name(char *__stack_data,\ + _TP_ARGS_DATA_PROTO(_args)) \ +{ \ + _fields \ +} + +#include TRACEPOINT_INCLUDE + + + /* * Stage 4 of tracepoint event generation. * @@ -398,6 +461,12 @@ size_t __event_get_align__##_provider##___##_name(_TP_ARGS_PROTO(_args)) \ #undef TP_FIELDS #define TP_FIELDS(...) __VA_ARGS__ +/* + * Using twice size for filter stack data to hold size and pointer for + * each field (worse case). For integers, max size required is 64-bit. + * Same for double-precision floats. Those fit within + * 2*sizeof(unsigned long) for all supported architectures. + */ #undef TRACEPOINT_EVENT_CLASS #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \ static void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args))\ @@ -408,7 +477,8 @@ static void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args))\ size_t __event_len, __event_align; \ size_t __dynamic_len_idx = 0; \ union { \ - size_t __dynamic_len[_TP_ARRAY_SIZE(__event_fields___##_provider##___##_name)]; \ + size_t __dynamic_len[_TP_ARRAY_SIZE(__event_fields___##_provider##___##_name)]; \ + char __filter_stack_data[2 * sizeof(unsigned long) * _TP_ARRAY_SIZE(__event_fields___##_provider##___##_name)]; \ } __stackvar; \ int __ret; \ \ @@ -420,7 +490,13 @@ static void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args))\ return; \ if (caa_unlikely(!CMM_ACCESS_ONCE(__event->enabled))) \ return; \ - __event_len = __event_get_size__##_provider##___##_name(__stackvar.__dynamic_len,\ + if (caa_unlikely(__event->filter)) { \ + __event_prepare_filter_stack__##_provider##___##_name(__stackvar.__filter_stack_data, \ + _TP_ARGS_DATA_VAR(_args)); \ + if (caa_likely(!__event->filter(__event->filter_data, __stackvar.__filter_stack_data))) \ + return; \ + } \ + __event_len = __event_get_size__##_provider##___##_name(__stackvar.__dynamic_len, \ _TP_ARGS_DATA_VAR(_args)); \ __event_align = __event_get_align__##_provider##___##_name(_TP_ARGS_VAR(_args)); \ lib_ring_buffer_ctx_init(&__ctx, __chan->chan, __event, __event_len, \ diff --git a/liblttng-ust/ltt-events.c b/liblttng-ust/ltt-events.c index 0fdfd2fd..eb6749d9 100644 --- a/liblttng-ust/ltt-events.c +++ b/liblttng-ust/ltt-events.c @@ -251,7 +251,7 @@ int pending_probe_fix_events(const struct lttng_event_desc *desc) sizeof(event_param.name)); /* create event */ ret = ltt_event_create(sw->chan, - &event_param, NULL, + &event_param, NULL, NULL, &ev); if (ret) { DBG("Error creating event"); @@ -500,7 +500,9 @@ void _ltt_channel_destroy(struct ltt_channel *chan) */ int ltt_event_create(struct ltt_channel *chan, struct lttng_ust_event *event_param, - void (*filter)(struct ltt_event *event), + int (*filter)(void *filter_data, + const char *filter_stack_data), + void *filter_data, struct ltt_event **_event) { const struct lttng_event_desc *desc = NULL; /* silence gcc */ @@ -549,6 +551,7 @@ int ltt_event_create(struct ltt_channel *chan, } event->chan = chan; event->filter = filter; + event->filter_data = filter_data; /* * used_event_id counts the maximum number of event IDs that can * register if all probes register. diff --git a/liblttng-ust/ltt-probes.c b/liblttng-ust/ltt-probes.c index 9072d37e..39fb5716 100644 --- a/liblttng-ust/ltt-probes.c +++ b/liblttng-ust/ltt-probes.c @@ -372,7 +372,7 @@ void ltt_probes_create_wildcard_events(struct wildcard_entry *entry, sizeof(event_param.name)); /* create event */ ret = ltt_event_create(wildcard->chan, - &event_param, NULL, + &event_param, NULL, NULL, &ev); if (ret) { DBG("Error creating event"); diff --git a/liblttng-ust/lttng-ust-abi.c b/liblttng-ust/lttng-ust-abi.c index dac86c78..fded1e3a 100644 --- a/liblttng-ust/lttng-ust-abi.c +++ b/liblttng-ust/lttng-ust-abi.c @@ -361,7 +361,7 @@ void lttng_metadata_create_events(int channel_objd) * We tolerate no failure path after event creation. It will stay * invariant for the rest of the session. */ - ret = ltt_event_create(channel, &metadata_params, NULL, &event); + ret = ltt_event_create(channel, &metadata_params, NULL, NULL, &event); if (ret < 0) { goto create_error; } @@ -753,7 +753,7 @@ int lttng_abi_create_event(int channel_objd, * We tolerate no failure path after event creation. It will stay * invariant for the rest of the session. */ - ret = ltt_event_create(channel, event_param, NULL, &event); + ret = ltt_event_create(channel, event_param, NULL, NULL, &event); if (ret < 0) { goto event_error; } -- 2.34.1