Implement dynamic types, and application context provider support
[lttng-ust.git] / include / lttng / ust-tracepoint-event.h
1 /*
2 * Copyright (c) 2011-2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 *
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:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
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
20 * SOFTWARE.
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
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>
31 #include <string.h>
32
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))
38
39 /*
40 * TRACEPOINT_EVENT_CLASS declares a class of tracepoints receiving the
41 * same arguments and having the same field layout.
42 *
43 * TRACEPOINT_EVENT_INSTANCE declares an instance of a tracepoint, with
44 * its own provider and name. It refers to a class (template).
45 *
46 * TRACEPOINT_EVENT declared both a class and an instance and does a
47 * direct mapping from the instance to the class.
48 */
49
50 #undef TRACEPOINT_EVENT
51 #define TRACEPOINT_EVENT(_provider, _name, _args, _fields) \
52 TRACEPOINT_EVENT_CLASS(_provider, _name, \
53 _TP_PARAMS(_args), \
54 _TP_PARAMS(_fields)) \
55 TRACEPOINT_EVENT_INSTANCE(_provider, _name, _name, \
56 _TP_PARAMS(_args))
57
58 /* Helpers */
59 #define _TP_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
60
61 #define _tp_max_t(type, x, y) \
62 ({ \
63 type __max1 = (x); \
64 type __max2 = (y); \
65 __max1 > __max2 ? __max1: __max2; \
66 })
67
68 /*
69 * Stage 0 of tracepoint event generation.
70 *
71 * Check that each TRACEPOINT_EVENT provider argument match the
72 * TRACEPOINT_PROVIDER by creating dummy callbacks.
73 */
74
75 /* Reset all macros within TRACEPOINT_EVENT */
76 #include <lttng/ust-tracepoint-event-reset.h>
77
78 static inline lttng_ust_notrace
79 void _TP_COMBINE_TOKENS(__tracepoint_provider_mismatch_, TRACEPOINT_PROVIDER)(void);
80 static inline
81 void _TP_COMBINE_TOKENS(__tracepoint_provider_mismatch_, TRACEPOINT_PROVIDER)(void)
82 {
83 }
84
85 #undef TRACEPOINT_EVENT_CLASS
86 #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
87 __tracepoint_provider_mismatch_##_provider();
88
89 #undef TRACEPOINT_EVENT_INSTANCE
90 #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
91 __tracepoint_provider_mismatch_##_provider();
92
93 static inline lttng_ust_notrace
94 void _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)(void);
95 static inline
96 void _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)(void)
97 {
98 #include TRACEPOINT_INCLUDE
99 }
100
101 /*
102 * Stage 0.1 of tracepoint event generation.
103 *
104 * Check that each TRACEPOINT_EVENT provider:name does not exceed the
105 * tracepoint name length limit.
106 */
107
108 /* Reset all macros within TRACEPOINT_EVENT */
109 #include <lttng/ust-tracepoint-event-reset.h>
110
111 #undef TRACEPOINT_EVENT_INSTANCE
112 #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
113 static const char \
114 __tp_name_len_check##_provider##___##_name[LTTNG_UST_SYM_NAME_LEN] \
115 __attribute__((unused)) = \
116 #_provider ":" #_name;
117
118 #include TRACEPOINT_INCLUDE
119
120 /*
121 * Stage 0.9 of tracepoint event generation
122 *
123 * Unfolding the enums
124 */
125 #include <lttng/ust-tracepoint-event-reset.h>
126
127 /* Enumeration entry (single value) */
128 #undef ctf_enum_value
129 #define ctf_enum_value(_string, _value) \
130 { _value, _value, _string },
131
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 },
136
137 #undef TP_ENUM_VALUES
138 #define TP_ENUM_VALUES(...) \
139 __VA_ARGS__
140
141 #undef TRACEPOINT_ENUM
142 #define TRACEPOINT_ENUM(_provider, _name, _values) \
143 const struct lttng_enum_entry __enum_values__##_provider##_##_name[] = { \
144 _values \
145 };
146
147 #include TRACEPOINT_INCLUDE
148
149 /*
150 * Stage 1 of tracepoint event generation.
151 *
152 * Create event field type metadata section.
153 * Each event produce an array of fields.
154 */
155
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>
160
161 #undef _ctf_integer_ext
162 #define _ctf_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \
163 { \
164 .name = #_item, \
165 .type = __type_integer(_type, _byte_order, _base, none),\
166 .nowrite = _nowrite, \
167 },
168
169 #undef _ctf_float
170 #define _ctf_float(_type, _item, _src, _nowrite) \
171 { \
172 .name = #_item, \
173 .type = __type_float(_type), \
174 .nowrite = _nowrite, \
175 },
176
177 #undef _ctf_array_encoded
178 #define _ctf_array_encoded(_type, _item, _src, _length, _encoding, _nowrite) \
179 { \
180 .name = #_item, \
181 .type = \
182 { \
183 .atype = atype_array, \
184 .u = \
185 { \
186 .array = \
187 { \
188 .elem_type = __type_integer(_type, BYTE_ORDER, 10, _encoding), \
189 .length = _length, \
190 } \
191 } \
192 }, \
193 .nowrite = _nowrite, \
194 },
195
196 #undef _ctf_sequence_encoded
197 #define _ctf_sequence_encoded(_type, _item, _src, \
198 _length_type, _src_length, _encoding, _nowrite, \
199 _elem_type_base) \
200 { \
201 .name = #_item, \
202 .type = \
203 { \
204 .atype = atype_sequence, \
205 .u = \
206 { \
207 .sequence = \
208 { \
209 .length_type = __type_integer(_length_type, BYTE_ORDER, 10, none), \
210 .elem_type = __type_integer(_type, BYTE_ORDER, _elem_type_base, _encoding), \
211 }, \
212 }, \
213 }, \
214 .nowrite = _nowrite, \
215 },
216
217 #undef _ctf_string
218 #define _ctf_string(_item, _src, _nowrite) \
219 { \
220 .name = #_item, \
221 .type = \
222 { \
223 .atype = atype_string, \
224 .u = \
225 { \
226 .basic = { .string = { .encoding = lttng_encode_UTF8 } } \
227 }, \
228 }, \
229 .nowrite = _nowrite, \
230 },
231
232 #undef _ctf_enum
233 #define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
234 { \
235 .name = #_item, \
236 .type = { \
237 .atype = atype_enum, \
238 .u = { \
239 .basic = { \
240 .enumeration = { \
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, \
247 .base = 10, \
248 .encoding = lttng_encode_none, \
249 }, \
250 }, \
251 }, \
252 }, \
253 }, \
254 .nowrite = _nowrite, \
255 },
256
257 #undef TP_FIELDS
258 #define TP_FIELDS(...) __VA_ARGS__ /* Only one used in this phase */
259
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[] = { \
263 _fields \
264 };
265
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), \
272 };
273
274 #include TRACEPOINT_INCLUDE
275
276 /*
277 * Stage 2 of tracepoint event generation.
278 *
279 * Create probe callback prototypes.
280 */
281
282 /* Reset all macros within TRACEPOINT_EVENT */
283 #include <lttng/ust-tracepoint-event-reset.h>
284
285 #undef TP_ARGS
286 #define TP_ARGS(...) __VA_ARGS__
287
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));
291
292 #include TRACEPOINT_INCLUDE
293
294 /*
295 * Stage 3.0 of tracepoint event generation.
296 *
297 * Create static inline function that calculates event size.
298 */
299
300 /* Reset all macros within TRACEPOINT_EVENT */
301 #include <lttng/ust-tracepoint-event-reset.h>
302 #include <lttng/ust-tracepoint-event-write.h>
303
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);
308
309 #undef _ctf_float
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);
313
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);
318
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]; \
327 __dynamic_len_idx++;
328
329 #undef _ctf_string
330 #define _ctf_string(_item, _src, _nowrite) \
331 __event_len += __dynamic_len[__dynamic_len_idx++] = strlen(_src) + 1;
332
333 #undef _ctf_enum
334 #define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
335 _ctf_integer_ext(_type, _item, _src, BYTE_ORDER, 10, _nowrite)
336
337 #undef TP_ARGS
338 #define TP_ARGS(...) __VA_ARGS__
339
340 #undef TP_FIELDS
341 #define TP_FIELDS(...) __VA_ARGS__
342
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)); \
347 static inline \
348 size_t __event_get_size__##_provider##___##_name(size_t *__dynamic_len, _TP_ARGS_DATA_PROTO(_args)) \
349 { \
350 size_t __event_len = 0; \
351 unsigned int __dynamic_len_idx = 0; \
352 \
353 if (0) \
354 (void) __dynamic_len_idx; /* don't warn if unused */ \
355 _fields \
356 return __event_len; \
357 }
358
359 #include TRACEPOINT_INCLUDE
360
361 /*
362 * Stage 3.1 of tracepoint event generation.
363 *
364 * Create static inline function that layout the filter stack data.
365 * We make both write and nowrite data available to the filter.
366 */
367
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>
372
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)) { \
378 case 1: \
379 { \
380 union { _type t; int8_t v; } __tmp = { (_type) (_src) }; \
381 __ctf_tmp_int64 = (int64_t) __tmp.v; \
382 break; \
383 } \
384 case 2: \
385 { \
386 union { _type t; int16_t v; } __tmp = { (_type) (_src) }; \
387 __ctf_tmp_int64 = (int64_t) __tmp.v; \
388 break; \
389 } \
390 case 4: \
391 { \
392 union { _type t; int32_t v; } __tmp = { (_type) (_src) }; \
393 __ctf_tmp_int64 = (int64_t) __tmp.v; \
394 break; \
395 } \
396 case 8: \
397 { \
398 union { _type t; int64_t v; } __tmp = { (_type) (_src) }; \
399 __ctf_tmp_int64 = (int64_t) __tmp.v; \
400 break; \
401 } \
402 default: \
403 abort(); \
404 }; \
405 memcpy(__stack_data, &__ctf_tmp_int64, sizeof(int64_t)); \
406 } else { \
407 uint64_t __ctf_tmp_uint64; \
408 switch (sizeof(_type)) { \
409 case 1: \
410 { \
411 union { _type t; uint8_t v; } __tmp = { (_type) (_src) }; \
412 __ctf_tmp_uint64 = (uint64_t) __tmp.v; \
413 break; \
414 } \
415 case 2: \
416 { \
417 union { _type t; uint16_t v; } __tmp = { (_type) (_src) }; \
418 __ctf_tmp_uint64 = (uint64_t) __tmp.v; \
419 break; \
420 } \
421 case 4: \
422 { \
423 union { _type t; uint32_t v; } __tmp = { (_type) (_src) }; \
424 __ctf_tmp_uint64 = (uint64_t) __tmp.v; \
425 break; \
426 } \
427 case 8: \
428 { \
429 union { _type t; uint64_t v; } __tmp = { (_type) (_src) }; \
430 __ctf_tmp_uint64 = (uint64_t) __tmp.v; \
431 break; \
432 } \
433 default: \
434 abort(); \
435 }; \
436 memcpy(__stack_data, &__ctf_tmp_uint64, sizeof(uint64_t)); \
437 } \
438 __stack_data += sizeof(int64_t);
439
440 #undef _ctf_float
441 #define _ctf_float(_type, _item, _src, _nowrite) \
442 { \
443 double __ctf_tmp_double = (double) (_type) (_src); \
444 memcpy(__stack_data, &__ctf_tmp_double, sizeof(double)); \
445 __stack_data += sizeof(double); \
446 }
447
448 #undef _ctf_array_encoded
449 #define _ctf_array_encoded(_type, _item, _src, _length, _encoding, _nowrite) \
450 { \
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 *); \
457 }
458
459 #undef _ctf_sequence_encoded
460 #define _ctf_sequence_encoded(_type, _item, _src, _length_type, \
461 _src_length, _encoding, _nowrite, _elem_type_base) \
462 { \
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 *); \
469 }
470
471 #undef _ctf_string
472 #define _ctf_string(_item, _src, _nowrite) \
473 { \
474 const void *__ctf_tmp_ptr = (_src); \
475 memcpy(__stack_data, &__ctf_tmp_ptr, sizeof(void *)); \
476 __stack_data += sizeof(void *); \
477 }
478
479 #undef _ctf_enum
480 #define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
481 _ctf_integer_ext(_type, _item, _src, BYTE_ORDER, 10, _nowrite)
482
483 #undef TP_ARGS
484 #define TP_ARGS(...) __VA_ARGS__
485
486 #undef TP_FIELDS
487 #define TP_FIELDS(...) __VA_ARGS__
488
489 #undef TRACEPOINT_EVENT_CLASS
490 #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
491 static inline \
492 void __event_prepare_filter_stack__##_provider##___##_name(char *__stack_data,\
493 _TP_ARGS_DATA_PROTO(_args)) \
494 { \
495 _fields \
496 }
497
498 #include TRACEPOINT_INCLUDE
499
500 /*
501 * Stage 4 of tracepoint event generation.
502 *
503 * Create static inline function that calculates event payload alignment.
504 */
505
506 /* Reset all macros within TRACEPOINT_EVENT */
507 #include <lttng/ust-tracepoint-event-reset.h>
508 #include <lttng/ust-tracepoint-event-write.h>
509
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));
513
514 #undef _ctf_float
515 #define _ctf_float(_type, _item, _src, _nowrite) \
516 __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_type));
517
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));
521
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));
527
528 #undef _ctf_string
529 #define _ctf_string(_item, _src, _nowrite)
530
531 #undef _ctf_enum
532 #define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
533 _ctf_integer_ext(_type, _item, _src, BYTE_ORDER, 10, _nowrite)
534
535 #undef TP_ARGS
536 #define TP_ARGS(...) __VA_ARGS__
537
538 #undef TP_FIELDS
539 #define TP_FIELDS(...) __VA_ARGS__
540
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)); \
545 static inline \
546 size_t __event_get_align__##_provider##___##_name(_TP_ARGS_PROTO(_args)) \
547 { \
548 size_t __event_align = 1; \
549 _fields \
550 return __event_align; \
551 }
552
553 #include TRACEPOINT_INCLUDE
554
555
556 /*
557 * Stage 5 of tracepoint event generation.
558 *
559 * Create the probe function. This function calls event size calculation
560 * and writes event data into the buffer.
561 */
562
563 /* Reset all macros within TRACEPOINT_EVENT */
564 #include <lttng/ust-tracepoint-event-reset.h>
565 #include <lttng/ust-tracepoint-event-write.h>
566
567 #undef _ctf_integer_ext
568 #define _ctf_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \
569 { \
570 _type __tmp = (_src); \
571 lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__tmp));\
572 __chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp));\
573 }
574
575 #undef _ctf_float
576 #define _ctf_float(_type, _item, _src, _nowrite) \
577 { \
578 _type __tmp = (_src); \
579 lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__tmp));\
580 __chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp));\
581 }
582
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));
587
588 #undef _ctf_sequence_encoded
589 #define _ctf_sequence_encoded(_type, _item, _src, _length_type, \
590 _src_length, _encoding, _nowrite, _elem_type_base) \
591 { \
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));\
595 } \
596 lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_type)); \
597 __chan->ops->event_write(&__ctx, _src, \
598 sizeof(_type) * __get_dynamic_len(dest));
599
600 /*
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.
604 */
605 #if (LTTNG_UST_PROVIDER_MAJOR > 1)
606 #error "Tracepoint probe provider major version has changed. Please remove dynamic check for has_strcpy."
607 #endif
608
609 #undef _ctf_string
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)); \
615 else \
616 __chan->ops->event_write(&__ctx, _src, \
617 __get_dynamic_len(dest));
618
619 #undef _ctf_enum
620 #define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
621 _ctf_integer_ext(_type, _item, _src, BYTE_ORDER, 10, _nowrite)
622
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++]
626
627 #undef TP_ARGS
628 #define TP_ARGS(...) __VA_ARGS__
629
630 #undef TP_FIELDS
631 #define TP_FIELDS(...) __VA_ARGS__
632
633 /*
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.
637 */
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 */
644
645 #undef _TP_IP_PARAM
646 #ifdef TP_IP_PARAM
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 */
651
652 /*
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.
658 */
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)); \
663 static \
664 void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args)) \
665 { \
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; \
672 union { \
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)]; \
675 } __stackvar; \
676 int __ret; \
677 \
678 if (0) \
679 (void) __dynamic_len_idx; /* don't warn if unused */ \
680 if (!_TP_SESSION_CHECK(session, __chan->session)) \
681 return; \
682 if (caa_unlikely(!CMM_ACCESS_ONCE(__chan->session->active))) \
683 return; \
684 if (caa_unlikely(!CMM_ACCESS_ONCE(__chan->enabled))) \
685 return; \
686 if (caa_unlikely(!CMM_ACCESS_ONCE(__event->enabled))) \
687 return; \
688 if (caa_unlikely(!TP_RCU_LINK_TEST())) \
689 return; \
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; \
693 \
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; \
700 } \
701 if (caa_likely(!__filter_record)) \
702 return; \
703 } \
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); \
715 if (__ret < 0) \
716 return; \
717 _fields \
718 __chan->ops->event_commit(&__ctx); \
719 }
720
721 #include TRACEPOINT_INCLUDE
722
723 #undef __get_dynamic_len
724
725 /*
726 * Stage 5.1 of tracepoint event generation.
727 *
728 * Create probe signature
729 */
730
731 /* Reset all macros within TRACEPOINT_EVENT */
732 #include <lttng/ust-tracepoint-event-reset.h>
733
734 #undef TP_ARGS
735 #define TP_ARGS(...) __VA_ARGS__
736
737 #define _TP_EXTRACT_STRING2(...) #__VA_ARGS__
738
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);
743
744 #include TRACEPOINT_INCLUDE
745
746 #undef _TP_EXTRACT_STRING2
747
748 /*
749 * Stage 6 of tracepoint event generation.
750 *
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.
755 */
756
757 /* Reset all macros within TRACEPOINT_EVENT */
758 #include <lttng/ust-tracepoint-event-reset.h>
759
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;
765
766 #include TRACEPOINT_INCLUDE
767
768 /*
769 * Stage 6.1 of tracepoint event generation.
770 *
771 * Tracepoint UML URI info.
772 */
773
774 /* Reset all macros within TRACEPOINT_EVENT */
775 #include <lttng/ust-tracepoint-event-reset.h>
776
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;
780
781 #include TRACEPOINT_INCLUDE
782
783 /*
784 * Stage 7.1 of tracepoint event generation.
785 *
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.
789 */
790
791 /* Reset all macros within TRACEPOINT_EVENT */
792 #include <lttng/ust-tracepoint-event-reset.h>
793
794 #undef TRACEPOINT_EVENT_INSTANCE
795 #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
796 static const int * \
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,\
805 .ctx = NULL, \
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, \
810 .u = { \
811 .ext = { \
812 .model_emf_uri = &__ref_model_emf_uri___##_provider##___##_name, \
813 }, \
814 }, \
815 };
816
817 #include TRACEPOINT_INCLUDE
818
819 /*
820 * Stage 7.2 of tracepoint event generation.
821 *
822 * Create array of events.
823 */
824
825 /* Reset all macros within TRACEPOINT_EVENT */
826 #include <lttng/ust-tracepoint-event-reset.h>
827
828 #undef TRACEPOINT_EVENT_INSTANCE
829 #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
830 &__event_desc___##_provider##_##_name,
831
832 static const struct lttng_event_desc *_TP_COMBINE_TOKENS(__event_desc___, TRACEPOINT_PROVIDER)[] = {
833 #include TRACEPOINT_INCLUDE
834 };
835
836
837 /*
838 * Stage 8 of tracepoint event generation.
839 *
840 * Create a toplevel descriptor for the whole probe.
841 */
842
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 },
850 .lazy = 0,
851 .major = LTTNG_UST_PROVIDER_MAJOR,
852 .minor = LTTNG_UST_PROVIDER_MINOR,
853 };
854
855 static int _TP_COMBINE_TOKENS(__probe_register_refcount___, TRACEPOINT_PROVIDER);
856
857 /*
858 * Stage 9 of tracepoint event generation.
859 *
860 * Register/unregister probes at module load/unload.
861 *
862 * Generate the constructor as an externally visible symbol for use when
863 * linking the probe statically.
864 *
865 * Register refcount is protected by libc dynamic loader mutex.
866 */
867
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);
872 static void
873 _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void)
874 {
875 int ret;
876
877 if (_TP_COMBINE_TOKENS(__probe_register_refcount___,
878 TRACEPOINT_PROVIDER)++) {
879 return;
880 }
881 /*
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
887 * error will appear.
888 */
889 _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)();
890 ret = lttng_probe_register(&_TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER));
891 if (ret) {
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);
893 abort();
894 }
895 }
896
897 static void lttng_ust_notrace __attribute__((destructor))
898 _TP_COMBINE_TOKENS(__lttng_events_exit__, TRACEPOINT_PROVIDER)(void);
899 static void
900 _TP_COMBINE_TOKENS(__lttng_events_exit__, TRACEPOINT_PROVIDER)(void)
901 {
902 if (--_TP_COMBINE_TOKENS(__probe_register_refcount___,
903 TRACEPOINT_PROVIDER)) {
904 return;
905 }
906 lttng_probe_unregister(&_TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER));
907 }
908
909 int _TP_COMBINE_TOKENS(__tracepoint_provider_, TRACEPOINT_PROVIDER);
This page took 0.058491 seconds and 5 git commands to generate.