Commit | Line | Data |
---|---|---|
1c324e59 MD |
1 | /* |
2 | * Copyright (c) 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
3 | * | |
4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED | |
5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. | |
6 | * | |
7 | * Permission is hereby granted to use or copy this program | |
8 | * for any purpose, provided the above notices are retained on all copies. | |
9 | * Permission to modify the code and to distribute modified code is granted, | |
10 | * provided the above notices are retained, and a notice that the code was | |
11 | * modified is included with the above copyright notice. | |
12 | */ | |
13 | ||
14 | #include <stdio.h> | |
15 | #include <urcu/compiler.h> | |
16 | #include <lttng/ust-events.h> | |
1c324e59 | 17 | #include <lttng/ringbuffer-config.h> |
44c72f10 | 18 | #include <string.h> |
1c324e59 MD |
19 | |
20 | /* | |
21 | * Macro declarations used for all stages. | |
22 | */ | |
23 | ||
24 | #undef ctf_integer | |
25 | #define ctf_integer(_type, _item, _src) \ | |
26 | ctf_integer_ext(_type, _item, _src, BYTE_ORDER, 10) | |
27 | ||
28 | #undef ctf_integer_hex | |
29 | #define ctf_integer_hex(_type, _item, _src) \ | |
30 | ctf_integer_ext(_type, _item, _src, BYTE_ORDER, 16) | |
31 | ||
32 | #undef ctf_integer_network | |
33 | #define ctf_integer_network(_type, _item, _src) \ | |
34 | ctf_integer_ext(_type, _item, _src, BIG_ENDIAN, 10) | |
35 | ||
36 | #undef ctf_integer_network_hex | |
37 | #define ctf_integer_network_hex(_type, _item, _src) \ | |
38 | ctf_integer_ext(_type, _item, _src, BIG_ENDIAN, 16) | |
39 | ||
40 | /* ctf_float is redefined at each step */ | |
41 | ||
42 | #undef ctf_array | |
43 | #define ctf_array(_type, _item, _src, _length) \ | |
44 | ctf_array_encoded(_type, _item, _src, _length, none) | |
45 | ||
46 | #undef ctf_array_text | |
47 | #define ctf_array_text(_type, _item, _src, _length) \ | |
48 | ctf_array_encoded(_type, _item, _src, _length, UTF8) | |
49 | ||
50 | #undef ctf_sequence | |
51 | #define ctf_sequence(_type, _item, _src, _length_type, _src_length) \ | |
52 | ctf_sequence_encoded(_type, _item, _src, \ | |
53 | _length_type, _src_length, none) | |
54 | ||
55 | #undef ctf_sequence_text | |
56 | #define ctf_sequence_text(_type, _item, _src, _length_type, _src_length) \ | |
57 | ctf_sequence_encoded(_type, _item, _src, \ | |
58 | _length_type, _src_length, UTF8) | |
59 | ||
60 | /* ctf_string is redefined at each step */ | |
61 | ||
62 | /* | |
63 | * TRACEPOINT_EVENT_CLASS declares a class of tracepoints receiving the | |
64 | * same arguments and having the same field layout. | |
65 | * | |
66 | * TRACEPOINT_EVENT_INSTANCE declares an instance of a tracepoint, with | |
67 | * its own provider and name. It refers to a class (template). | |
68 | * | |
69 | * TRACEPOINT_EVENT declared both a class and an instance and does a | |
70 | * direct mapping from the instance to the class. | |
71 | */ | |
72 | ||
73 | #undef TRACEPOINT_EVENT | |
74 | #define TRACEPOINT_EVENT(_provider, _name, _args, _fields) \ | |
75 | TRACEPOINT_EVENT_CLASS(_provider, _name, \ | |
76 | _TP_PARAMS(_args), \ | |
77 | _TP_PARAMS(_fields)) \ | |
78 | TRACEPOINT_EVENT_INSTANCE(_provider, _name, _name, \ | |
79 | _TP_PARAMS(args)) | |
80 | ||
81 | /* Helpers */ | |
82 | #define _TP_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) | |
83 | ||
84 | #define _tp_max_t(type, x, y) \ | |
85 | ({ \ | |
86 | type __max1 = (x); \ | |
87 | type __max2 = (y); \ | |
88 | __max1 > __max2 ? __max1: __max2; \ | |
89 | }) | |
90 | ||
91 | /* | |
92 | * Stage 0 of tracepoint event generation. | |
93 | * | |
94 | * Check that each TRACEPOINT_EVENT provider argument match the | |
95 | * TRACEPOINT_PROVIDER by creating dummy callbacks. | |
96 | */ | |
97 | ||
98 | /* Reset all macros within TRACEPOINT_EVENT */ | |
99 | #include <lttng/ust-tracepoint-event-reset.h> | |
100 | ||
101 | static inline | |
102 | void _TP_COMBINE_TOKENS(__tracepoint_provider_mismatch_, TRACEPOINT_PROVIDER)(void) | |
103 | { | |
104 | } | |
105 | ||
106 | #undef TRACEPOINT_EVENT_CLASS | |
107 | #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \ | |
108 | __tracepoint_provider_mismatch_##_provider(); | |
109 | ||
110 | #undef TRACEPOINT_EVENT_INSTANCE | |
111 | #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \ | |
112 | __tracepoint_provider_mismatch_##_provider(); | |
113 | ||
114 | static __attribute__((unused)) | |
115 | void _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)(void) | |
116 | { | |
117 | #include TRACEPOINT_INCLUDE | |
118 | } | |
119 | ||
120 | /* | |
121 | * Stage 1 of tracepoint event generation. | |
122 | * | |
123 | * Create event field type metadata section. | |
124 | * Each event produce an array of fields. | |
125 | */ | |
126 | ||
127 | /* Reset all macros within TRACEPOINT_EVENT */ | |
128 | #include <lttng/ust-tracepoint-event-reset.h> | |
129 | ||
130 | #undef ctf_integer_ext | |
131 | #define ctf_integer_ext(_type, _item, _src, _byte_order, _base) \ | |
132 | { \ | |
133 | .name = #_item, \ | |
134 | .type = __type_integer(_type, _byte_order, _base, none),\ | |
135 | }, | |
136 | ||
137 | #undef ctf_float | |
138 | #define ctf_float(_type, _item, _src) \ | |
139 | { \ | |
140 | .name = #_item, \ | |
141 | .type = __type_float(_type), \ | |
142 | }, | |
143 | ||
144 | #undef ctf_array_encoded | |
145 | #define ctf_array_encoded(_type, _item, _src, _length, _encoding) \ | |
146 | { \ | |
147 | .name = #_item, \ | |
148 | .type = \ | |
149 | { \ | |
150 | .atype = atype_array, \ | |
151 | .u.array = \ | |
152 | { \ | |
153 | .length = _length, \ | |
154 | .elem_type = __type_integer(_type, BYTE_ORDER, 10, _encoding), \ | |
155 | }, \ | |
156 | }, \ | |
157 | }, | |
158 | ||
159 | #undef ctf_sequence_encoded | |
160 | #define ctf_sequence_encoded(_type, _item, _src, \ | |
161 | _length_type, _src_length, _encoding) \ | |
162 | { \ | |
163 | .name = #_item, \ | |
164 | .type = \ | |
165 | { \ | |
166 | .atype = atype_sequence, \ | |
167 | .u.sequence = \ | |
168 | { \ | |
169 | .length_type = __type_integer(_length_type, BYTE_ORDER, 10, none), \ | |
170 | .elem_type = __type_integer(_type, BYTE_ORDER, 10, _encoding), \ | |
171 | }, \ | |
172 | }, \ | |
173 | }, | |
174 | ||
175 | #undef ctf_string | |
176 | #define ctf_string(_item, _src) \ | |
177 | { \ | |
178 | .name = #_item, \ | |
179 | .type = \ | |
180 | { \ | |
181 | .atype = atype_string, \ | |
182 | .u.basic.string.encoding = lttng_encode_UTF8, \ | |
183 | }, \ | |
184 | }, | |
185 | ||
186 | #undef TP_FIELDS | |
187 | #define TP_FIELDS(args...) args /* Only one used in this phase */ | |
188 | ||
189 | #undef TRACEPOINT_EVENT_CLASS | |
190 | #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \ | |
191 | static const struct lttng_event_field __event_fields___##_provider##___##_name[] = { \ | |
192 | _fields \ | |
193 | }; | |
194 | ||
195 | #include TRACEPOINT_INCLUDE | |
196 | ||
197 | /* | |
198 | * Stage 2 of tracepoint event generation. | |
199 | * | |
200 | * Create probe callback prototypes. | |
201 | */ | |
202 | ||
203 | /* Reset all macros within TRACEPOINT_EVENT */ | |
204 | #include <lttng/ust-tracepoint-event-reset.h> | |
205 | ||
206 | #undef TP_ARGS | |
207 | #define TP_ARGS(args...) args | |
208 | ||
209 | #undef TRACEPOINT_EVENT_CLASS | |
210 | #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \ | |
211 | static void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args)); | |
212 | ||
213 | #include TRACEPOINT_INCLUDE | |
214 | ||
215 | /* | |
216 | * Stage 3 of tracepoint event generation. | |
217 | * | |
1c324e59 MD |
218 | * Create static inline function that calculates event size. |
219 | */ | |
220 | ||
221 | /* Reset all macros within TRACEPOINT_EVENT */ | |
222 | #include <lttng/ust-tracepoint-event-reset.h> | |
223 | ||
224 | #undef ctf_integer_ext | |
225 | #define ctf_integer_ext(_type, _item, _src, _byte_order, _base) \ | |
226 | __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \ | |
227 | __event_len += sizeof(_type); | |
228 | ||
229 | #undef ctf_float | |
230 | #define ctf_float(_type, _item, _src) \ | |
231 | __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \ | |
232 | __event_len += sizeof(_type); | |
233 | ||
234 | #undef ctf_array_encoded | |
235 | #define ctf_array_encoded(_type, _item, _src, _length, _encoding) \ | |
236 | __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \ | |
237 | __event_len += sizeof(_type) * (_length); | |
238 | ||
239 | #undef ctf_sequence_encoded | |
240 | #define ctf_sequence_encoded(_type, _item, _src, _length_type, \ | |
241 | _src_length, _encoding) \ | |
242 | __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_length_type)); \ | |
243 | __event_len += sizeof(_length_type); \ | |
244 | __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \ | |
245 | __dynamic_len[__dynamic_len_idx] = (_src_length); \ | |
246 | __event_len += sizeof(_type) * __dynamic_len[__dynamic_len_idx]; \ | |
247 | __dynamic_len_idx++; | |
248 | ||
249 | #undef ctf_string | |
250 | #define ctf_string(_item, _src) \ | |
251 | __event_len += __dynamic_len[__dynamic_len_idx++] = strlen(_src) + 1; | |
252 | ||
253 | #undef TP_ARGS | |
254 | #define TP_ARGS(args...) args | |
255 | ||
256 | #undef TP_FIELDS | |
257 | #define TP_FIELDS(args...) args | |
258 | ||
259 | #undef TRACEPOINT_EVENT_CLASS | |
260 | #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \ | |
261 | static inline size_t __event_get_size__##_provider##___##_name(size_t *__dynamic_len, _TP_ARGS_DATA_PROTO(_args)) \ | |
262 | { \ | |
263 | size_t __event_len = 0; \ | |
264 | unsigned int __dynamic_len_idx = 0; \ | |
265 | \ | |
266 | if (0) \ | |
267 | (void) __dynamic_len_idx; /* don't warn if unused */ \ | |
268 | _fields \ | |
269 | return __event_len; \ | |
270 | } | |
271 | ||
272 | #include TRACEPOINT_INCLUDE | |
273 | ||
274 | /* | |
df854e41 | 275 | * Stage 4 of tracepoint event generation. |
1c324e59 MD |
276 | * |
277 | * Create static inline function that calculates event payload alignment. | |
278 | */ | |
279 | ||
280 | /* Reset all macros within TRACEPOINT_EVENT */ | |
281 | #include <lttng/ust-tracepoint-event-reset.h> | |
282 | ||
283 | #undef ctf_integer_ext | |
284 | #define ctf_integer_ext(_type, _item, _src, _byte_order, _base) \ | |
285 | __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_type)); | |
286 | ||
287 | #undef ctf_float | |
288 | #define ctf_float(_type, _item, _src) \ | |
289 | __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_type)); | |
290 | ||
291 | #undef ctf_array_encoded | |
292 | #define ctf_array_encoded(_type, _item, _src, _length, _encoding) \ | |
293 | __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_type)); | |
294 | ||
295 | #undef ctf_sequence_encoded | |
296 | #define ctf_sequence_encoded(_type, _item, _src, _length_type, \ | |
297 | _src_length, _encoding) \ | |
298 | __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_length_type)); \ | |
299 | __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_type)); | |
300 | ||
301 | #undef ctf_string | |
302 | #define ctf_string(_item, _src) | |
303 | ||
304 | #undef TP_ARGS | |
305 | #define TP_ARGS(args...) args | |
306 | ||
307 | #undef TP_FIELDS | |
308 | #define TP_FIELDS(args...) args | |
309 | ||
310 | #undef TRACEPOINT_EVENT_CLASS | |
311 | #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \ | |
312 | static inline \ | |
313 | size_t __event_get_align__##_provider##___##_name(_TP_ARGS_PROTO(_args)) \ | |
314 | { \ | |
315 | size_t __event_align = 1; \ | |
316 | _fields \ | |
317 | return __event_align; \ | |
318 | } | |
319 | ||
320 | #include TRACEPOINT_INCLUDE | |
321 | ||
322 | ||
323 | /* | |
df854e41 | 324 | * Stage 5 of tracepoint event generation. |
1c324e59 MD |
325 | * |
326 | * Create the probe function. This function calls event size calculation | |
327 | * and writes event data into the buffer. | |
328 | */ | |
329 | ||
330 | /* Reset all macros within TRACEPOINT_EVENT */ | |
331 | #include <lttng/ust-tracepoint-event-reset.h> | |
332 | ||
333 | #undef ctf_integer_ext | |
334 | #define ctf_integer_ext(_type, _item, _src, _byte_order, _base) \ | |
335 | { \ | |
336 | _type __tmp = (_src); \ | |
337 | lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__tmp));\ | |
338 | __chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp));\ | |
339 | } | |
340 | ||
341 | #undef ctf_float | |
342 | #define ctf_float(_type, _item, _src) \ | |
343 | { \ | |
344 | _type __tmp = (_src); \ | |
345 | lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__tmp));\ | |
346 | __chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp));\ | |
347 | } | |
348 | ||
349 | #undef ctf_array_encoded | |
350 | #define ctf_array_encoded(_type, _item, _src, _length, _encoding) \ | |
351 | lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_type)); \ | |
352 | __chan->ops->event_write(&__ctx, _src, sizeof(_type) * (_length)); | |
353 | ||
354 | #undef ctf_sequence_encoded | |
355 | #define ctf_sequence_encoded(_type, _item, _src, _length_type, \ | |
356 | _src_length, _encoding) \ | |
357 | { \ | |
358 | _length_type __tmpl = __dynamic_len[__dynamic_len_idx]; \ | |
359 | lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_length_type));\ | |
360 | __chan->ops->event_write(&__ctx, &__tmpl, sizeof(_length_type));\ | |
361 | } \ | |
362 | lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_type)); \ | |
363 | __chan->ops->event_write(&__ctx, _src, \ | |
364 | sizeof(_type) * __get_dynamic_len(dest)); | |
365 | ||
366 | #undef ctf_string | |
367 | #define ctf_string(_item, _src) \ | |
368 | lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(*(_src))); \ | |
369 | __chan->ops->event_write(&__ctx, _src, __get_dynamic_len(dest)); | |
370 | ||
371 | /* Beware: this get len actually consumes the len value */ | |
372 | #undef __get_dynamic_len | |
373 | #define __get_dynamic_len(field) __dynamic_len[__dynamic_len_idx++] | |
374 | ||
375 | #undef TP_ARGS | |
376 | #define TP_ARGS(args...) args | |
377 | ||
378 | #undef TP_FIELDS | |
379 | #define TP_FIELDS(args...) args | |
380 | ||
381 | #undef TRACEPOINT_EVENT_CLASS | |
382 | #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \ | |
383 | static void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args))\ | |
384 | { \ | |
f280cb51 | 385 | struct ltt_event *__event = __tp_data; \ |
1c324e59 | 386 | struct ltt_channel *__chan = __event->chan; \ |
f280cb51 | 387 | struct lttng_ust_lib_ring_buffer_ctx __ctx; \ |
1c324e59 MD |
388 | size_t __event_len, __event_align; \ |
389 | size_t __dynamic_len_idx = 0; \ | |
390 | size_t __dynamic_len[_TP_ARRAY_SIZE(__event_fields___##_provider##___##_name)]; \ | |
391 | int __ret; \ | |
392 | \ | |
393 | if (0) \ | |
394 | (void) __dynamic_len_idx; /* don't warn if unused */ \ | |
395 | if (caa_unlikely(!CMM_ACCESS_ONCE(__chan->session->active))) \ | |
396 | return; \ | |
397 | if (caa_unlikely(!CMM_ACCESS_ONCE(__chan->enabled))) \ | |
398 | return; \ | |
399 | if (caa_unlikely(!CMM_ACCESS_ONCE(__event->enabled))) \ | |
400 | return; \ | |
401 | __event_len = __event_get_size__##_provider##___##_name(__dynamic_len,\ | |
402 | _TP_ARGS_DATA_VAR(_args)); \ | |
403 | __event_align = __event_get_align__##_provider##___##_name(_TP_ARGS_VAR(_args)); \ | |
404 | lib_ring_buffer_ctx_init(&__ctx, __chan->chan, __event, __event_len, \ | |
405 | __event_align, -1, __chan->handle); \ | |
406 | __ret = __chan->ops->event_reserve(&__ctx, __event->id); \ | |
407 | if (__ret < 0) \ | |
408 | return; \ | |
409 | _fields \ | |
410 | __chan->ops->event_commit(&__ctx); \ | |
411 | } | |
412 | ||
413 | #include TRACEPOINT_INCLUDE | |
414 | ||
415 | #undef __get_dynamic_len | |
416 | ||
05ceaafd | 417 | /* |
df854e41 | 418 | * Stage 6.1 of tracepoint event generation. |
05ceaafd MD |
419 | * |
420 | * Tracepoint loglevel enumeration definition generation. | |
421 | */ | |
422 | ||
423 | /* Reset all macros within TRACEPOINT_EVENT */ | |
424 | #include <lttng/ust-tracepoint-event-reset.h> | |
425 | ||
426 | #undef TRACEPOINT_LOGLEVEL_ENUM | |
427 | #define TRACEPOINT_LOGLEVEL_ENUM(...) __VA_ARGS__ | |
428 | ||
8e90eb06 MD |
429 | #undef tp_loglevel |
430 | #define tp_loglevel(_identifier, _value) \ | |
df854e41 MD |
431 | static const struct tracepoint_loglevel_entry \ |
432 | _TP_COMBINE_TOKENS4(__tp_loglevel_entry__, TRACEPOINT_PROVIDER, ___, _identifier) = { \ | |
05ceaafd MD |
433 | .identifier = #_identifier, \ |
434 | .value = (_value), \ | |
435 | }; | |
436 | ||
437 | #include TRACEPOINT_INCLUDE | |
438 | ||
439 | /* | |
df854e41 | 440 | * Stage 6.2 of tracepoint event generation. |
05ceaafd MD |
441 | * |
442 | * Tracepoint loglevel enumeration array generation. | |
443 | */ | |
444 | ||
445 | /* Reset all macros within TRACEPOINT_EVENT */ | |
446 | #include <lttng/ust-tracepoint-event-reset.h> | |
447 | ||
448 | #undef TRACEPOINT_LOGLEVEL_ENUM | |
449 | #define TRACEPOINT_LOGLEVEL_ENUM(...) __VA_ARGS__ | |
450 | ||
8e90eb06 MD |
451 | #undef tp_loglevel |
452 | #define tp_loglevel(_identifier, _value) \ | |
df854e41 | 453 | &_TP_COMBINE_TOKENS4(__tp_loglevel_entry__, TRACEPOINT_PROVIDER, ___, _identifier), \ |
05ceaafd | 454 | |
df854e41 | 455 | static const struct tracepoint_loglevel_entry *_TP_COMBINE_TOKENS(__tracepoint_loglevel_enum__, TRACEPOINT_PROVIDER)[] = { |
05ceaafd MD |
456 | #include TRACEPOINT_INCLUDE |
457 | }; | |
458 | ||
1c324e59 | 459 | /* |
df854e41 | 460 | * Stage 7 of tracepoint event generation. |
1c324e59 | 461 | * |
df854e41 MD |
462 | * Tracepoint loglevel mapping definition generation. We generate a |
463 | * symbol for each mapping for a provider/event to ensure at most a 1 to | |
464 | * 1 mapping between events and loglevels. If the symbol is repeated, | |
465 | * the compiler will complain. | |
05ceaafd MD |
466 | */ |
467 | ||
468 | /* Reset all macros within TRACEPOINT_EVENT */ | |
469 | #include <lttng/ust-tracepoint-event-reset.h> | |
470 | ||
471 | #undef TRACEPOINT_LOGLEVEL | |
df854e41 MD |
472 | #define TRACEPOINT_LOGLEVEL(__provider, __name, __loglevel) \ |
473 | static const struct tracepoint_loglevel_entry * \ | |
474 | _loglevel_mapping___##__provider##___##__name = \ | |
475 | &__tp_loglevel_entry__##__provider##___##__loglevel; | |
476 | ||
477 | #include TRACEPOINT_INCLUDE | |
478 | ||
479 | /* | |
480 | * Stage 8.1 of tracepoint event generation. | |
481 | * | |
482 | * Create events description structures. We use a weakref because | |
483 | * loglevels are optional. If not declared, the event will point to the | |
484 | * a loglevel that contains NULL. | |
485 | */ | |
486 | ||
487 | /* Reset all macros within TRACEPOINT_EVENT */ | |
488 | #include <lttng/ust-tracepoint-event-reset.h> | |
489 | ||
490 | #undef TRACEPOINT_EVENT_INSTANCE | |
491 | #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \ | |
492 | static const struct tracepoint_loglevel_entry * \ | |
493 | __ref_loglevel_mapping___##_provider##___##_name \ | |
494 | __attribute__((weakref ("_loglevel_mapping___" #_provider "___" #_name))); \ | |
495 | const struct lttng_event_desc __event_desc___##_provider##_##_name = { \ | |
496 | .fields = __event_fields___##_provider##___##_template, \ | |
497 | .name = #_provider ":" #_name, \ | |
498 | .probe_callback = (void *) &__event_probe__##_provider##___##_template,\ | |
499 | .nr_fields = _TP_ARRAY_SIZE(__event_fields___##_provider##___##_template), \ | |
500 | .loglevel = &__ref_loglevel_mapping___##_provider##___##_name, \ | |
501 | }; | |
502 | ||
503 | #include TRACEPOINT_INCLUDE | |
05ceaafd | 504 | |
df854e41 MD |
505 | /* |
506 | * Stage 8.2 of tracepoint event generation. | |
507 | * | |
508 | * Create array of events. | |
509 | */ | |
510 | ||
511 | /* Reset all macros within TRACEPOINT_EVENT */ | |
512 | #include <lttng/ust-tracepoint-event-reset.h> | |
513 | ||
514 | #undef TRACEPOINT_EVENT_INSTANCE | |
515 | #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \ | |
516 | &__event_desc___##_provider##_##_name, | |
517 | ||
518 | static const struct lttng_event_desc *_TP_COMBINE_TOKENS(__event_desc___, TRACEPOINT_PROVIDER)[] = { | |
05ceaafd MD |
519 | #include TRACEPOINT_INCLUDE |
520 | }; | |
521 | ||
df854e41 | 522 | |
05ceaafd MD |
523 | /* |
524 | * Stage 9 of tracepoint event generation. | |
525 | * | |
526 | * Create a toplevel descriptor for the whole probe. | |
527 | */ | |
528 | ||
529 | /* non-const because list head will be modified when registered. */ | |
530 | static struct lttng_probe_desc _TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER) = { | |
df854e41 | 531 | .provider = __tp_stringify(TRACEPOINT_PROVIDER), |
05ceaafd MD |
532 | .event_desc = _TP_COMBINE_TOKENS(__event_desc___, TRACEPOINT_PROVIDER), |
533 | .nr_events = _TP_ARRAY_SIZE(_TP_COMBINE_TOKENS(__event_desc___, TRACEPOINT_PROVIDER)), | |
df854e41 MD |
534 | .loglevels = _TP_COMBINE_TOKENS(__tracepoint_loglevel_enum__, TRACEPOINT_PROVIDER), |
535 | .nr_loglevels = _TP_ARRAY_SIZE(_TP_COMBINE_TOKENS(__tracepoint_loglevel_enum__, TRACEPOINT_PROVIDER)), | |
05ceaafd MD |
536 | }; |
537 | ||
538 | /* | |
539 | * Stage 10 of tracepoint event generation. | |
540 | * | |
1c324e59 MD |
541 | * Register/unregister probes at module load/unload. |
542 | */ | |
543 | ||
544 | /* Reset all macros within TRACEPOINT_EVENT */ | |
545 | #include <lttng/ust-tracepoint-event-reset.h> | |
546 | ||
547 | static void __attribute__((constructor)) | |
548 | _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void) | |
549 | { | |
550 | int ret; | |
551 | ||
552 | ret = ltt_probe_register(&_TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER)); | |
553 | assert(!ret); | |
554 | } | |
555 | ||
556 | static void __attribute__((destructor)) | |
557 | _TP_COMBINE_TOKENS(__lttng_events_exit__, TRACEPOINT_PROVIDER)(void) | |
558 | { | |
559 | ltt_probe_unregister(&_TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER)); | |
560 | } |