cec6239e0df0b63de18c10bc0c0cfe1bd40da2bb
[lttng-ust.git] / include / lttng / ust-tracepoint-event.h
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 */
6
7 #include <stdint.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <urcu/compiler.h>
11 #include <urcu/rculist.h>
12 #include <lttng/ust-events.h>
13 #include <lttng/ust-ringbuffer-context.h>
14 #include <lttng/ust-arch.h>
15 #include <lttng/ust-compiler.h>
16 #include <lttng/tracepoint.h>
17 #include <lttng/ust-endian.h>
18 #include <lttng/ust-api-compat.h>
19 #include <string.h>
20
21 #define LTTNG_UST__NULL_STRING "(null)"
22
23 #undef tp_list_for_each_entry_rcu
24 #define tp_list_for_each_entry_rcu(pos, head, member) \
25 for (pos = cds_list_entry(lttng_ust_tp_rcu_dereference((head)->next), __typeof__(*pos), member); \
26 &pos->member != (head); \
27 pos = cds_list_entry(lttng_ust_tp_rcu_dereference(pos->member.next), __typeof__(*pos), member))
28
29 /*
30 * LTTNG_UST_TRACEPOINT_EVENT_CLASS declares a class of tracepoints receiving the
31 * same arguments and having the same field layout.
32 *
33 * LTTNG_UST_TRACEPOINT_EVENT_INSTANCE declares an instance of a tracepoint, with
34 * its own provider and name. It refers to a class (template).
35 *
36 * LTTNG_UST_TRACEPOINT_EVENT declared both a class and an instance and does a
37 * direct mapping from the instance to the class.
38 */
39
40 #undef LTTNG_UST_TRACEPOINT_EVENT
41 #define LTTNG_UST_TRACEPOINT_EVENT(_provider, _name, _args, _fields) \
42 LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, \
43 LTTNG_UST__TP_PARAMS(_args), \
44 LTTNG_UST__TP_PARAMS(_fields)) \
45 LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_provider, _name, _name, \
46 LTTNG_UST__TP_PARAMS(_args))
47
48 #undef LTTNG_UST_TRACEPOINT_EVENT_CLASS
49 #define LTTNG_UST_TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
50 LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, LTTNG_UST__TP_PARAMS(_args), LTTNG_UST__TP_PARAMS(_fields))
51
52 #undef LTTNG_UST_TRACEPOINT_EVENT_INSTANCE
53 #define LTTNG_UST_TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
54 LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, LTTNG_UST__TP_PARAMS(_args))
55
56 /* Helpers */
57 #define LTTNG_UST__TP_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
58
59 #define lttng_ust__tp_max_t(type, x, y) \
60 ({ \
61 type lttng_ust__max1 = (x); \
62 type lttng_ust__max2 = (y); \
63 lttng_ust__max1 > lttng_ust__max2 ? lttng_ust__max1: lttng_ust__max2; \
64 })
65
66 /*
67 * Stage 0 of tracepoint event generation.
68 *
69 * Check that each LTTNG_UST_TRACEPOINT_EVENT provider argument match the
70 * LTTNG_UST_TRACEPOINT_PROVIDER by creating dummy callbacks.
71 */
72
73 /* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
74 #include <lttng/ust-tracepoint-event-reset.h>
75
76 static inline
77 void LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust_tracepoint_provider_mismatch_, LTTNG_UST_TRACEPOINT_PROVIDER)(void)
78 lttng_ust_notrace;
79 static inline
80 void LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust_tracepoint_provider_mismatch_, LTTNG_UST_TRACEPOINT_PROVIDER)(void)
81 {
82 }
83
84 #undef LTTNG_UST__TRACEPOINT_EVENT_CLASS
85 #define LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
86 lttng_ust_tracepoint_provider_mismatch_##_provider();
87
88 #undef LTTNG_UST__TRACEPOINT_EVENT_INSTANCE
89 #define LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
90 lttng_ust_tracepoint_provider_mismatch_##_provider();
91
92 static inline
93 void LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust_tracepoint_provider_check_, LTTNG_UST_TRACEPOINT_PROVIDER)(void)
94 lttng_ust_notrace;
95 static inline
96 void LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust_tracepoint_provider_check_, LTTNG_UST_TRACEPOINT_PROVIDER)(void)
97 {
98 #include LTTNG_UST_TRACEPOINT_INCLUDE
99 }
100
101 /*
102 * Stage 0.1 of tracepoint event generation.
103 *
104 * Check that each LTTNG_UST_TRACEPOINT_EVENT provider:name does not exceed the
105 * tracepoint name length limit.
106 */
107
108 /* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
109 #include <lttng/ust-tracepoint-event-reset.h>
110
111 #undef LTTNG_UST__TRACEPOINT_EVENT_INSTANCE
112 #define LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
113 lttng_ust_tracepoint_validate_name_len(_provider, _name);
114
115 #include LTTNG_UST_TRACEPOINT_INCLUDE
116
117 /*
118 * Stage 0.2 of tracepoint event generation.
119 *
120 * Create dummy trace prototypes for each event class, and for each used
121 * template. This will allow checking whether the prototypes from the
122 * class and the instance using the class actually match.
123 */
124
125 /* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
126 #include <lttng/ust-tracepoint-event-reset.h>
127
128 #undef LTTNG_UST_TP_ARGS
129 #define LTTNG_UST_TP_ARGS(...) __VA_ARGS__
130
131 #undef LTTNG_UST__TRACEPOINT_EVENT_INSTANCE
132 #define LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
133 void lttng_ust__event_template_proto___##_provider##___##_template(LTTNG_UST__TP_ARGS_DATA_PROTO(_args));
134
135 #undef LTTNG_UST__TRACEPOINT_EVENT_CLASS
136 #define LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
137 void lttng_ust__event_template_proto___##_provider##___##_name(LTTNG_UST__TP_ARGS_DATA_PROTO(_args));
138
139 #include LTTNG_UST_TRACEPOINT_INCLUDE
140
141 /*
142 * Stage 0.9 of tracepoint event generation
143 *
144 * Unfolding the enums
145 */
146 #include <lttng/ust-tracepoint-event-reset.h>
147
148 /* Enumeration entry (single value) */
149 #undef lttng_ust_field_enum_value
150 #define lttng_ust_field_enum_value(_string, _value) \
151 LTTNG_UST_COMPOUND_LITERAL(const struct lttng_ust_enum_entry, { \
152 .struct_size = sizeof(struct lttng_ust_enum_entry), \
153 .start = { \
154 .value = lttng_ust_is_signed_type(__typeof__(_value)) ? \
155 (long long) (_value) : (_value), \
156 .signedness = lttng_ust_is_signed_type(__typeof__(_value)), \
157 }, \
158 .end = { \
159 .value = lttng_ust_is_signed_type(__typeof__(_value)) ? \
160 (long long) (_value) : (_value), \
161 .signedness = lttng_ust_is_signed_type(__typeof__(_value)), \
162 }, \
163 .string = (_string), \
164 }),
165
166 /* Enumeration entry (range) */
167 #undef lttng_ust_field_enum_range
168 #define lttng_ust_field_enum_range(_string, _range_start, _range_end) \
169 LTTNG_UST_COMPOUND_LITERAL(const struct lttng_ust_enum_entry, { \
170 .struct_size = sizeof(struct lttng_ust_enum_entry), \
171 .start = { \
172 .value = lttng_ust_is_signed_type(__typeof__(_range_start)) ? \
173 (long long) (_range_start) : (_range_start), \
174 .signedness = lttng_ust_is_signed_type(__typeof__(_range_start)), \
175 }, \
176 .end = { \
177 .value = lttng_ust_is_signed_type(__typeof__(_range_end)) ? \
178 (long long) (_range_end) : (_range_end), \
179 .signedness = lttng_ust_is_signed_type(__typeof__(_range_end)), \
180 }, \
181 .string = (_string), \
182 }),
183
184 /* Enumeration entry (automatic value; follows the rules of CTF) */
185 #undef lttng_ust_field_enum_auto
186 #define lttng_ust_field_enum_auto(_string) \
187 LTTNG_UST_COMPOUND_LITERAL(const struct lttng_ust_enum_entry, { \
188 .struct_size = sizeof(struct lttng_ust_enum_entry), \
189 .start = { \
190 .value = -1ULL, \
191 .signedness = 0, \
192 }, \
193 .end = { \
194 .value = -1ULL, \
195 .signedness = 0, \
196 }, \
197 .string = (_string), \
198 .options = LTTNG_UST_ENUM_ENTRY_OPTION_IS_AUTO, \
199 }),
200
201 #undef LTTNG_UST_TP_ENUM_VALUES
202 #define LTTNG_UST_TP_ENUM_VALUES(...) \
203 __VA_ARGS__
204
205 #if LTTNG_UST_COMPAT_API(0)
206 # undef TP_ENUM_VALUES
207 # define TP_ENUM_VALUES LTTNG_UST_TP_ENUM_VALUES
208 #endif /* #if LTTNG_UST_COMPAT_API(0) */
209
210 #undef LTTNG_UST_TRACEPOINT_ENUM
211 #define LTTNG_UST_TRACEPOINT_ENUM(_provider, _name, _values) \
212 const struct lttng_ust_enum_entry * const __enum_values__##_provider##_##_name[] = { \
213 _values \
214 lttng_ust_field_enum_value("", 0) /* Dummy, 0-len array forbidden by C99. */ \
215 };
216 #include LTTNG_UST_TRACEPOINT_INCLUDE
217
218 /*
219 * Stage 0.9.1
220 * Verifying array and sequence elements are of an integer type.
221 */
222
223 /* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
224 #include <lttng/ust-tracepoint-event-reset.h>
225 #include <lttng/ust-tracepoint-event-write.h>
226 #include <lttng/ust-tracepoint-event-nowrite.h>
227
228 #undef lttng_ust__field_array_encoded
229 #define lttng_ust__field_array_encoded(_type, _item, _src, _byte_order, \
230 _length, _encoding, _nowrite, \
231 _elem_type_base) \
232 lttng_ust_field_array_element_type_is_supported(_type, _item);
233
234 #undef lttng_ust__field_sequence_encoded
235 #define lttng_ust__field_sequence_encoded(_type, _item, _src, _byte_order, \
236 _length_type, _src_length, _encoding, _nowrite, \
237 _elem_type_base) \
238 lttng_ust_field_array_element_type_is_supported(_type, _item);
239
240 #undef LTTNG_UST_TP_FIELDS
241 #define LTTNG_UST_TP_FIELDS(...) __VA_ARGS__ /* Only one used in this phase */
242
243 #undef LTTNG_UST__TRACEPOINT_EVENT_CLASS
244 #define LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
245 _fields
246
247 #include LTTNG_UST_TRACEPOINT_INCLUDE
248
249 /*
250 * Stage 1 of tracepoint event generation.
251 *
252 * Create event field type metadata section.
253 * Each event produce an array of fields.
254 */
255
256 /* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
257 #include <lttng/ust-tracepoint-event-reset.h>
258 #include <lttng/ust-tracepoint-event-write.h>
259 #include <lttng/ust-tracepoint-event-nowrite.h>
260
261 #undef lttng_ust__field_integer_ext
262 #define lttng_ust__field_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \
263 LTTNG_UST_COMPOUND_LITERAL(const struct lttng_ust_event_field, { \
264 .struct_size = sizeof(struct lttng_ust_event_field), \
265 .name = #_item, \
266 .type = lttng_ust_type_integer_define(_type, _byte_order, _base), \
267 .nowrite = _nowrite, \
268 .nofilter = 0, \
269 }),
270
271 #undef lttng_ust__field_float
272 #define lttng_ust__field_float(_type, _item, _src, _nowrite) \
273 LTTNG_UST_COMPOUND_LITERAL(const struct lttng_ust_event_field, { \
274 .struct_size = sizeof(struct lttng_ust_event_field), \
275 .name = #_item, \
276 .type = lttng_ust_type_float_define(_type), \
277 .nowrite = _nowrite, \
278 .nofilter = 0, \
279 }),
280
281 #undef lttng_ust__field_array_encoded
282 #define lttng_ust__field_array_encoded(_type, _item, _src, _byte_order, \
283 _length, _encoding, _nowrite, \
284 _elem_type_base) \
285 LTTNG_UST_COMPOUND_LITERAL(const struct lttng_ust_event_field, { \
286 .struct_size = sizeof(struct lttng_ust_event_field), \
287 .name = #_item, \
288 .type = (const struct lttng_ust_type_common *) LTTNG_UST_COMPOUND_LITERAL(const struct lttng_ust_type_array, { \
289 .parent = { \
290 .type = lttng_ust_type_array, \
291 }, \
292 .struct_size = sizeof(struct lttng_ust_type_array), \
293 .elem_type = lttng_ust_type_integer_define(_type, _byte_order, _elem_type_base), \
294 .length = _length, \
295 .alignment = 0, \
296 .encoding = lttng_ust_string_encoding_##_encoding, \
297 }), \
298 .nowrite = _nowrite, \
299 .nofilter = 0, \
300 }),
301
302 #undef lttng_ust__field_sequence_encoded
303 #define lttng_ust__field_sequence_encoded(_type, _item, _src, _byte_order, \
304 _length_type, _src_length, _encoding, _nowrite, \
305 _elem_type_base) \
306 LTTNG_UST_COMPOUND_LITERAL(const struct lttng_ust_event_field, { \
307 .struct_size = sizeof(struct lttng_ust_event_field), \
308 .name = "_" #_item "_length", \
309 .type = lttng_ust_type_integer_define(_length_type, LTTNG_UST_BYTE_ORDER, 10), \
310 .nowrite = _nowrite, \
311 .nofilter = 1, \
312 }), \
313 LTTNG_UST_COMPOUND_LITERAL(const struct lttng_ust_event_field, { \
314 .struct_size = sizeof(struct lttng_ust_event_field), \
315 .name = #_item, \
316 .type = (const struct lttng_ust_type_common *) LTTNG_UST_COMPOUND_LITERAL(const struct lttng_ust_type_sequence, { \
317 .parent = { \
318 .type = lttng_ust_type_sequence, \
319 }, \
320 .struct_size = sizeof(struct lttng_ust_type_sequence), \
321 .length_name = "_" #_item "_length", \
322 .elem_type = lttng_ust_type_integer_define(_type, _byte_order, _elem_type_base), \
323 .alignment = 0, \
324 .encoding = lttng_ust_string_encoding_##_encoding, \
325 }), \
326 .nowrite = _nowrite, \
327 .nofilter = 0, \
328 }),
329
330 #undef lttng_ust__field_string
331 #define lttng_ust__field_string(_item, _src, _nowrite) \
332 LTTNG_UST_COMPOUND_LITERAL(const struct lttng_ust_event_field, { \
333 .struct_size = sizeof(struct lttng_ust_event_field), \
334 .name = #_item, \
335 .type = (const struct lttng_ust_type_common *) LTTNG_UST_COMPOUND_LITERAL(const struct lttng_ust_type_string, { \
336 .parent = { \
337 .type = lttng_ust_type_string, \
338 }, \
339 .struct_size = sizeof(struct lttng_ust_type_string), \
340 .encoding = lttng_ust_string_encoding_UTF8, \
341 }), \
342 .nowrite = _nowrite, \
343 .nofilter = 0, \
344 }),
345
346 #undef lttng_ust__field_unused
347 #define lttng_ust__field_unused(_src)
348
349 #undef lttng_ust__field_enum
350 #define lttng_ust__field_enum(_provider, _name, _type, _item, _src, _nowrite) \
351 LTTNG_UST_COMPOUND_LITERAL(const struct lttng_ust_event_field, { \
352 .struct_size = sizeof(struct lttng_ust_event_field), \
353 .name = #_item, \
354 .type = (const struct lttng_ust_type_common *) LTTNG_UST_COMPOUND_LITERAL(const struct lttng_ust_type_enum, { \
355 .parent = { \
356 .type = lttng_ust_type_enum, \
357 }, \
358 .struct_size = sizeof(struct lttng_ust_type_enum), \
359 .desc = &__enum_##_provider##_##_name, \
360 .container_type = lttng_ust_type_integer_define(_type, LTTNG_UST_BYTE_ORDER, 10), \
361 }), \
362 .nowrite = _nowrite, \
363 .nofilter = 0, \
364 }),
365
366 #undef LTTNG_UST_TP_FIELDS
367 #define LTTNG_UST_TP_FIELDS(...) __VA_ARGS__ /* Only one used in this phase */
368
369 #undef LTTNG_UST__TRACEPOINT_EVENT_CLASS
370 #define LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
371 static const struct lttng_ust_event_field * const lttng_ust__event_fields___##_provider##___##_name[] = { \
372 _fields \
373 lttng_ust_field_integer(int, dummy, 0) /* Dummy, C99 forbids 0-len array. */ \
374 };
375
376 #undef LTTNG_UST_TRACEPOINT_ENUM
377 #define LTTNG_UST_TRACEPOINT_ENUM(_provider, _name, _values) \
378 static const struct lttng_ust_enum_desc __enum_##_provider##_##_name = { \
379 .struct_size = sizeof(struct lttng_ust_enum_desc), \
380 .name = #_provider "_" #_name, \
381 .entries = __enum_values__##_provider##_##_name, \
382 .nr_entries = LTTNG_UST__TP_ARRAY_SIZE(__enum_values__##_provider##_##_name) - 1, \
383 };
384
385 #include LTTNG_UST_TRACEPOINT_INCLUDE
386
387 /*
388 * Stage 2 of tracepoint event generation.
389 *
390 * Create probe callback prototypes.
391 */
392
393 /* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
394 #include <lttng/ust-tracepoint-event-reset.h>
395
396 #undef LTTNG_UST_TP_ARGS
397 #define LTTNG_UST_TP_ARGS(...) __VA_ARGS__
398
399 #undef LTTNG_UST__TRACEPOINT_EVENT_CLASS
400 #define LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
401 static void lttng_ust__event_probe__##_provider##___##_name(LTTNG_UST__TP_ARGS_DATA_PROTO(_args));
402
403 #include LTTNG_UST_TRACEPOINT_INCLUDE
404
405 /*
406 * Stage 3.0 of tracepoint event generation.
407 *
408 * Create static inline function that calculates event size.
409 */
410
411 /* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
412 #include <lttng/ust-tracepoint-event-reset.h>
413 #include <lttng/ust-tracepoint-event-write.h>
414
415 #undef lttng_ust__field_integer_ext
416 #define lttng_ust__field_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \
417 if (0) \
418 (void) (_src); /* Unused */ \
419 __event_len += lttng_ust_ring_buffer_align(__event_len, lttng_ust_rb_alignof(_type)); \
420 __event_len += sizeof(_type);
421
422 #undef lttng_ust__field_float
423 #define lttng_ust__field_float(_type, _item, _src, _nowrite) \
424 if (0) \
425 (void) (_src); /* Unused */ \
426 __event_len += lttng_ust_ring_buffer_align(__event_len, lttng_ust_rb_alignof(_type)); \
427 __event_len += sizeof(_type);
428
429 #undef lttng_ust__field_array_encoded
430 #define lttng_ust__field_array_encoded(_type, _item, _src, _byte_order, _length, _encoding, \
431 _nowrite, _elem_type_base) \
432 if (0) \
433 (void) (_src); /* Unused */ \
434 __event_len += lttng_ust_ring_buffer_align(__event_len, lttng_ust_rb_alignof(_type)); \
435 __event_len += sizeof(_type) * (_length);
436
437 #undef lttng_ust__field_sequence_encoded
438 #define lttng_ust__field_sequence_encoded(_type, _item, _src, _byte_order, _length_type, \
439 _src_length, _encoding, _nowrite, _elem_type_base) \
440 if (0) \
441 (void) (_src); /* Unused */ \
442 __event_len += lttng_ust_ring_buffer_align(__event_len, lttng_ust_rb_alignof(_length_type)); \
443 __event_len += sizeof(_length_type); \
444 __event_len += lttng_ust_ring_buffer_align(__event_len, lttng_ust_rb_alignof(_type)); \
445 __dynamic_len[__dynamic_len_idx] = (_src_length); \
446 __event_len += sizeof(_type) * __dynamic_len[__dynamic_len_idx]; \
447 __dynamic_len_idx++;
448
449 #undef lttng_ust__field_string
450 #define lttng_ust__field_string(_item, _src, _nowrite) \
451 __event_len += __dynamic_len[__dynamic_len_idx++] = \
452 strlen((_src) ? (_src) : LTTNG_UST__NULL_STRING) + 1;
453
454 #undef lttng_ust__field_unused
455 #define lttng_ust__field_unused(_src) \
456 if (0) \
457 (void) (_src); /* Unused */
458
459 #undef lttng_ust__field_enum
460 #define lttng_ust__field_enum(_provider, _name, _type, _item, _src, _nowrite) \
461 lttng_ust__field_integer_ext(_type, _item, _src, LTTNG_UST_BYTE_ORDER, 10, _nowrite)
462
463 #undef LTTNG_UST_TP_ARGS
464 #define LTTNG_UST_TP_ARGS(...) __VA_ARGS__
465
466 #undef LTTNG_UST_TP_FIELDS
467 #define LTTNG_UST_TP_FIELDS(...) __VA_ARGS__
468
469 #undef LTTNG_UST__TRACEPOINT_EVENT_CLASS
470 #define LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
471 static inline \
472 size_t lttng_ust__event_get_size__##_provider##___##_name(size_t *__dynamic_len, LTTNG_UST__TP_ARGS_DATA_PROTO(_args)) \
473 lttng_ust_notrace; \
474 static inline \
475 size_t lttng_ust__event_get_size__##_provider##___##_name( \
476 size_t *__dynamic_len __attribute__((__unused__)), \
477 LTTNG_UST__TP_ARGS_DATA_PROTO(_args)) \
478 { \
479 size_t __event_len = 0; \
480 unsigned int __dynamic_len_idx __attribute__((__unused__)) = 0; \
481 \
482 if (0) \
483 (void) __tp_data; /* don't warn if unused */ \
484 \
485 _fields \
486 return __event_len; \
487 }
488
489 #include LTTNG_UST_TRACEPOINT_INCLUDE
490
491 /*
492 * Stage 3.1 of tracepoint event generation.
493 *
494 * Create static inline function that layout the filter stack data.
495 * We make both write and nowrite data available to the filter.
496 */
497
498 /* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
499 #include <lttng/ust-tracepoint-event-reset.h>
500 #include <lttng/ust-tracepoint-event-write.h>
501 #include <lttng/ust-tracepoint-event-nowrite.h>
502
503 #undef lttng_ust__field_integer_ext
504 #define lttng_ust__field_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \
505 if (lttng_ust_is_signed_type(_type)) { \
506 int64_t __ctf_tmp_int64; \
507 switch (sizeof(_type)) { \
508 case 1: \
509 { \
510 union { _type t; int8_t v; } __tmp = { (_type) (_src) }; \
511 __ctf_tmp_int64 = (int64_t) __tmp.v; \
512 break; \
513 } \
514 case 2: \
515 { \
516 union { _type t; int16_t v; } __tmp = { (_type) (_src) }; \
517 if (_byte_order != LTTNG_UST_BYTE_ORDER) \
518 __tmp.v = lttng_ust_bswap_16(__tmp.v); \
519 __ctf_tmp_int64 = (int64_t) __tmp.v; \
520 break; \
521 } \
522 case 4: \
523 { \
524 union { _type t; int32_t v; } __tmp = { (_type) (_src) }; \
525 if (_byte_order != LTTNG_UST_BYTE_ORDER) \
526 __tmp.v = lttng_ust_bswap_32(__tmp.v); \
527 __ctf_tmp_int64 = (int64_t) __tmp.v; \
528 break; \
529 } \
530 case 8: \
531 { \
532 union { _type t; int64_t v; } __tmp = { (_type) (_src) }; \
533 if (_byte_order != LTTNG_UST_BYTE_ORDER) \
534 __tmp.v = lttng_ust_bswap_64(__tmp.v); \
535 __ctf_tmp_int64 = (int64_t) __tmp.v; \
536 break; \
537 } \
538 default: \
539 abort(); \
540 }; \
541 memcpy(__stack_data, &__ctf_tmp_int64, sizeof(int64_t)); \
542 } else { \
543 uint64_t __ctf_tmp_uint64; \
544 switch (sizeof(_type)) { \
545 case 1: \
546 { \
547 union { _type t; uint8_t v; } __tmp = { (_type) (_src) }; \
548 __ctf_tmp_uint64 = (uint64_t) __tmp.v; \
549 break; \
550 } \
551 case 2: \
552 { \
553 union { _type t; uint16_t v; } __tmp = { (_type) (_src) }; \
554 if (_byte_order != LTTNG_UST_BYTE_ORDER) \
555 __tmp.v = lttng_ust_bswap_16(__tmp.v); \
556 __ctf_tmp_uint64 = (uint64_t) __tmp.v; \
557 break; \
558 } \
559 case 4: \
560 { \
561 union { _type t; uint32_t v; } __tmp = { (_type) (_src) }; \
562 if (_byte_order != LTTNG_UST_BYTE_ORDER) \
563 __tmp.v = lttng_ust_bswap_32(__tmp.v); \
564 __ctf_tmp_uint64 = (uint64_t) __tmp.v; \
565 break; \
566 } \
567 case 8: \
568 { \
569 union { _type t; uint64_t v; } __tmp = { (_type) (_src) }; \
570 if (_byte_order != LTTNG_UST_BYTE_ORDER) \
571 __tmp.v = lttng_ust_bswap_64(__tmp.v); \
572 __ctf_tmp_uint64 = (uint64_t) __tmp.v; \
573 break; \
574 } \
575 default: \
576 abort(); \
577 }; \
578 memcpy(__stack_data, &__ctf_tmp_uint64, sizeof(uint64_t)); \
579 } \
580 __stack_data += sizeof(int64_t);
581
582 #undef lttng_ust__field_float
583 #define lttng_ust__field_float(_type, _item, _src, _nowrite) \
584 { \
585 double __ctf_tmp_double = (double) (_type) (_src); \
586 memcpy(__stack_data, &__ctf_tmp_double, sizeof(double)); \
587 __stack_data += sizeof(double); \
588 }
589
590 #undef lttng_ust__field_array_encoded
591 #define lttng_ust__field_array_encoded(_type, _item, _src, _byte_order, _length, \
592 _encoding, _nowrite, _elem_type_base) \
593 { \
594 unsigned long __ctf_tmp_ulong = (unsigned long) (_length); \
595 const void *__ctf_tmp_ptr = (_src); \
596 memcpy(__stack_data, &__ctf_tmp_ulong, sizeof(unsigned long)); \
597 __stack_data += sizeof(unsigned long); \
598 memcpy(__stack_data, &__ctf_tmp_ptr, sizeof(void *)); \
599 __stack_data += sizeof(void *); \
600 }
601
602 #undef lttng_ust__field_sequence_encoded
603 #define lttng_ust__field_sequence_encoded(_type, _item, _src, _byte_order, _length_type, \
604 _src_length, _encoding, _nowrite, _elem_type_base) \
605 { \
606 unsigned long __ctf_tmp_ulong = (unsigned long) (_src_length); \
607 const void *__ctf_tmp_ptr = (_src); \
608 memcpy(__stack_data, &__ctf_tmp_ulong, sizeof(unsigned long)); \
609 __stack_data += sizeof(unsigned long); \
610 memcpy(__stack_data, &__ctf_tmp_ptr, sizeof(void *)); \
611 __stack_data += sizeof(void *); \
612 }
613
614 #undef lttng_ust__field_string
615 #define lttng_ust__field_string(_item, _src, _nowrite) \
616 { \
617 const void *__ctf_tmp_ptr = \
618 ((_src) ? (_src) : LTTNG_UST__NULL_STRING); \
619 memcpy(__stack_data, &__ctf_tmp_ptr, sizeof(void *)); \
620 __stack_data += sizeof(void *); \
621 }
622
623 #undef lttng_ust__field_unused
624 #define lttng_ust__field_unused(_src) \
625 if (0) \
626 (void) (_src);
627
628 #undef lttng_ust__field_enum
629 #define lttng_ust__field_enum(_provider, _name, _type, _item, _src, _nowrite) \
630 lttng_ust__field_integer_ext(_type, _item, _src, LTTNG_UST_BYTE_ORDER, 10, _nowrite)
631
632 #undef LTTNG_UST_TP_ARGS
633 #define LTTNG_UST_TP_ARGS(...) __VA_ARGS__
634
635 #undef LTTNG_UST_TP_FIELDS
636 #define LTTNG_UST_TP_FIELDS(...) __VA_ARGS__
637
638 #undef LTTNG_UST__TRACEPOINT_EVENT_CLASS
639 #define LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
640 static inline \
641 void lttng_ust__event_prepare_interpreter_stack__##_provider##___##_name(char *__stack_data,\
642 LTTNG_UST__TP_ARGS_DATA_PROTO(_args)) \
643 { \
644 if (0) { \
645 (void) __tp_data; /* don't warn if unused */ \
646 (void) __stack_data; /* don't warn if unused */ \
647 } \
648 \
649 _fields \
650 }
651
652 #include LTTNG_UST_TRACEPOINT_INCLUDE
653
654 /*
655 * Stage 4 of tracepoint event generation.
656 *
657 * Create static inline function that calculates event payload alignment.
658 */
659
660 /* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
661 #include <lttng/ust-tracepoint-event-reset.h>
662 #include <lttng/ust-tracepoint-event-write.h>
663
664 #undef lttng_ust__field_integer_ext
665 #define lttng_ust__field_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \
666 if (0) \
667 (void) (_src); /* Unused */ \
668 lttng_ust__event_align = lttng_ust__tp_max_t(size_t, lttng_ust__event_align, lttng_ust_rb_alignof(_type));
669
670 #undef lttng_ust__field_float
671 #define lttng_ust__field_float(_type, _item, _src, _nowrite) \
672 if (0) \
673 (void) (_src); /* Unused */ \
674 lttng_ust__event_align = lttng_ust__tp_max_t(size_t, lttng_ust__event_align, lttng_ust_rb_alignof(_type));
675
676 #undef lttng_ust__field_array_encoded
677 #define lttng_ust__field_array_encoded(_type, _item, _src, _byte_order, _length, \
678 _encoding, _nowrite, _elem_type_base) \
679 if (0) \
680 (void) (_src); /* Unused */ \
681 lttng_ust__event_align = lttng_ust__tp_max_t(size_t, lttng_ust__event_align, lttng_ust_rb_alignof(_type));
682
683 #undef lttng_ust__field_sequence_encoded
684 #define lttng_ust__field_sequence_encoded(_type, _item, _src, _byte_order, _length_type, \
685 _src_length, _encoding, _nowrite, _elem_type_base) \
686 if (0) \
687 (void) (_src); /* Unused */ \
688 if (0) \
689 (void) (_src_length); /* Unused */ \
690 lttng_ust__event_align = lttng_ust__tp_max_t(size_t, lttng_ust__event_align, lttng_ust_rb_alignof(_length_type)); \
691 lttng_ust__event_align = lttng_ust__tp_max_t(size_t, lttng_ust__event_align, lttng_ust_rb_alignof(_type));
692
693 #undef lttng_ust__field_string
694 #define lttng_ust__field_string(_item, _src, _nowrite) \
695 if (0) \
696 (void) (_src); /* Unused */
697
698 #undef lttng_ust__field_unused
699 #define lttng_ust__field_unused(_src) \
700 if (0) \
701 (void) (_src); /* Unused */
702
703 #undef lttng_ust__field_enum
704 #define lttng_ust__field_enum(_provider, _name, _type, _item, _src, _nowrite) \
705 lttng_ust__field_integer_ext(_type, _item, _src, LTTNG_UST_BYTE_ORDER, 10, _nowrite)
706
707 #undef LTTNG_UST_TP_ARGS
708 #define LTTNG_UST_TP_ARGS(...) __VA_ARGS__
709
710 #undef LTTNG_UST_TP_FIELDS
711 #define LTTNG_UST_TP_FIELDS(...) __VA_ARGS__
712
713 #undef LTTNG_UST__TRACEPOINT_EVENT_CLASS
714 #define LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
715 static inline \
716 size_t lttng_ust__event_get_align__##_provider##___##_name(LTTNG_UST__TP_ARGS_PROTO(_args)) \
717 lttng_ust_notrace; \
718 static inline \
719 size_t lttng_ust__event_get_align__##_provider##___##_name(LTTNG_UST__TP_ARGS_PROTO(_args)) \
720 { \
721 size_t lttng_ust__event_align = 1; \
722 _fields \
723 return lttng_ust__event_align; \
724 }
725
726 #include LTTNG_UST_TRACEPOINT_INCLUDE
727
728
729 /*
730 * Stage 5 of tracepoint event generation.
731 *
732 * Create the probe function. This function calls event size calculation
733 * and writes event data into the buffer.
734 */
735
736 /* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
737 #include <lttng/ust-tracepoint-event-reset.h>
738 #include <lttng/ust-tracepoint-event-write.h>
739
740 #undef lttng_ust__field_integer_ext
741 #define lttng_ust__field_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \
742 { \
743 _type __tmp = (_src); \
744 __chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp), lttng_ust_rb_alignof(__tmp));\
745 }
746
747 #undef lttng_ust__field_float
748 #define lttng_ust__field_float(_type, _item, _src, _nowrite) \
749 { \
750 _type __tmp = (_src); \
751 __chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp), lttng_ust_rb_alignof(__tmp));\
752 }
753
754 #undef lttng_ust__field_array_encoded
755 #define lttng_ust__field_array_encoded(_type, _item, _src, _byte_order, _length, \
756 _encoding, _nowrite, _elem_type_base) \
757 if (lttng_ust_string_encoding_##_encoding == lttng_ust_string_encoding_none) \
758 __chan->ops->event_write(&__ctx, _src, sizeof(_type) * (_length), lttng_ust_rb_alignof(_type)); \
759 else \
760 __chan->ops->event_pstrcpy_pad(&__ctx, (const char *) (_src), _length); \
761
762 #undef lttng_ust__field_sequence_encoded
763 #define lttng_ust__field_sequence_encoded(_type, _item, _src, _byte_order, _length_type, \
764 _src_length, _encoding, _nowrite, _elem_type_base) \
765 { \
766 _length_type __tmpl = __stackvar.__dynamic_len[__dynamic_len_idx]; \
767 __chan->ops->event_write(&__ctx, &__tmpl, sizeof(_length_type), lttng_ust_rb_alignof(_length_type));\
768 } \
769 if (lttng_ust_string_encoding_##_encoding == lttng_ust_string_encoding_none) \
770 __chan->ops->event_write(&__ctx, _src, \
771 sizeof(_type) * lttng_ust__get_dynamic_len(dest), lttng_ust_rb_alignof(_type)); \
772 else \
773 __chan->ops->event_pstrcpy_pad(&__ctx, (const char *) (_src), lttng_ust__get_dynamic_len(dest)); \
774
775 #undef lttng_ust__field_string
776 #define lttng_ust__field_string(_item, _src, _nowrite) \
777 { \
778 const char *__ctf_tmp_string = \
779 ((_src) ? (_src) : LTTNG_UST__NULL_STRING); \
780 __chan->ops->event_strcpy(&__ctx, __ctf_tmp_string, \
781 lttng_ust__get_dynamic_len(dest)); \
782 }
783
784 #undef lttng_ust__field_unused
785 #define lttng_ust__field_unused(_src)
786
787 #undef lttng_ust__field_enum
788 #define lttng_ust__field_enum(_provider, _name, _type, _item, _src, _nowrite) \
789 lttng_ust__field_integer_ext(_type, _item, _src, LTTNG_UST_BYTE_ORDER, 10, _nowrite)
790
791 /* Beware: this get len actually consumes the len value */
792 #undef lttng_ust__get_dynamic_len
793 #define lttng_ust__get_dynamic_len(field) __stackvar.__dynamic_len[__dynamic_len_idx++]
794
795 #undef LTTNG_UST_TP_ARGS
796 #define LTTNG_UST_TP_ARGS(...) __VA_ARGS__
797
798 #undef LTTNG_UST_TP_FIELDS
799 #define LTTNG_UST_TP_FIELDS(...) __VA_ARGS__
800
801 /*
802 * For state dump, check that "session" argument (mandatory) matches the
803 * session this event belongs to. Ensures that we write state dump data only
804 * into the started session, not into all sessions.
805 */
806 #undef LTTNG_UST__TP_SESSION_CHECK
807 #ifdef LTTNG_UST_TP_SESSION_CHECK
808 #define LTTNG_UST__TP_SESSION_CHECK(session, csession) (session == csession)
809 #else /* TP_SESSION_CHECK */
810 #define LTTNG_UST__TP_SESSION_CHECK(session, csession) 1
811 #endif /* TP_SESSION_CHECK */
812
813 /*
814 * Use of __builtin_return_address(0) sometimes seems to cause stack
815 * corruption on 32-bit PowerPC. Disable this feature on that
816 * architecture for now by always using the NULL value for the ip
817 * context.
818 */
819 #undef LTTNG_UST__TP_IP_PARAM
820
821 #ifdef LTTNG_UST_TP_IP_PARAM
822 #define LTTNG_UST__TP_IP_PARAM(x) (x)
823 #else /* TP_IP_PARAM */
824
825 #if defined(LTTNG_UST_ARCH_PPC) && !defined(LTTNG_UST_ARCH_PPC64)
826 #define LTTNG_UST__TP_IP_PARAM(x) NULL
827 #else
828 #define LTTNG_UST__TP_IP_PARAM(x) __builtin_return_address(0)
829 #endif
830
831 #endif /* TP_IP_PARAM */
832
833 /*
834 * Using twice size for filter stack data to hold size and pointer for
835 * each field (worse case). For integers, max size required is 64-bit.
836 * Same for double-precision floats. Those fit within
837 * 2*sizeof(unsigned long) for all supported architectures.
838 * Perform UNION (||) of filter runtime list.
839 */
840 #undef LTTNG_UST__TRACEPOINT_EVENT_CLASS
841 #define LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
842 static \
843 void lttng_ust__event_probe__##_provider##___##_name(LTTNG_UST__TP_ARGS_DATA_PROTO(_args)) \
844 lttng_ust_notrace; \
845 static \
846 void lttng_ust__event_probe__##_provider##___##_name(LTTNG_UST__TP_ARGS_DATA_PROTO(_args)) \
847 { \
848 struct lttng_ust_event_common *__event = (struct lttng_ust_event_common *) __tp_data; \
849 size_t __dynamic_len_idx = 0; \
850 const size_t __num_fields = LTTNG_UST__TP_ARRAY_SIZE(lttng_ust__event_fields___##_provider##___##_name) - 1; \
851 union { \
852 size_t __dynamic_len[__num_fields]; \
853 char __interpreter_stack_data[2 * sizeof(unsigned long) * __num_fields]; \
854 } __stackvar; \
855 int __ret; \
856 bool __interpreter_stack_prepared = false; \
857 \
858 if (0) \
859 (void) __dynamic_len_idx; /* don't warn if unused */ \
860 switch (__event->type) { \
861 case LTTNG_UST_EVENT_TYPE_RECORDER: \
862 { \
863 struct lttng_ust_event_recorder *lttng_ust__event_recorder = (struct lttng_ust_event_recorder *) __event->child; \
864 struct lttng_ust_channel_buffer *__chan = lttng_ust__event_recorder->chan; \
865 struct lttng_ust_channel_common *__chan_common = __chan->parent; \
866 \
867 if (!LTTNG_UST__TP_SESSION_CHECK(session, __chan_common->session)) \
868 return; \
869 if (caa_unlikely(!CMM_ACCESS_ONCE(__chan_common->session->active))) \
870 return; \
871 if (caa_unlikely(!CMM_ACCESS_ONCE(__chan_common->enabled))) \
872 return; \
873 break; \
874 } \
875 case LTTNG_UST_EVENT_TYPE_NOTIFIER: \
876 break; \
877 } \
878 if (caa_unlikely(!CMM_ACCESS_ONCE(__event->enabled))) \
879 return; \
880 if (caa_unlikely(!LTTNG_UST_TP_RCU_LINK_TEST())) \
881 return; \
882 if (caa_unlikely(CMM_ACCESS_ONCE(__event->eval_filter))) { \
883 lttng_ust__event_prepare_interpreter_stack__##_provider##___##_name(__stackvar.__interpreter_stack_data, \
884 LTTNG_UST__TP_ARGS_DATA_VAR(_args)); \
885 __interpreter_stack_prepared = true; \
886 if (caa_likely(__event->run_filter(__event, \
887 __stackvar.__interpreter_stack_data, NULL) != LTTNG_UST_EVENT_FILTER_ACCEPT)) \
888 return; \
889 } \
890 switch (__event->type) { \
891 case LTTNG_UST_EVENT_TYPE_RECORDER: \
892 { \
893 size_t __event_len, lttng_ust__event_align; \
894 struct lttng_ust_event_recorder *lttng_ust__event_recorder = (struct lttng_ust_event_recorder *) __event->child; \
895 struct lttng_ust_channel_buffer *__chan = lttng_ust__event_recorder->chan; \
896 struct lttng_ust_ring_buffer_ctx __ctx; \
897 \
898 __event_len = lttng_ust__event_get_size__##_provider##___##_name(__stackvar.__dynamic_len, \
899 LTTNG_UST__TP_ARGS_DATA_VAR(_args)); \
900 lttng_ust__event_align = lttng_ust__event_get_align__##_provider##___##_name(LTTNG_UST__TP_ARGS_VAR(_args)); \
901 lttng_ust_ring_buffer_ctx_init(&__ctx, lttng_ust__event_recorder, __event_len, lttng_ust__event_align, \
902 LTTNG_UST__TP_IP_PARAM(LTTNG_UST_TP_IP_PARAM)); \
903 __ret = __chan->ops->event_reserve(&__ctx); \
904 if (__ret < 0) \
905 return; \
906 _fields \
907 __chan->ops->event_commit(&__ctx); \
908 break; \
909 } \
910 case LTTNG_UST_EVENT_TYPE_NOTIFIER: \
911 { \
912 struct lttng_ust_event_notifier *lttng_ust__event_notifier = (struct lttng_ust_event_notifier *) __event->child; \
913 struct lttng_ust_notification_ctx __notif_ctx; \
914 \
915 __notif_ctx.struct_size = sizeof(struct lttng_ust_notification_ctx); \
916 __notif_ctx.eval_capture = CMM_ACCESS_ONCE(lttng_ust__event_notifier->eval_capture); \
917 \
918 if (caa_unlikely(!__interpreter_stack_prepared && __notif_ctx.eval_capture)) \
919 lttng_ust__event_prepare_interpreter_stack__##_provider##___##_name(__stackvar.__interpreter_stack_data, \
920 LTTNG_UST__TP_ARGS_DATA_VAR(_args)); \
921 \
922 lttng_ust__event_notifier->notification_send(lttng_ust__event_notifier, \
923 __stackvar.__interpreter_stack_data, \
924 &__notif_ctx); \
925 break; \
926 } \
927 } \
928 }
929
930 #include LTTNG_UST_TRACEPOINT_INCLUDE
931
932 #undef lttng_ust__get_dynamic_len
933
934 /*
935 * Stage 5.1 of tracepoint event generation.
936 *
937 * Create probe signature
938 */
939
940 /* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
941 #include <lttng/ust-tracepoint-event-reset.h>
942
943 #undef LTTNG_UST_TP_ARGS
944 #define LTTNG_UST_TP_ARGS(...) __VA_ARGS__
945
946 #define LTTNG_UST__TP_EXTRACT_STRING2(...) #__VA_ARGS__
947
948 #undef LTTNG_UST__TRACEPOINT_EVENT_CLASS
949 #define LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
950 static const char __tp_event_signature___##_provider##___##_name[] = \
951 LTTNG_UST__TP_EXTRACT_STRING2(_args);
952
953 #include LTTNG_UST_TRACEPOINT_INCLUDE
954
955 #undef LTTNG_UST__TP_EXTRACT_STRING2
956
957 /*
958 * Stage 6 of tracepoint event generation.
959 *
960 * Tracepoint loglevel mapping definition generation. We generate a
961 * symbol for each mapping for a provider/event to ensure at most a 1 to
962 * 1 mapping between events and loglevels. If the symbol is repeated,
963 * the compiler will complain.
964 */
965
966 /* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
967 #include <lttng/ust-tracepoint-event-reset.h>
968
969 /*
970 * Declare _loglevel___##__provider##___##__name as non-static, with
971 * hidden visibility for c++ handling of weakref. We do a weakref to the
972 * symbol in a later stage, which requires that the symbol is not
973 * mangled.
974 */
975 #ifdef __cplusplus
976 #define LTTNG_UST_TP_EXTERN_C extern "C"
977 #else
978 #define LTTNG_UST_TP_EXTERN_C
979 #endif
980
981 #undef LTTNG_UST_TRACEPOINT_LOGLEVEL
982 #define LTTNG_UST_TRACEPOINT_LOGLEVEL(__provider, __name, __loglevel) \
983 static const int _loglevel_value___##__provider##___##__name = __loglevel; \
984 LTTNG_UST_TP_EXTERN_C const int * const _loglevel___##__provider##___##__name \
985 __attribute__((visibility("hidden"))) = \
986 &_loglevel_value___##__provider##___##__name;
987
988 #include LTTNG_UST_TRACEPOINT_INCLUDE
989
990 #undef LTTNG_UST_TP_EXTERN_C
991
992 /*
993 * Stage 6.1 of tracepoint event generation.
994 *
995 * Tracepoint UML URI info.
996 */
997
998 /* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
999 #include <lttng/ust-tracepoint-event-reset.h>
1000
1001 /*
1002 * Declare _model_emf_uri___##__provider##___##__name as non-static,
1003 * with hidden visibility for c++ handling of weakref. We do a weakref
1004 * to the symbol in a later stage, which requires that the symbol is not
1005 * mangled.
1006 */
1007 #ifdef __cplusplus
1008 #define LTTNG_UST_TP_EXTERN_C extern "C"
1009 #else
1010 #define LTTNG_UST_TP_EXTERN_C
1011 #endif
1012
1013 #undef LTTNG_UST_TRACEPOINT_MODEL_EMF_URI
1014 #define LTTNG_UST_TRACEPOINT_MODEL_EMF_URI(__provider, __name, __uri) \
1015 LTTNG_UST_TP_EXTERN_C const char * const _model_emf_uri___##__provider##___##__name \
1016 __attribute__((visibility("hidden"))) = __uri; \
1017
1018 #include LTTNG_UST_TRACEPOINT_INCLUDE
1019
1020 #undef LTTNG_UST_TP_EXTERN_C
1021
1022 /*
1023 * Stage 7.0 of tracepoint event generation.
1024 *
1025 * Declare toplevel descriptor for the whole probe.
1026 * Unlike C, C++ does not allow tentative definitions. Therefore, we
1027 * need to explicitly declare the variable with "extern", using hidden
1028 * visibility to keep this symbol from being exported to the global
1029 * symbol table.
1030 */
1031
1032 extern const struct lttng_ust_probe_desc LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__probe_desc___, LTTNG_UST_TRACEPOINT_PROVIDER)
1033 __attribute__((visibility("hidden")));
1034
1035 /*
1036 * Stage 7.1 of tracepoint event generation.
1037 *
1038 * Create events description structures. We use a weakref because
1039 * loglevels are optional. If not declared, the event will point to
1040 * a loglevel that contains NULL.
1041 *
1042 * C++ requires that const objects have a user-declared default
1043 * constructor. However, in both C++ and C, weakref cannot be
1044 * initialized because it causes the weakref attribute to be ignored.
1045 * Therefore, the loglevel and model_emf_uri pointers are not const
1046 * to ensure C++ compilers default-initialize them.
1047 */
1048
1049 /* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
1050 #include <lttng/ust-tracepoint-event-reset.h>
1051
1052 #undef LTTNG_UST__TRACEPOINT_EVENT_INSTANCE
1053 #define LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
1054 static const int * \
1055 __ref_loglevel___##_provider##___##_name \
1056 __attribute__((weakref ("_loglevel___" #_provider "___" #_name))); \
1057 static const char * \
1058 __ref_model_emf_uri___##_provider##___##_name \
1059 __attribute__((weakref ("_model_emf_uri___" #_provider "___" #_name)));\
1060 static const struct lttng_ust_event_desc lttng_ust__event_desc___##_provider##_##_name = { \
1061 .struct_size = sizeof(struct lttng_ust_event_desc), \
1062 .event_name = #_name, \
1063 .probe_desc = &lttng_ust__probe_desc___##_provider, \
1064 .probe_callback = (void (*)(void)) &lttng_ust__event_probe__##_provider##___##_template, \
1065 .fields = lttng_ust__event_fields___##_provider##___##_template, \
1066 .nr_fields = LTTNG_UST__TP_ARRAY_SIZE(lttng_ust__event_fields___##_provider##___##_template) - 1, \
1067 .loglevel = &__ref_loglevel___##_provider##___##_name, \
1068 .signature = __tp_event_signature___##_provider##___##_template, \
1069 .model_emf_uri = &__ref_model_emf_uri___##_provider##___##_name, \
1070 };
1071
1072 #include LTTNG_UST_TRACEPOINT_INCLUDE
1073
1074 /*
1075 * Stage 7.2 of tracepoint event generation.
1076 *
1077 * Create array of events.
1078 */
1079
1080 /* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
1081 #include <lttng/ust-tracepoint-event-reset.h>
1082
1083 #undef LTTNG_UST__TRACEPOINT_EVENT_INSTANCE
1084 #define LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
1085 &lttng_ust__event_desc___##_provider##_##_name,
1086
1087 static const struct lttng_ust_event_desc * const LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__event_desc___, LTTNG_UST_TRACEPOINT_PROVIDER)[] = {
1088 #include LTTNG_UST_TRACEPOINT_INCLUDE
1089 NULL, /* Dummy, C99 forbids 0-len array. */
1090 };
1091
1092
1093 /*
1094 * Stage 8 of tracepoint event generation.
1095 *
1096 * Create a toplevel descriptor for the whole probe.
1097 */
1098
1099 const struct lttng_ust_probe_desc LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__probe_desc___, LTTNG_UST_TRACEPOINT_PROVIDER) = {
1100 .struct_size = sizeof(struct lttng_ust_probe_desc),
1101 .provider_name = lttng_ust__tp_stringify(LTTNG_UST_TRACEPOINT_PROVIDER),
1102 .event_desc = LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__event_desc___, LTTNG_UST_TRACEPOINT_PROVIDER),
1103 .nr_events = LTTNG_UST__TP_ARRAY_SIZE(LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__event_desc___, LTTNG_UST_TRACEPOINT_PROVIDER)) - 1,
1104 .major = LTTNG_UST_PROVIDER_MAJOR,
1105 .minor = LTTNG_UST_PROVIDER_MINOR,
1106 };
1107
1108 static int LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__probe_register_refcount___, LTTNG_UST_TRACEPOINT_PROVIDER);
1109 static struct lttng_ust_registered_probe *LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__probe_register_cookie___, LTTNG_UST_TRACEPOINT_PROVIDER);
1110
1111 /*
1112 * Stage 9 of tracepoint event generation.
1113 *
1114 * Register/unregister probes at module load/unload.
1115 *
1116 * Generate the constructor as an externally visible symbol for use when
1117 * linking the probe statically.
1118 *
1119 * Register refcount is protected by libc dynamic loader mutex.
1120 */
1121
1122 /* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
1123 #include <lttng/ust-tracepoint-event-reset.h>
1124 static void
1125 LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__events_init__, LTTNG_UST_TRACEPOINT_PROVIDER)(void)
1126 lttng_ust_notrace __attribute__((constructor));
1127 static void
1128 LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__events_init__, LTTNG_UST_TRACEPOINT_PROVIDER)(void)
1129 {
1130 struct lttng_ust_registered_probe *reg_probe;
1131
1132 if (LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__probe_register_refcount___,
1133 LTTNG_UST_TRACEPOINT_PROVIDER)++) {
1134 return;
1135 }
1136 /*
1137 * lttng_ust_tracepoint_provider_check_ ## LTTNG_UST_TRACEPOINT_PROVIDER() is a
1138 * static inline function that ensures every probe PROVIDER
1139 * argument match the provider within which they appear. It
1140 * calls empty static inline functions, and therefore has no
1141 * runtime effect. However, if it detects an error, a linker
1142 * error will appear.
1143 */
1144 LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust_tracepoint_provider_check_, LTTNG_UST_TRACEPOINT_PROVIDER)();
1145 assert(!LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__probe_register_cookie___, LTTNG_UST_TRACEPOINT_PROVIDER));
1146 reg_probe = lttng_ust_probe_register(&LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__probe_desc___, LTTNG_UST_TRACEPOINT_PROVIDER));
1147 if (!reg_probe) {
1148 fprintf(stderr, "LTTng-UST: Error while registering tracepoint probe.\n");
1149 abort();
1150 }
1151 LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__probe_register_cookie___, LTTNG_UST_TRACEPOINT_PROVIDER) = reg_probe;
1152 }
1153
1154 static void
1155 LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__events_exit__, LTTNG_UST_TRACEPOINT_PROVIDER)(void)
1156 lttng_ust_notrace __attribute__((destructor));
1157 static void
1158 LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__events_exit__, LTTNG_UST_TRACEPOINT_PROVIDER)(void)
1159 {
1160 if (--LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__probe_register_refcount___,
1161 LTTNG_UST_TRACEPOINT_PROVIDER)) {
1162 return;
1163 }
1164 lttng_ust_probe_unregister(LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__probe_register_cookie___, LTTNG_UST_TRACEPOINT_PROVIDER));
1165 LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__probe_register_cookie___, LTTNG_UST_TRACEPOINT_PROVIDER) = NULL;
1166 }
1167
1168 int LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust_tracepoint_provider_, LTTNG_UST_TRACEPOINT_PROVIDER)
1169 __attribute__((visibility("default")));
This page took 0.05187 seconds and 3 git commands to generate.