X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=include%2Flttng%2Fust-tracepoint-event.h;h=4130b7cb8f794e6310efd5b75b584c82728cce67;hb=cd54f6d934faf715cbd12fa9665e94b6fe367802;hp=0bdc35be4f85ce6a7650efcea86745b5768b26cf;hpb=75c5ad79cbdc0b7d0579ccd1c97902ded5bdc08a;p=lttng-ust.git diff --git a/include/lttng/ust-tracepoint-event.h b/include/lttng/ust-tracepoint-event.h index 0bdc35be..4130b7cb 100644 --- a/include/lttng/ust-tracepoint-event.h +++ b/include/lttng/ust-tracepoint-event.h @@ -1,14 +1,15 @@ /* - * Copyright (c) 2011 - Mathieu Desnoyers + * Copyright (c) 2011-2012 - Mathieu Desnoyers * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED - * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * Permission is hereby granted to use or copy this program - * for any purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is granted, - * provided the above notices are retained, and a notice that the code was - * modified is included with the above copyright notice. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. */ #include @@ -76,7 +77,7 @@ _TP_PARAMS(_args), \ _TP_PARAMS(_fields)) \ TRACEPOINT_EVENT_INSTANCE(_provider, _name, _name, \ - _TP_PARAMS(args)) + _TP_PARAMS(_args)) /* Helpers */ #define _TP_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) @@ -203,7 +204,7 @@ static const char \ }, #undef TP_FIELDS -#define TP_FIELDS(args...) args /* Only one used in this phase */ +#define TP_FIELDS(...) __VA_ARGS__ /* Only one used in this phase */ #undef TRACEPOINT_EVENT_CLASS #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \ @@ -223,7 +224,7 @@ static const char \ #include #undef TP_ARGS -#define TP_ARGS(args...) args +#define TP_ARGS(...) __VA_ARGS__ #undef TRACEPOINT_EVENT_CLASS #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \ @@ -270,10 +271,10 @@ static void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args)); __event_len += __dynamic_len[__dynamic_len_idx++] = strlen(_src) + 1; #undef TP_ARGS -#define TP_ARGS(args...) args +#define TP_ARGS(...) __VA_ARGS__ #undef TP_FIELDS -#define TP_FIELDS(args...) args +#define TP_FIELDS(...) __VA_ARGS__ #undef TRACEPOINT_EVENT_CLASS #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \ @@ -290,6 +291,67 @@ 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) \ + *(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. * @@ -321,10 +383,10 @@ static inline size_t __event_get_size__##_provider##___##_name(size_t *__dynamic #define ctf_string(_item, _src) #undef TP_ARGS -#define TP_ARGS(args...) args +#define TP_ARGS(...) __VA_ARGS__ #undef TP_FIELDS -#define TP_FIELDS(args...) args +#define TP_FIELDS(...) __VA_ARGS__ #undef TRACEPOINT_EVENT_CLASS #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \ @@ -374,7 +436,7 @@ size_t __event_get_align__##_provider##___##_name(_TP_ARGS_PROTO(_args)) \ #define ctf_sequence_encoded(_type, _item, _src, _length_type, \ _src_length, _encoding) \ { \ - _length_type __tmpl = __dynamic_len[__dynamic_len_idx]; \ + _length_type __tmpl = __stackvar.__dynamic_len[__dynamic_len_idx]; \ lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_length_type));\ __chan->ops->event_write(&__ctx, &__tmpl, sizeof(_length_type));\ } \ @@ -389,14 +451,20 @@ size_t __event_get_align__##_provider##___##_name(_TP_ARGS_PROTO(_args)) \ /* Beware: this get len actually consumes the len value */ #undef __get_dynamic_len -#define __get_dynamic_len(field) __dynamic_len[__dynamic_len_idx++] +#define __get_dynamic_len(field) __stackvar.__dynamic_len[__dynamic_len_idx++] #undef TP_ARGS -#define TP_ARGS(args...) args +#define TP_ARGS(...) __VA_ARGS__ #undef TP_FIELDS -#define TP_FIELDS(args...) args +#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))\ @@ -406,7 +474,10 @@ static void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args))\ struct lttng_ust_lib_ring_buffer_ctx __ctx; \ size_t __event_len, __event_align; \ size_t __dynamic_len_idx = 0; \ - size_t __dynamic_len[_TP_ARRAY_SIZE(__event_fields___##_provider##___##_name)]; \ + union { \ + 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; \ \ if (0) \ @@ -417,7 +488,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(__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, \ @@ -434,76 +511,30 @@ static void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args))\ #undef __get_dynamic_len /* - * Stage 6.1 of tracepoint event generation. + * Stage 5.1 of tracepoint event generation. * - * Tracepoint loglevel enumeration definition generation. + * Create probe signature */ /* Reset all macros within TRACEPOINT_EVENT */ #include -#undef TRACEPOINT_LOGLEVEL_ENUM -#define TRACEPOINT_LOGLEVEL_ENUM(...) __VA_ARGS__ - -#undef tp_loglevel -#define tp_loglevel(_identifier, _value) \ -static const struct tracepoint_loglevel_entry \ - _TP_COMBINE_TOKENS4(__tp_loglevel_entry__, TRACEPOINT_PROVIDER, ___, _identifier) = { \ - .identifier = #_identifier, \ - .value = (_value), \ - }; +#undef TP_ARGS +#define TP_ARGS(...) __VA_ARGS__ -tp_loglevel(TRACE_EMERG, 0) -tp_loglevel(TRACE_ALERT, 1) -tp_loglevel(TRACE_CRIT, 2) -tp_loglevel(TRACE_ERR, 3) -tp_loglevel(TRACE_WARNING, 4) -tp_loglevel(TRACE_NOTICE, 5) -tp_loglevel(TRACE_INFO, 6) -tp_loglevel(TRACE_SYSTEM, 7) -tp_loglevel(TRACE_PROCESS, 8) -tp_loglevel(TRACE_MODULE, 9) -tp_loglevel(TRACE_UNIT, 10) -tp_loglevel(TRACE_CLASS, 11) -tp_loglevel(TRACE_OBJECT, 12) -tp_loglevel(TRACE_FUNCTION, 13) -tp_loglevel(TRACE_PRINTF, 14) -tp_loglevel(TRACE_DEBUG, 15) +#define _TP_EXTRACT_STRING2(...) #__VA_ARGS__ -/* - * Stage 6.2 of tracepoint event generation. - * - * Tracepoint loglevel enumeration array generation. - */ +#undef TRACEPOINT_EVENT_CLASS +#define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \ +const char __tp_event_signature___##_provider##___##_name[] = \ + _TP_EXTRACT_STRING2(_args); -/* Reset all macros within TRACEPOINT_EVENT */ -#include +#include TRACEPOINT_INCLUDE -#undef tp_loglevel -#define tp_loglevel(_identifier, _value) \ - &_TP_COMBINE_TOKENS4(__tp_loglevel_entry__, TRACEPOINT_PROVIDER, ___, _identifier), \ - -static const struct tracepoint_loglevel_entry *_TP_COMBINE_TOKENS(__tracepoint_loglevel_enum__, TRACEPOINT_PROVIDER)[] = { - tp_loglevel(TRACE_EMERG, 0) - tp_loglevel(TRACE_ALERT, 1) - tp_loglevel(TRACE_CRIT, 2) - tp_loglevel(TRACE_ERR, 3) - tp_loglevel(TRACE_WARNING, 4) - tp_loglevel(TRACE_NOTICE, 5) - tp_loglevel(TRACE_INFO, 6) - tp_loglevel(TRACE_SYSTEM, 7) - tp_loglevel(TRACE_PROCESS, 8) - tp_loglevel(TRACE_MODULE, 9) - tp_loglevel(TRACE_UNIT, 10) - tp_loglevel(TRACE_CLASS, 11) - tp_loglevel(TRACE_OBJECT, 12) - tp_loglevel(TRACE_FUNCTION, 13) - tp_loglevel(TRACE_PRINTF, 14) - tp_loglevel(TRACE_DEBUG, 15) -}; +#undef _TP_EXTRACT_STRING2 /* - * Stage 7 of tracepoint event generation. + * Stage 6 of tracepoint event generation. * * Tracepoint loglevel mapping definition generation. We generate a * symbol for each mapping for a provider/event to ensure at most a 1 to @@ -515,15 +546,15 @@ static const struct tracepoint_loglevel_entry *_TP_COMBINE_TOKENS(__tracepoint_l #include #undef TRACEPOINT_LOGLEVEL -#define TRACEPOINT_LOGLEVEL(__provider, __name, __loglevel) \ -static const struct tracepoint_loglevel_entry * \ - _loglevel_mapping___##__provider##___##__name = \ - &__tp_loglevel_entry__##__provider##___##__loglevel; +#define TRACEPOINT_LOGLEVEL(__provider, __name, __loglevel) \ +static const int _loglevel_value___##__provider##___##__name = __loglevel; \ +static const int *_loglevel___##__provider##___##__name = \ + &_loglevel_value___##__provider##___##__name; #include TRACEPOINT_INCLUDE /* - * Stage 8.1 of tracepoint event generation. + * Stage 7.1 of tracepoint event generation. * * Create events description structures. We use a weakref because * loglevels are optional. If not declared, the event will point to the @@ -535,21 +566,22 @@ static const struct tracepoint_loglevel_entry * \ #undef TRACEPOINT_EVENT_INSTANCE #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \ -static const struct tracepoint_loglevel_entry * \ - __ref_loglevel_mapping___##_provider##___##_name \ - __attribute__((weakref ("_loglevel_mapping___" #_provider "___" #_name))); \ +static const int * \ + __ref_loglevel___##_provider##___##_name \ + __attribute__((weakref ("_loglevel___" #_provider "___" #_name))); \ const struct lttng_event_desc __event_desc___##_provider##_##_name = { \ .fields = __event_fields___##_provider##___##_template, \ .name = #_provider ":" #_name, \ - .probe_callback = (void *) &__event_probe__##_provider##___##_template,\ + .probe_callback = (void (*)(void)) &__event_probe__##_provider##___##_template,\ .nr_fields = _TP_ARRAY_SIZE(__event_fields___##_provider##___##_template), \ - .loglevel = &__ref_loglevel_mapping___##_provider##___##_name, \ + .loglevel = &__ref_loglevel___##_provider##___##_name, \ + .signature = __tp_event_signature___##_provider##___##_template, \ }; #include TRACEPOINT_INCLUDE /* - * Stage 8.2 of tracepoint event generation. + * Stage 7.2 of tracepoint event generation. * * Create array of events. */ @@ -567,7 +599,7 @@ static const struct lttng_event_desc *_TP_COMBINE_TOKENS(__event_desc___, TRACEP /* - * Stage 9 of tracepoint event generation. + * Stage 8 of tracepoint event generation. * * Create a toplevel descriptor for the whole probe. */ @@ -577,19 +609,19 @@ static struct lttng_probe_desc _TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PR .provider = __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)), - .loglevels = _TP_COMBINE_TOKENS(__tracepoint_loglevel_enum__, TRACEPOINT_PROVIDER), - .nr_loglevels = _TP_ARRAY_SIZE(_TP_COMBINE_TOKENS(__tracepoint_loglevel_enum__, TRACEPOINT_PROVIDER)), }; /* - * Stage 10 of tracepoint event generation. + * Stage 9 of tracepoint event generation. * * Register/unregister probes at module load/unload. + * + * Generate the constructor as an externally visible symbol for use when + * linking the probe statically. */ /* Reset all macros within TRACEPOINT_EVENT */ #include - static void __attribute__((constructor)) _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void) { @@ -604,3 +636,5 @@ _TP_COMBINE_TOKENS(__lttng_events_exit__, TRACEPOINT_PROVIDER)(void) { ltt_probe_unregister(&_TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER)); } + +int _TP_COMBINE_TOKENS(__tracepoint_provider_, TRACEPOINT_PROVIDER);