2 * Copyright (c) 2011-2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 #include <urcu/compiler.h>
26 #include <urcu/rculist.h>
27 #include <lttng/ust-events.h>
28 #include <lttng/ringbuffer-config.h>
29 #include <lttng/ust-compiler.h>
30 #include <lttng/tracepoint.h>
33 #undef tp_list_for_each_entry_rcu
34 #define tp_list_for_each_entry_rcu(pos, head, member) \
35 for (pos = cds_list_entry(tp_rcu_dereference_bp((head)->next), __typeof__(*pos), member); \
36 &pos->member != (head); \
37 pos = cds_list_entry(tp_rcu_dereference_bp(pos->member.next), __typeof__(*pos), member))
40 * TRACEPOINT_EVENT_CLASS declares a class of tracepoints receiving the
41 * same arguments and having the same field layout.
43 * TRACEPOINT_EVENT_INSTANCE declares an instance of a tracepoint, with
44 * its own provider and name. It refers to a class (template).
46 * TRACEPOINT_EVENT declared both a class and an instance and does a
47 * direct mapping from the instance to the class.
50 #undef TRACEPOINT_EVENT
51 #define TRACEPOINT_EVENT(_provider, _name, _args, _fields) \
52 TRACEPOINT_EVENT_CLASS(_provider, _name, \
54 _TP_PARAMS(_fields)) \
55 TRACEPOINT_EVENT_INSTANCE(_provider, _name, _name, \
59 #define _TP_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
61 #define _tp_max_t(type, x, y) \
65 __max1 > __max2 ? __max1: __max2; \
69 * Stage 0 of tracepoint event generation.
71 * Check that each TRACEPOINT_EVENT provider argument match the
72 * TRACEPOINT_PROVIDER by creating dummy callbacks.
75 /* Reset all macros within TRACEPOINT_EVENT */
76 #include <lttng/ust-tracepoint-event-reset.h>
78 static inline lttng_ust_notrace
79 void _TP_COMBINE_TOKENS(__tracepoint_provider_mismatch_
, TRACEPOINT_PROVIDER
)(void);
81 void _TP_COMBINE_TOKENS(__tracepoint_provider_mismatch_
, TRACEPOINT_PROVIDER
)(void)
85 #undef TRACEPOINT_EVENT_CLASS
86 #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
87 __tracepoint_provider_mismatch_##_provider();
89 #undef TRACEPOINT_EVENT_INSTANCE
90 #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
91 __tracepoint_provider_mismatch_##_provider();
93 static inline lttng_ust_notrace
94 void _TP_COMBINE_TOKENS(__tracepoint_provider_check_
, TRACEPOINT_PROVIDER
)(void);
96 void _TP_COMBINE_TOKENS(__tracepoint_provider_check_
, TRACEPOINT_PROVIDER
)(void)
98 #include TRACEPOINT_INCLUDE
102 * Stage 0.1 of tracepoint event generation.
104 * Check that each TRACEPOINT_EVENT provider:name does not exceed the
105 * tracepoint name length limit.
108 /* Reset all macros within TRACEPOINT_EVENT */
109 #include <lttng/ust-tracepoint-event-reset.h>
111 #undef TRACEPOINT_EVENT_INSTANCE
112 #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
114 __tp_name_len_check##_provider##___##_name[LTTNG_UST_SYM_NAME_LEN] \
115 __attribute__((unused)) = \
116 #_provider ":" #_name;
118 #include TRACEPOINT_INCLUDE
121 * Stage 0.9 of tracepoint event generation
123 * Unfolding the enums
125 #include <lttng/ust-tracepoint-event-reset.h>
127 /* Enumeration entry (single value) */
128 #undef ctf_enum_value
129 #define ctf_enum_value(_string, _value) \
130 { _value, _value, _string },
132 /* Enumeration entry (range) */
133 #undef ctf_enum_range
134 #define ctf_enum_range(_string, _range_start, _range_end) \
135 { _range_start, _range_end, _string },
137 #undef TP_ENUM_VALUES
138 #define TP_ENUM_VALUES(...) \
141 #undef TRACEPOINT_ENUM
142 #define TRACEPOINT_ENUM(_provider, _name, _values) \
143 const struct lttng_enum_entry __enum_values__##_provider##_##_name[] = { \
147 #include TRACEPOINT_INCLUDE
150 * Stage 1 of tracepoint event generation.
152 * Create event field type metadata section.
153 * Each event produce an array of fields.
156 /* Reset all macros within TRACEPOINT_EVENT */
157 #include <lttng/ust-tracepoint-event-reset.h>
158 #include <lttng/ust-tracepoint-event-write.h>
159 #include <lttng/ust-tracepoint-event-nowrite.h>
161 #undef _ctf_integer_ext
162 #define _ctf_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \
165 .type = __type_integer(_type, _byte_order, _base, none),\
166 .nowrite = _nowrite, \
170 #define _ctf_float(_type, _item, _src, _nowrite) \
173 .type = __type_float(_type), \
174 .nowrite = _nowrite, \
177 #undef _ctf_array_encoded
178 #define _ctf_array_encoded(_type, _item, _src, _length, _encoding, _nowrite) \
183 .atype = atype_array, \
188 .elem_type = __type_integer(_type, BYTE_ORDER, 10, _encoding), \
193 .nowrite = _nowrite, \
196 #undef _ctf_sequence_encoded
197 #define _ctf_sequence_encoded(_type, _item, _src, \
198 _length_type, _src_length, _encoding, _nowrite, \
204 .atype = atype_sequence, \
209 .length_type = __type_integer(_length_type, BYTE_ORDER, 10, none), \
210 .elem_type = __type_integer(_type, BYTE_ORDER, _elem_type_base, _encoding), \
214 .nowrite = _nowrite, \
218 #define _ctf_string(_item, _src, _nowrite) \
223 .atype = atype_string, \
226 .basic = { .string = { .encoding = lttng_encode_UTF8 } } \
229 .nowrite = _nowrite, \
233 #define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
237 .atype = atype_enum, \
241 .desc = &__enum_##_provider##_##_name, \
242 .container_type = { \
243 .size = sizeof(_type) * CHAR_BIT, \
244 .alignment = lttng_alignof(_type) * CHAR_BIT, \
245 .signedness = lttng_is_signed_type(_type), \
246 .reverse_byte_order = 0, \
248 .encoding = lttng_encode_none, \
254 .nowrite = _nowrite, \
258 #define TP_FIELDS(...) __VA_ARGS__ /* Only one used in this phase */
260 #undef TRACEPOINT_EVENT_CLASS
261 #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
262 static const struct lttng_event_field __event_fields___##_provider##___##_name[] = { \
266 #undef TRACEPOINT_ENUM
267 #define TRACEPOINT_ENUM(_provider, _name, _values) \
268 static const struct lttng_enum_desc __enum_##_provider##_##_name = { \
269 .name = #_provider "_" #_name, \
270 .entries = __enum_values__##_provider##_##_name, \
271 .nr_entries = _TP_ARRAY_SIZE(__enum_values__##_provider##_##_name), \
274 #include TRACEPOINT_INCLUDE
277 * Stage 2 of tracepoint event generation.
279 * Create probe callback prototypes.
282 /* Reset all macros within TRACEPOINT_EVENT */
283 #include <lttng/ust-tracepoint-event-reset.h>
286 #define TP_ARGS(...) __VA_ARGS__
288 #undef TRACEPOINT_EVENT_CLASS
289 #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
290 static void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args));
292 #include TRACEPOINT_INCLUDE
295 * Stage 3.0 of tracepoint event generation.
297 * Create static inline function that calculates event size.
300 /* Reset all macros within TRACEPOINT_EVENT */
301 #include <lttng/ust-tracepoint-event-reset.h>
302 #include <lttng/ust-tracepoint-event-write.h>
304 #undef _ctf_integer_ext
305 #define _ctf_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \
306 __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \
307 __event_len += sizeof(_type);
310 #define _ctf_float(_type, _item, _src, _nowrite) \
311 __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \
312 __event_len += sizeof(_type);
314 #undef _ctf_array_encoded
315 #define _ctf_array_encoded(_type, _item, _src, _length, _encoding, _nowrite) \
316 __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \
317 __event_len += sizeof(_type) * (_length);
319 #undef _ctf_sequence_encoded
320 #define _ctf_sequence_encoded(_type, _item, _src, _length_type, \
321 _src_length, _encoding, _nowrite, _elem_type_base) \
322 __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_length_type)); \
323 __event_len += sizeof(_length_type); \
324 __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \
325 __dynamic_len[__dynamic_len_idx] = (_src_length); \
326 __event_len += sizeof(_type) * __dynamic_len[__dynamic_len_idx]; \
330 #define _ctf_string(_item, _src, _nowrite) \
331 __event_len += __dynamic_len[__dynamic_len_idx++] = strlen(_src) + 1;
334 #define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
335 _ctf_integer_ext(_type, _item, _src, BYTE_ORDER, 10, _nowrite)
338 #define TP_ARGS(...) __VA_ARGS__
341 #define TP_FIELDS(...) __VA_ARGS__
343 #undef TRACEPOINT_EVENT_CLASS
344 #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
345 static inline lttng_ust_notrace \
346 size_t __event_get_size__##_provider##___##_name(size_t *__dynamic_len, _TP_ARGS_DATA_PROTO(_args)); \
348 size_t __event_get_size__##_provider##___##_name(size_t *__dynamic_len, _TP_ARGS_DATA_PROTO(_args)) \
350 size_t __event_len = 0; \
351 unsigned int __dynamic_len_idx = 0; \
354 (void) __dynamic_len_idx; /* don't warn if unused */ \
356 return __event_len; \
359 #include TRACEPOINT_INCLUDE
362 * Stage 3.1 of tracepoint event generation.
364 * Create static inline function that layout the filter stack data.
365 * We make both write and nowrite data available to the filter.
368 /* Reset all macros within TRACEPOINT_EVENT */
369 #include <lttng/ust-tracepoint-event-reset.h>
370 #include <lttng/ust-tracepoint-event-write.h>
371 #include <lttng/ust-tracepoint-event-nowrite.h>
373 #undef _ctf_integer_ext
374 #define _ctf_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \
375 if (lttng_is_signed_type(_type)) { \
376 int64_t __ctf_tmp_int64; \
377 switch (sizeof(_type)) { \
380 union { _type t; int8_t v; } __tmp = { (_type) (_src) }; \
381 __ctf_tmp_int64 = (int64_t) __tmp.v; \
386 union { _type t; int16_t v; } __tmp = { (_type) (_src) }; \
387 __ctf_tmp_int64 = (int64_t) __tmp.v; \
392 union { _type t; int32_t v; } __tmp = { (_type) (_src) }; \
393 __ctf_tmp_int64 = (int64_t) __tmp.v; \
398 union { _type t; int64_t v; } __tmp = { (_type) (_src) }; \
399 __ctf_tmp_int64 = (int64_t) __tmp.v; \
405 memcpy(__stack_data, &__ctf_tmp_int64, sizeof(int64_t)); \
407 uint64_t __ctf_tmp_uint64; \
408 switch (sizeof(_type)) { \
411 union { _type t; uint8_t v; } __tmp = { (_type) (_src) }; \
412 __ctf_tmp_uint64 = (uint64_t) __tmp.v; \
417 union { _type t; uint16_t v; } __tmp = { (_type) (_src) }; \
418 __ctf_tmp_uint64 = (uint64_t) __tmp.v; \
423 union { _type t; uint32_t v; } __tmp = { (_type) (_src) }; \
424 __ctf_tmp_uint64 = (uint64_t) __tmp.v; \
429 union { _type t; uint64_t v; } __tmp = { (_type) (_src) }; \
430 __ctf_tmp_uint64 = (uint64_t) __tmp.v; \
436 memcpy(__stack_data, &__ctf_tmp_uint64, sizeof(uint64_t)); \
438 __stack_data += sizeof(int64_t);
441 #define _ctf_float(_type, _item, _src, _nowrite) \
443 double __ctf_tmp_double = (double) (_type) (_src); \
444 memcpy(__stack_data, &__ctf_tmp_double, sizeof(double)); \
445 __stack_data += sizeof(double); \
448 #undef _ctf_array_encoded
449 #define _ctf_array_encoded(_type, _item, _src, _length, _encoding, _nowrite) \
451 unsigned long __ctf_tmp_ulong = (unsigned long) (_length); \
452 const void *__ctf_tmp_ptr = (_src); \
453 memcpy(__stack_data, &__ctf_tmp_ulong, sizeof(unsigned long)); \
454 __stack_data += sizeof(unsigned long); \
455 memcpy(__stack_data, &__ctf_tmp_ptr, sizeof(void *)); \
456 __stack_data += sizeof(void *); \
459 #undef _ctf_sequence_encoded
460 #define _ctf_sequence_encoded(_type, _item, _src, _length_type, \
461 _src_length, _encoding, _nowrite, _elem_type_base) \
463 unsigned long __ctf_tmp_ulong = (unsigned long) (_src_length); \
464 const void *__ctf_tmp_ptr = (_src); \
465 memcpy(__stack_data, &__ctf_tmp_ulong, sizeof(unsigned long)); \
466 __stack_data += sizeof(unsigned long); \
467 memcpy(__stack_data, &__ctf_tmp_ptr, sizeof(void *)); \
468 __stack_data += sizeof(void *); \
472 #define _ctf_string(_item, _src, _nowrite) \
474 const void *__ctf_tmp_ptr = (_src); \
475 memcpy(__stack_data, &__ctf_tmp_ptr, sizeof(void *)); \
476 __stack_data += sizeof(void *); \
480 #define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
481 _ctf_integer_ext(_type, _item, _src, BYTE_ORDER, 10, _nowrite)
484 #define TP_ARGS(...) __VA_ARGS__
487 #define TP_FIELDS(...) __VA_ARGS__
489 #undef TRACEPOINT_EVENT_CLASS
490 #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
492 void __event_prepare_filter_stack__##_provider##___##_name(char *__stack_data,\
493 _TP_ARGS_DATA_PROTO(_args)) \
498 #include TRACEPOINT_INCLUDE
501 * Stage 4 of tracepoint event generation.
503 * Create static inline function that calculates event payload alignment.
506 /* Reset all macros within TRACEPOINT_EVENT */
507 #include <lttng/ust-tracepoint-event-reset.h>
508 #include <lttng/ust-tracepoint-event-write.h>
510 #undef _ctf_integer_ext
511 #define _ctf_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \
512 __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_type));
515 #define _ctf_float(_type, _item, _src, _nowrite) \
516 __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_type));
518 #undef _ctf_array_encoded
519 #define _ctf_array_encoded(_type, _item, _src, _length, _encoding, _nowrite) \
520 __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_type));
522 #undef _ctf_sequence_encoded
523 #define _ctf_sequence_encoded(_type, _item, _src, _length_type, \
524 _src_length, _encoding, _nowrite, _elem_type_base) \
525 __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_length_type)); \
526 __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_type));
529 #define _ctf_string(_item, _src, _nowrite)
532 #define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
533 _ctf_integer_ext(_type, _item, _src, BYTE_ORDER, 10, _nowrite)
536 #define TP_ARGS(...) __VA_ARGS__
539 #define TP_FIELDS(...) __VA_ARGS__
541 #undef TRACEPOINT_EVENT_CLASS
542 #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
543 static inline lttng_ust_notrace \
544 size_t __event_get_align__##_provider##___##_name(_TP_ARGS_PROTO(_args)); \
546 size_t __event_get_align__##_provider##___##_name(_TP_ARGS_PROTO(_args)) \
548 size_t __event_align = 1; \
550 return __event_align; \
553 #include TRACEPOINT_INCLUDE
557 * Stage 5 of tracepoint event generation.
559 * Create the probe function. This function calls event size calculation
560 * and writes event data into the buffer.
563 /* Reset all macros within TRACEPOINT_EVENT */
564 #include <lttng/ust-tracepoint-event-reset.h>
565 #include <lttng/ust-tracepoint-event-write.h>
567 #undef _ctf_integer_ext
568 #define _ctf_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \
570 _type __tmp = (_src); \
571 lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__tmp));\
572 __chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp));\
576 #define _ctf_float(_type, _item, _src, _nowrite) \
578 _type __tmp = (_src); \
579 lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__tmp));\
580 __chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp));\
583 #undef _ctf_array_encoded
584 #define _ctf_array_encoded(_type, _item, _src, _length, _encoding, _nowrite) \
585 lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_type)); \
586 __chan->ops->event_write(&__ctx, _src, sizeof(_type) * (_length));
588 #undef _ctf_sequence_encoded
589 #define _ctf_sequence_encoded(_type, _item, _src, _length_type, \
590 _src_length, _encoding, _nowrite, _elem_type_base) \
592 _length_type __tmpl = __stackvar.__dynamic_len[__dynamic_len_idx]; \
593 lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_length_type));\
594 __chan->ops->event_write(&__ctx, &__tmpl, sizeof(_length_type));\
596 lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_type)); \
597 __chan->ops->event_write(&__ctx, _src, \
598 sizeof(_type) * __get_dynamic_len(dest));
601 * __chan->ops->u.has_strcpy is a flag letting us know if the LTTng-UST
602 * tracepoint provider ABI implements event_strcpy. This dynamic check
603 * can be removed when the tracepoint provider ABI moves to 2.
605 #if (LTTNG_UST_PROVIDER_MAJOR > 1)
606 #error "Tracepoint probe provider major version has changed. Please remove dynamic check for has_strcpy."
610 #define _ctf_string(_item, _src, _nowrite) \
611 lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(*(_src))); \
612 if (__chan->ops->u.has_strcpy) \
613 __chan->ops->event_strcpy(&__ctx, _src, \
614 __get_dynamic_len(dest)); \
616 __chan->ops->event_write(&__ctx, _src, \
617 __get_dynamic_len(dest));
620 #define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
621 _ctf_integer_ext(_type, _item, _src, BYTE_ORDER, 10, _nowrite)
623 /* Beware: this get len actually consumes the len value */
624 #undef __get_dynamic_len
625 #define __get_dynamic_len(field) __stackvar.__dynamic_len[__dynamic_len_idx++]
628 #define TP_ARGS(...) __VA_ARGS__
631 #define TP_FIELDS(...) __VA_ARGS__
634 * For state dump, check that "session" argument (mandatory) matches the
635 * session this event belongs to. Ensures that we write state dump data only
636 * into the started session, not into all sessions.
638 #undef _TP_SESSION_CHECK
639 #ifdef TP_SESSION_CHECK
640 #define _TP_SESSION_CHECK(session, csession) (session == csession)
641 #else /* TP_SESSION_CHECK */
642 #define _TP_SESSION_CHECK(session, csession) 1
643 #endif /* TP_SESSION_CHECK */
647 #define _TP_IP_PARAM(x) (x)
648 #else /* TP_IP_PARAM */
649 #define _TP_IP_PARAM(x) __builtin_return_address(0)
650 #endif /* TP_IP_PARAM */
653 * Using twice size for filter stack data to hold size and pointer for
654 * each field (worse case). For integers, max size required is 64-bit.
655 * Same for double-precision floats. Those fit within
656 * 2*sizeof(unsigned long) for all supported architectures.
657 * Perform UNION (||) of filter runtime list.
659 #undef TRACEPOINT_EVENT_CLASS
660 #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
661 static lttng_ust_notrace \
662 void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args)); \
664 void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args)) \
666 struct lttng_event *__event = (struct lttng_event *) __tp_data; \
667 struct lttng_channel *__chan = __event->chan; \
668 struct lttng_ust_lib_ring_buffer_ctx __ctx; \
669 struct lttng_stack_ctx __lttng_ctx; \
670 size_t __event_len, __event_align; \
671 size_t __dynamic_len_idx = 0; \
673 size_t __dynamic_len[_TP_ARRAY_SIZE(__event_fields___##_provider##___##_name)]; \
674 char __filter_stack_data[2 * sizeof(unsigned long) * _TP_ARRAY_SIZE(__event_fields___##_provider##___##_name)]; \
679 (void) __dynamic_len_idx; /* don't warn if unused */ \
680 if (!_TP_SESSION_CHECK(session, __chan->session)) \
682 if (caa_unlikely(!CMM_ACCESS_ONCE(__chan->session->active))) \
684 if (caa_unlikely(!CMM_ACCESS_ONCE(__chan->enabled))) \
686 if (caa_unlikely(!CMM_ACCESS_ONCE(__event->enabled))) \
688 if (caa_unlikely(!TP_RCU_LINK_TEST())) \
690 if (caa_unlikely(!cds_list_empty(&__event->bytecode_runtime_head))) { \
691 struct lttng_bytecode_runtime *bc_runtime; \
692 int __filter_record = __event->has_enablers_without_bytecode; \
694 __event_prepare_filter_stack__##_provider##___##_name(__stackvar.__filter_stack_data, \
695 _TP_ARGS_DATA_VAR(_args)); \
696 tp_list_for_each_entry_rcu(bc_runtime, &__event->bytecode_runtime_head, node) { \
697 if (caa_unlikely(bc_runtime->filter(bc_runtime, \
698 __stackvar.__filter_stack_data) & LTTNG_FILTER_RECORD_FLAG)) \
699 __filter_record = 1; \
701 if (caa_likely(!__filter_record)) \
704 __event_len = __event_get_size__##_provider##___##_name(__stackvar.__dynamic_len, \
705 _TP_ARGS_DATA_VAR(_args)); \
706 __event_align = __event_get_align__##_provider##___##_name(_TP_ARGS_VAR(_args)); \
707 memset(&__lttng_ctx, 0, sizeof(__lttng_ctx)); \
708 __lttng_ctx.event = __event; \
709 __lttng_ctx.chan_ctx = tp_rcu_dereference_bp(__chan->ctx); \
710 __lttng_ctx.event_ctx = tp_rcu_dereference_bp(__event->ctx); \
711 lib_ring_buffer_ctx_init(&__ctx, __chan->chan, __event, __event_len, \
712 __event_align, -1, __chan->handle, &__lttng_ctx); \
713 __ctx.ip = _TP_IP_PARAM(TP_IP_PARAM); \
714 __ret = __chan->ops->event_reserve(&__ctx, __event->id); \
718 __chan->ops->event_commit(&__ctx); \
721 #include TRACEPOINT_INCLUDE
723 #undef __get_dynamic_len
726 * Stage 5.1 of tracepoint event generation.
728 * Create probe signature
731 /* Reset all macros within TRACEPOINT_EVENT */
732 #include <lttng/ust-tracepoint-event-reset.h>
735 #define TP_ARGS(...) __VA_ARGS__
737 #define _TP_EXTRACT_STRING2(...) #__VA_ARGS__
739 #undef TRACEPOINT_EVENT_CLASS
740 #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
741 const char __tp_event_signature___##_provider##___##_name[] = \
742 _TP_EXTRACT_STRING2(_args);
744 #include TRACEPOINT_INCLUDE
746 #undef _TP_EXTRACT_STRING2
749 * Stage 6 of tracepoint event generation.
751 * Tracepoint loglevel mapping definition generation. We generate a
752 * symbol for each mapping for a provider/event to ensure at most a 1 to
753 * 1 mapping between events and loglevels. If the symbol is repeated,
754 * the compiler will complain.
757 /* Reset all macros within TRACEPOINT_EVENT */
758 #include <lttng/ust-tracepoint-event-reset.h>
760 #undef TRACEPOINT_LOGLEVEL
761 #define TRACEPOINT_LOGLEVEL(__provider, __name, __loglevel) \
762 static const int _loglevel_value___##__provider##___##__name = __loglevel; \
763 static const int *_loglevel___##__provider##___##__name = \
764 &_loglevel_value___##__provider##___##__name;
766 #include TRACEPOINT_INCLUDE
769 * Stage 6.1 of tracepoint event generation.
771 * Tracepoint UML URI info.
774 /* Reset all macros within TRACEPOINT_EVENT */
775 #include <lttng/ust-tracepoint-event-reset.h>
777 #undef TRACEPOINT_MODEL_EMF_URI
778 #define TRACEPOINT_MODEL_EMF_URI(__provider, __name, __uri) \
779 static const char *_model_emf_uri___##__provider##___##__name = __uri;
781 #include TRACEPOINT_INCLUDE
784 * Stage 7.1 of tracepoint event generation.
786 * Create events description structures. We use a weakref because
787 * loglevels are optional. If not declared, the event will point to the
788 * a loglevel that contains NULL.
791 /* Reset all macros within TRACEPOINT_EVENT */
792 #include <lttng/ust-tracepoint-event-reset.h>
794 #undef TRACEPOINT_EVENT_INSTANCE
795 #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
797 __ref_loglevel___##_provider##___##_name \
798 __attribute__((weakref ("_loglevel___" #_provider "___" #_name))); \
799 static const char * \
800 __ref_model_emf_uri___##_provider##___##_name \
801 __attribute__((weakref ("_model_emf_uri___" #_provider "___" #_name)));\
802 const struct lttng_event_desc __event_desc___##_provider##_##_name = { \
803 .name = #_provider ":" #_name, \
804 .probe_callback = (void (*)(void)) &__event_probe__##_provider##___##_template,\
806 .fields = __event_fields___##_provider##___##_template, \
807 .nr_fields = _TP_ARRAY_SIZE(__event_fields___##_provider##___##_template), \
808 .loglevel = &__ref_loglevel___##_provider##___##_name, \
809 .signature = __tp_event_signature___##_provider##___##_template, \
812 .model_emf_uri = &__ref_model_emf_uri___##_provider##___##_name, \
817 #include TRACEPOINT_INCLUDE
820 * Stage 7.2 of tracepoint event generation.
822 * Create array of events.
825 /* Reset all macros within TRACEPOINT_EVENT */
826 #include <lttng/ust-tracepoint-event-reset.h>
828 #undef TRACEPOINT_EVENT_INSTANCE
829 #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
830 &__event_desc___##_provider##_##_name,
832 static const struct lttng_event_desc
*_TP_COMBINE_TOKENS(__event_desc___
, TRACEPOINT_PROVIDER
)[] = {
833 #include TRACEPOINT_INCLUDE
838 * Stage 8 of tracepoint event generation.
840 * Create a toplevel descriptor for the whole probe.
843 /* non-const because list head will be modified when registered. */
844 static struct lttng_probe_desc
_TP_COMBINE_TOKENS(__probe_desc___
, TRACEPOINT_PROVIDER
) = {
845 .provider
= __tp_stringify(TRACEPOINT_PROVIDER
),
846 .event_desc
= _TP_COMBINE_TOKENS(__event_desc___
, TRACEPOINT_PROVIDER
),
847 .nr_events
= _TP_ARRAY_SIZE(_TP_COMBINE_TOKENS(__event_desc___
, TRACEPOINT_PROVIDER
)),
848 .head
= { NULL
, NULL
},
849 .lazy_init_head
= { NULL
, NULL
},
851 .major
= LTTNG_UST_PROVIDER_MAJOR
,
852 .minor
= LTTNG_UST_PROVIDER_MINOR
,
855 static int _TP_COMBINE_TOKENS(__probe_register_refcount___
, TRACEPOINT_PROVIDER
);
858 * Stage 9 of tracepoint event generation.
860 * Register/unregister probes at module load/unload.
862 * Generate the constructor as an externally visible symbol for use when
863 * linking the probe statically.
865 * Register refcount is protected by libc dynamic loader mutex.
868 /* Reset all macros within TRACEPOINT_EVENT */
869 #include <lttng/ust-tracepoint-event-reset.h>
870 static void lttng_ust_notrace
__attribute__((constructor
))
871 _TP_COMBINE_TOKENS(__lttng_events_init__
, TRACEPOINT_PROVIDER
)(void);
873 _TP_COMBINE_TOKENS(__lttng_events_init__
, TRACEPOINT_PROVIDER
)(void)
877 if (_TP_COMBINE_TOKENS(__probe_register_refcount___
,
878 TRACEPOINT_PROVIDER
)++) {
882 * __tracepoint_provider_check_ ## TRACEPOINT_PROVIDER() is a
883 * static inline function that ensures every probe PROVIDER
884 * argument match the provider within which they appear. It
885 * calls empty static inline functions, and therefore has no
886 * runtime effect. However, if it detects an error, a linker
889 _TP_COMBINE_TOKENS(__tracepoint_provider_check_
, TRACEPOINT_PROVIDER
)();
890 ret
= lttng_probe_register(&_TP_COMBINE_TOKENS(__probe_desc___
, TRACEPOINT_PROVIDER
));
892 fprintf(stderr
, "LTTng-UST: Error (%d) while registering tracepoint probe. Duplicate registration of tracepoint probes having the same name is not allowed.\n", ret
);
897 static void lttng_ust_notrace
__attribute__((destructor
))
898 _TP_COMBINE_TOKENS(__lttng_events_exit__
, TRACEPOINT_PROVIDER
)(void);
900 _TP_COMBINE_TOKENS(__lttng_events_exit__
, TRACEPOINT_PROVIDER
)(void)
902 if (--_TP_COMBINE_TOKENS(__probe_register_refcount___
,
903 TRACEPOINT_PROVIDER
)) {
906 lttng_probe_unregister(&_TP_COMBINE_TOKENS(__probe_desc___
, TRACEPOINT_PROVIDER
));
909 int _TP_COMBINE_TOKENS(__tracepoint_provider_
, TRACEPOINT_PROVIDER
);