Tracepoint API namespacing '__lttng_ust_events_init'
[lttng-ust.git] / include / lttng / ust-tracepoint-event.h
... / ...
CommitLineData
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(tp_rcu_dereference((head)->next), __typeof__(*pos), member); \
26 &pos->member != (head); \
27 pos = cds_list_entry(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
76static inline
77void LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust_tracepoint_provider_mismatch_, LTTNG_UST_TRACEPOINT_PROVIDER)(void)
78 lttng_ust_notrace;
79static inline
80void 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
92static inline
93void LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust_tracepoint_provider_check_, LTTNG_UST_TRACEPOINT_PROVIDER)(void)
94 lttng_ust_notrace;
95static inline
96void 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) \
133void 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) \
137void 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 ctf_enum_value
150#define ctf_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 ctf_enum_range
168#define ctf_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 ctf_enum_auto
186#define ctf_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 ctf_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 _ctf_array_encoded
229#define _ctf_array_encoded(_type, _item, _src, _byte_order, \
230 _length, _encoding, _nowrite, \
231 _elem_type_base) \
232 lttng_ust_ctf_array_element_type_is_supported(_type, _item);
233
234#undef _ctf_sequence_encoded
235#define _ctf_sequence_encoded(_type, _item, _src, _byte_order, \
236 _length_type, _src_length, _encoding, _nowrite, \
237 _elem_type_base) \
238 lttng_ust_ctf_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 _ctf_integer_ext
262#define _ctf_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 _ctf_float
272#define _ctf_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 _ctf_array_encoded
282#define _ctf_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 _ctf_sequence_encoded
303#define _ctf_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, 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 _ctf_string
331#define _ctf_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 _ctf_unused
347#define _ctf_unused(_src)
348
349#undef _ctf_enum
350#define _ctf_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, 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 ctf_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) \
401static 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 _ctf_integer_ext
416#define _ctf_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 _ctf_float
423#define _ctf_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 _ctf_array_encoded
430#define _ctf_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 _ctf_sequence_encoded
438#define _ctf_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 _ctf_string
450#define _ctf_string(_item, _src, _nowrite) \
451 __event_len += __dynamic_len[__dynamic_len_idx++] = \
452 strlen((_src) ? (_src) : LTTNG_UST__NULL_STRING) + 1;
453
454#undef _ctf_unused
455#define _ctf_unused(_src) \
456 if (0) \
457 (void) (_src); /* Unused */
458
459#undef _ctf_enum
460#define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
461 _ctf_integer_ext(_type, _item, _src, 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) \
471static inline \
472size_t lttng_ust__event_get_size__##_provider##___##_name(size_t *__dynamic_len, LTTNG_UST__TP_ARGS_DATA_PROTO(_args)) \
473 lttng_ust_notrace; \
474static inline \
475size_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 _ctf_integer_ext
504#define _ctf_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 != BYTE_ORDER) \
518 __tmp.v = 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 != BYTE_ORDER) \
526 __tmp.v = 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 != BYTE_ORDER) \
534 __tmp.v = 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 != BYTE_ORDER) \
555 __tmp.v = 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 != BYTE_ORDER) \
563 __tmp.v = 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 != BYTE_ORDER) \
571 __tmp.v = 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 _ctf_float
583#define _ctf_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 _ctf_array_encoded
591#define _ctf_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 _ctf_sequence_encoded
603#define _ctf_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 _ctf_string
615#define _ctf_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 _ctf_unused
624#define _ctf_unused(_src) \
625 if (0) \
626 (void) (_src);
627
628#undef _ctf_enum
629#define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
630 _ctf_integer_ext(_type, _item, _src, 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) \
640static inline \
641void 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 _ctf_integer_ext
665#define _ctf_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 _ctf_float
671#define _ctf_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 _ctf_array_encoded
677#define _ctf_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 _ctf_sequence_encoded
684#define _ctf_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 _ctf_string
694#define _ctf_string(_item, _src, _nowrite) \
695 if (0) \
696 (void) (_src); /* Unused */
697
698#undef _ctf_unused
699#define _ctf_unused(_src) \
700 if (0) \
701 (void) (_src); /* Unused */
702
703#undef _ctf_enum
704#define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
705 _ctf_integer_ext(_type, _item, _src, 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) \
715static inline \
716size_t lttng_ust__event_get_align__##_provider##___##_name(LTTNG_UST__TP_ARGS_PROTO(_args)) \
717 lttng_ust_notrace; \
718static inline \
719size_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 _ctf_integer_ext
741#define _ctf_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 _ctf_float
748#define _ctf_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 _ctf_array_encoded
755#define _ctf_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 _ctf_sequence_encoded
763#define _ctf_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 _ctf_string
776#define _ctf_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 _ctf_unused
785#define _ctf_unused(_src)
786
787#undef _ctf_enum
788#define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
789 _ctf_integer_ext(_type, _item, _src, 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) \
842static \
843void lttng_ust__event_probe__##_provider##___##_name(LTTNG_UST__TP_ARGS_DATA_PROTO(_args)) \
844 lttng_ust_notrace; \
845static \
846void 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(!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) \
950static 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) \
983static const int _loglevel_value___##__provider##___##__name = __loglevel; \
984LTTNG_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) \
1015LTTNG_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
1032extern 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) \
1054static const int * \
1055 __ref_loglevel___##_provider##___##_name \
1056 __attribute__((weakref ("_loglevel___" #_provider "___" #_name))); \
1057static const char * \
1058 __ref_model_emf_uri___##_provider##___##_name \
1059 __attribute__((weakref ("_model_emf_uri___" #_provider "___" #_name)));\
1060static 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
1087static 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
1099const 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
1108static int LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__probe_register_refcount___, LTTNG_UST_TRACEPOINT_PROVIDER);
1109static 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>
1124static void
1125LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__events_init__, LTTNG_UST_TRACEPOINT_PROVIDER)(void)
1126 lttng_ust_notrace __attribute__((constructor));
1127static void
1128LTTNG_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
1154static void
1155LTTNG_UST__TP_COMBINE_TOKENS(__lttng_ust_events_exit__, LTTNG_UST_TRACEPOINT_PROVIDER)(void)
1156 lttng_ust_notrace __attribute__((destructor));
1157static void
1158LTTNG_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
1168int LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust_tracepoint_provider_, LTTNG_UST_TRACEPOINT_PROVIDER)
1169 __attribute__((visibility("default")));
This page took 0.02702 seconds and 4 git commands to generate.