X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=include%2Flttng%2Fust-tracepoint-event.h;h=11762aaacc3ef664ceee14a54a8b9ab6b558c03c;hb=b367a10555056790c34dcfa3026d7f9b82f067f4;hp=0be3395be7d72996dc7a33645ceabd6048396f9c;hpb=7dd08bec735b428479201f9f84d59c78deabdf57;p=lttng-ust.git diff --git a/include/lttng/ust-tracepoint-event.h b/include/lttng/ust-tracepoint-event.h index 0be3395b..11762aaa 100644 --- a/include/lttng/ust-tracepoint-event.h +++ b/include/lttng/ust-tracepoint-event.h @@ -10,16 +10,32 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include +#include #include #include #include #include #include +#include #include +#undef tp_list_for_each_entry_rcu +#define tp_list_for_each_entry_rcu(pos, head, member) \ + for (pos = cds_list_entry(tp_rcu_dereference_bp((head)->next), __typeof__(*pos), member); \ + &pos->member != (head); \ + pos = cds_list_entry(tp_rcu_dereference_bp(pos->member.next), __typeof__(*pos), member)) + /* * TRACEPOINT_EVENT_CLASS declares a class of tracepoints receiving the * same arguments and having the same field layout. @@ -72,7 +88,7 @@ void _TP_COMBINE_TOKENS(__tracepoint_provider_mismatch_, TRACEPOINT_PROVIDER)(vo #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \ __tracepoint_provider_mismatch_##_provider(); -static __attribute__((unused)) +static inline void _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)(void) { #include TRACEPOINT_INCLUDE @@ -132,11 +148,14 @@ static const char \ .type = \ { \ .atype = atype_array, \ - .u.array = \ + .u = \ { \ - .length = _length, \ - .elem_type = __type_integer(_type, BYTE_ORDER, 10, _encoding), \ - }, \ + .array = \ + { \ + .elem_type = __type_integer(_type, BYTE_ORDER, 10, _encoding), \ + .length = _length, \ + } \ + } \ }, \ .nowrite = _nowrite, \ }, @@ -149,10 +168,13 @@ static const char \ .type = \ { \ .atype = atype_sequence, \ - .u.sequence = \ + .u = \ { \ - .length_type = __type_integer(_length_type, BYTE_ORDER, 10, none), \ - .elem_type = __type_integer(_type, BYTE_ORDER, 10, _encoding), \ + .sequence = \ + { \ + .length_type = __type_integer(_length_type, BYTE_ORDER, 10, none), \ + .elem_type = __type_integer(_type, BYTE_ORDER, 10, _encoding), \ + }, \ }, \ }, \ .nowrite = _nowrite, \ @@ -165,7 +187,10 @@ static const char \ .type = \ { \ .atype = atype_string, \ - .u.basic.string.encoding = lttng_encode_UTF8, \ + .u = \ + { \ + .basic = { .string = { .encoding = lttng_encode_UTF8 } } \ + }, \ }, \ .nowrite = _nowrite, \ }, @@ -277,10 +302,66 @@ size_t __event_get_size__##_provider##___##_name(size_t *__dynamic_len, _TP_ARGS #undef _ctf_integer_ext #define _ctf_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \ if (lttng_is_signed_type(_type)) { \ - int64_t __ctf_tmp_int64 = (int64_t) (_type) (_src); \ + int64_t __ctf_tmp_int64; \ + switch (sizeof(_type)) { \ + case 1: \ + { \ + union { _type t; int8_t v; } __tmp = { (_type) (_src) }; \ + __ctf_tmp_int64 = (int64_t) __tmp.v; \ + break; \ + } \ + case 2: \ + { \ + union { _type t; int16_t v; } __tmp = { (_type) (_src) }; \ + __ctf_tmp_int64 = (int64_t) __tmp.v; \ + break; \ + } \ + case 4: \ + { \ + union { _type t; int32_t v; } __tmp = { (_type) (_src) }; \ + __ctf_tmp_int64 = (int64_t) __tmp.v; \ + break; \ + } \ + case 8: \ + { \ + union { _type t; int64_t v; } __tmp = { (_type) (_src) }; \ + __ctf_tmp_int64 = (int64_t) __tmp.v; \ + break; \ + } \ + default: \ + abort(); \ + }; \ memcpy(__stack_data, &__ctf_tmp_int64, sizeof(int64_t)); \ } else { \ - uint64_t __ctf_tmp_uint64 = (uint64_t) (_type) (_src); \ + uint64_t __ctf_tmp_uint64; \ + switch (sizeof(_type)) { \ + case 1: \ + { \ + union { _type t; uint8_t v; } __tmp = { (_type) (_src) }; \ + __ctf_tmp_uint64 = (uint64_t) __tmp.v; \ + break; \ + } \ + case 2: \ + { \ + union { _type t; uint16_t v; } __tmp = { (_type) (_src) }; \ + __ctf_tmp_uint64 = (uint64_t) __tmp.v; \ + break; \ + } \ + case 4: \ + { \ + union { _type t; uint32_t v; } __tmp = { (_type) (_src) }; \ + __ctf_tmp_uint64 = (uint64_t) __tmp.v; \ + break; \ + } \ + case 8: \ + { \ + union { _type t; uint64_t v; } __tmp = { (_type) (_src) }; \ + __ctf_tmp_uint64 = (uint64_t) __tmp.v; \ + break; \ + } \ + default: \ + abort(); \ + }; \ memcpy(__stack_data, &__ctf_tmp_uint64, sizeof(uint64_t)); \ } \ __stack_data += sizeof(int64_t); @@ -459,6 +540,7 @@ size_t __event_get_align__##_provider##___##_name(_TP_ARGS_PROTO(_args)) \ * 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. + * Perform UNION (||) of filter runtime list. */ #undef TRACEPOINT_EVENT_CLASS #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \ @@ -467,7 +549,7 @@ void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args)); \ static \ void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args)) \ { \ - struct lttng_event *__event = __tp_data; \ + struct lttng_event *__event = (struct lttng_event *) __tp_data; \ struct lttng_channel *__chan = __event->chan; \ struct lttng_ust_lib_ring_buffer_ctx __ctx; \ size_t __event_len, __event_align; \ @@ -486,22 +568,28 @@ void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args)) \ return; \ if (caa_unlikely(!CMM_ACCESS_ONCE(__event->enabled))) \ return; \ - if (caa_unlikely(!cds_list_empty(&__event->bytecode_runtime))) { \ + if (caa_unlikely(!TP_RCU_LINK_TEST())) \ + return; \ + if (caa_unlikely(!cds_list_empty(&__event->bytecode_runtime_head))) { \ struct lttng_bytecode_runtime *bc_runtime; \ + int __filter_record = __event->has_enablers_without_bytecode; \ \ __event_prepare_filter_stack__##_provider##___##_name(__stackvar.__filter_stack_data, \ _TP_ARGS_DATA_VAR(_args)); \ - cds_list_for_each_entry_rcu(bc_runtime, &__event->bytecode_runtime, node) { \ - if (caa_likely(!bc_runtime->filter(bc_runtime, \ - __stackvar.__filter_stack_data))) \ - return; \ + tp_list_for_each_entry_rcu(bc_runtime, &__event->bytecode_runtime_head, node) { \ + if (caa_unlikely(bc_runtime->filter(bc_runtime, \ + __stackvar.__filter_stack_data) & LTTNG_FILTER_RECORD_FLAG)) \ + __filter_record = 1; \ } \ + if (caa_likely(!__filter_record)) \ + 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, \ __event_align, -1, __chan->handle); \ + __ctx.ip = __builtin_return_address(0); \ __ret = __chan->ops->event_reserve(&__ctx, __event->id); \ if (__ret < 0) \ return; \ @@ -591,13 +679,14 @@ static const char * \ __ref_model_emf_uri___##_provider##___##_name \ __attribute__((weakref ("_model_emf_uri___" #_provider "___" #_name)));\ const struct lttng_event_desc __event_desc___##_provider##_##_name = { \ - .fields = __event_fields___##_provider##___##_template, \ .name = #_provider ":" #_name, \ .probe_callback = (void (*)(void)) &__event_probe__##_provider##___##_template,\ + .ctx = NULL, \ + .fields = __event_fields___##_provider##___##_template, \ .nr_fields = _TP_ARRAY_SIZE(__event_fields___##_provider##___##_template), \ .loglevel = &__ref_loglevel___##_provider##___##_name, \ .signature = __tp_event_signature___##_provider##___##_template, \ - .u.ext.model_emf_uri = &__ref_model_emf_uri___##_provider##___##_name, \ + .u = { .ext = { .model_emf_uri = &__ref_model_emf_uri___##_provider##___##_name } }, \ }; #include TRACEPOINT_INCLUDE @@ -631,6 +720,11 @@ 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)), + .head = { NULL, NULL }, + .lazy_init_head = { NULL, NULL }, + .lazy = 0, + .major = LTTNG_UST_PROVIDER_MAJOR, + .minor = LTTNG_UST_PROVIDER_MINOR, }; /* @@ -651,8 +745,20 @@ _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void) { int ret; + /* + * __tracepoint_provider_check_ ## TRACEPOINT_PROVIDER() is a + * static inline function that ensures every probe PROVIDER + * argument match the provider within which they appear. It + * calls empty static inline functions, and therefore has no + * runtime effect. However, if it detects an error, a linker + * error will appear. + */ + _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)(); ret = lttng_probe_register(&_TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER)); - assert(!ret); + if (ret) { + fprintf(stderr, "LTTng-UST: Error (%d) while registering tracepoint probe. Duplicate registration of tracepoint probes having the same name is not allowed.\n", ret); + abort(); + } } static void lttng_ust_notrace __attribute__((destructor))