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 | * | |
218 | * Create an array of events. | |
219 | */ | |
220 | ||
221 | /* Reset all macros within TRACEPOINT_EVENT */ | |
222 | #include <lttng/ust-tracepoint-event-reset.h> | |
223 | ||
224 | #undef TRACEPOINT_EVENT_INSTANCE | |
225 | #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \ | |
226 | { \ | |
227 | .fields = __event_fields___##_provider##___##_template,\ | |
228 | .name = #_provider ":" #_name, \ | |
229 | .probe_callback = (void *) &__event_probe__##_provider##___##_template,\ | |
230 | .nr_fields = _TP_ARRAY_SIZE(__event_fields___##_provider##___##_template), \ | |
231 | }, | |
232 | ||
233 | static const struct lttng_event_desc _TP_COMBINE_TOKENS(__event_desc___, TRACEPOINT_PROVIDER)[] = { | |
234 | #include TRACEPOINT_INCLUDE | |
235 | }; | |
236 | ||
237 | ||
238 | /* | |
239 | * Stage 4 of tracepoint event generation. | |
240 | * | |
1c324e59 MD |
241 | * Create static inline function that calculates event size. |
242 | */ | |
243 | ||
244 | /* Reset all macros within TRACEPOINT_EVENT */ | |
245 | #include <lttng/ust-tracepoint-event-reset.h> | |
246 | ||
247 | #undef ctf_integer_ext | |
248 | #define ctf_integer_ext(_type, _item, _src, _byte_order, _base) \ | |
249 | __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \ | |
250 | __event_len += sizeof(_type); | |
251 | ||
252 | #undef ctf_float | |
253 | #define ctf_float(_type, _item, _src) \ | |
254 | __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \ | |
255 | __event_len += sizeof(_type); | |
256 | ||
257 | #undef ctf_array_encoded | |
258 | #define ctf_array_encoded(_type, _item, _src, _length, _encoding) \ | |
259 | __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \ | |
260 | __event_len += sizeof(_type) * (_length); | |
261 | ||
262 | #undef ctf_sequence_encoded | |
263 | #define ctf_sequence_encoded(_type, _item, _src, _length_type, \ | |
264 | _src_length, _encoding) \ | |
265 | __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_length_type)); \ | |
266 | __event_len += sizeof(_length_type); \ | |
267 | __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \ | |
268 | __dynamic_len[__dynamic_len_idx] = (_src_length); \ | |
269 | __event_len += sizeof(_type) * __dynamic_len[__dynamic_len_idx]; \ | |
270 | __dynamic_len_idx++; | |
271 | ||
272 | #undef ctf_string | |
273 | #define ctf_string(_item, _src) \ | |
274 | __event_len += __dynamic_len[__dynamic_len_idx++] = strlen(_src) + 1; | |
275 | ||
276 | #undef TP_ARGS | |
277 | #define TP_ARGS(args...) args | |
278 | ||
279 | #undef TP_FIELDS | |
280 | #define TP_FIELDS(args...) args | |
281 | ||
282 | #undef TRACEPOINT_EVENT_CLASS | |
283 | #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \ | |
284 | static inline size_t __event_get_size__##_provider##___##_name(size_t *__dynamic_len, _TP_ARGS_DATA_PROTO(_args)) \ | |
285 | { \ | |
286 | size_t __event_len = 0; \ | |
287 | unsigned int __dynamic_len_idx = 0; \ | |
288 | \ | |
289 | if (0) \ | |
290 | (void) __dynamic_len_idx; /* don't warn if unused */ \ | |
291 | _fields \ | |
292 | return __event_len; \ | |
293 | } | |
294 | ||
295 | #include TRACEPOINT_INCLUDE | |
296 | ||
297 | /* | |
05ceaafd | 298 | * Stage 5 of tracepoint event generation. |
1c324e59 MD |
299 | * |
300 | * Create static inline function that calculates event payload alignment. | |
301 | */ | |
302 | ||
303 | /* Reset all macros within TRACEPOINT_EVENT */ | |
304 | #include <lttng/ust-tracepoint-event-reset.h> | |
305 | ||
306 | #undef ctf_integer_ext | |
307 | #define ctf_integer_ext(_type, _item, _src, _byte_order, _base) \ | |
308 | __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_type)); | |
309 | ||
310 | #undef ctf_float | |
311 | #define ctf_float(_type, _item, _src) \ | |
312 | __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_type)); | |
313 | ||
314 | #undef ctf_array_encoded | |
315 | #define ctf_array_encoded(_type, _item, _src, _length, _encoding) \ | |
316 | __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_type)); | |
317 | ||
318 | #undef ctf_sequence_encoded | |
319 | #define ctf_sequence_encoded(_type, _item, _src, _length_type, \ | |
320 | _src_length, _encoding) \ | |
321 | __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_length_type)); \ | |
322 | __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_type)); | |
323 | ||
324 | #undef ctf_string | |
325 | #define ctf_string(_item, _src) | |
326 | ||
327 | #undef TP_ARGS | |
328 | #define TP_ARGS(args...) args | |
329 | ||
330 | #undef TP_FIELDS | |
331 | #define TP_FIELDS(args...) args | |
332 | ||
333 | #undef TRACEPOINT_EVENT_CLASS | |
334 | #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \ | |
335 | static inline \ | |
336 | size_t __event_get_align__##_provider##___##_name(_TP_ARGS_PROTO(_args)) \ | |
337 | { \ | |
338 | size_t __event_align = 1; \ | |
339 | _fields \ | |
340 | return __event_align; \ | |
341 | } | |
342 | ||
343 | #include TRACEPOINT_INCLUDE | |
344 | ||
345 | ||
346 | /* | |
05ceaafd | 347 | * Stage 6 of tracepoint event generation. |
1c324e59 MD |
348 | * |
349 | * Create the probe function. This function calls event size calculation | |
350 | * and writes event data into the buffer. | |
351 | */ | |
352 | ||
353 | /* Reset all macros within TRACEPOINT_EVENT */ | |
354 | #include <lttng/ust-tracepoint-event-reset.h> | |
355 | ||
356 | #undef ctf_integer_ext | |
357 | #define ctf_integer_ext(_type, _item, _src, _byte_order, _base) \ | |
358 | { \ | |
359 | _type __tmp = (_src); \ | |
360 | lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__tmp));\ | |
361 | __chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp));\ | |
362 | } | |
363 | ||
364 | #undef ctf_float | |
365 | #define ctf_float(_type, _item, _src) \ | |
366 | { \ | |
367 | _type __tmp = (_src); \ | |
368 | lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__tmp));\ | |
369 | __chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp));\ | |
370 | } | |
371 | ||
372 | #undef ctf_array_encoded | |
373 | #define ctf_array_encoded(_type, _item, _src, _length, _encoding) \ | |
374 | lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_type)); \ | |
375 | __chan->ops->event_write(&__ctx, _src, sizeof(_type) * (_length)); | |
376 | ||
377 | #undef ctf_sequence_encoded | |
378 | #define ctf_sequence_encoded(_type, _item, _src, _length_type, \ | |
379 | _src_length, _encoding) \ | |
380 | { \ | |
381 | _length_type __tmpl = __dynamic_len[__dynamic_len_idx]; \ | |
382 | lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_length_type));\ | |
383 | __chan->ops->event_write(&__ctx, &__tmpl, sizeof(_length_type));\ | |
384 | } \ | |
385 | lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_type)); \ | |
386 | __chan->ops->event_write(&__ctx, _src, \ | |
387 | sizeof(_type) * __get_dynamic_len(dest)); | |
388 | ||
389 | #undef ctf_string | |
390 | #define ctf_string(_item, _src) \ | |
391 | lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(*(_src))); \ | |
392 | __chan->ops->event_write(&__ctx, _src, __get_dynamic_len(dest)); | |
393 | ||
394 | /* Beware: this get len actually consumes the len value */ | |
395 | #undef __get_dynamic_len | |
396 | #define __get_dynamic_len(field) __dynamic_len[__dynamic_len_idx++] | |
397 | ||
398 | #undef TP_ARGS | |
399 | #define TP_ARGS(args...) args | |
400 | ||
401 | #undef TP_FIELDS | |
402 | #define TP_FIELDS(args...) args | |
403 | ||
404 | #undef TRACEPOINT_EVENT_CLASS | |
405 | #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \ | |
406 | static void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args))\ | |
407 | { \ | |
f280cb51 | 408 | struct ltt_event *__event = __tp_data; \ |
1c324e59 | 409 | struct ltt_channel *__chan = __event->chan; \ |
f280cb51 | 410 | struct lttng_ust_lib_ring_buffer_ctx __ctx; \ |
1c324e59 MD |
411 | size_t __event_len, __event_align; \ |
412 | size_t __dynamic_len_idx = 0; \ | |
413 | size_t __dynamic_len[_TP_ARRAY_SIZE(__event_fields___##_provider##___##_name)]; \ | |
414 | int __ret; \ | |
415 | \ | |
416 | if (0) \ | |
417 | (void) __dynamic_len_idx; /* don't warn if unused */ \ | |
418 | if (caa_unlikely(!CMM_ACCESS_ONCE(__chan->session->active))) \ | |
419 | return; \ | |
420 | if (caa_unlikely(!CMM_ACCESS_ONCE(__chan->enabled))) \ | |
421 | return; \ | |
422 | if (caa_unlikely(!CMM_ACCESS_ONCE(__event->enabled))) \ | |
423 | return; \ | |
424 | __event_len = __event_get_size__##_provider##___##_name(__dynamic_len,\ | |
425 | _TP_ARGS_DATA_VAR(_args)); \ | |
426 | __event_align = __event_get_align__##_provider##___##_name(_TP_ARGS_VAR(_args)); \ | |
427 | lib_ring_buffer_ctx_init(&__ctx, __chan->chan, __event, __event_len, \ | |
428 | __event_align, -1, __chan->handle); \ | |
429 | __ret = __chan->ops->event_reserve(&__ctx, __event->id); \ | |
430 | if (__ret < 0) \ | |
431 | return; \ | |
432 | _fields \ | |
433 | __chan->ops->event_commit(&__ctx); \ | |
434 | } | |
435 | ||
436 | #include TRACEPOINT_INCLUDE | |
437 | ||
438 | #undef __get_dynamic_len | |
439 | ||
05ceaafd MD |
440 | /* |
441 | * Stage 7.1 of tracepoint event generation. | |
442 | * | |
443 | * Tracepoint loglevel enumeration definition generation. | |
444 | */ | |
445 | ||
446 | /* Reset all macros within TRACEPOINT_EVENT */ | |
447 | #include <lttng/ust-tracepoint-event-reset.h> | |
448 | ||
449 | #undef TRACEPOINT_LOGLEVEL_ENUM | |
450 | #define TRACEPOINT_LOGLEVEL_ENUM(...) __VA_ARGS__ | |
451 | ||
452 | #undef TP_LOGLEVEL | |
453 | #define TP_LOGLEVEL(_identifier, _value) \ | |
454 | static const struct tracepoint_loglevel_enum_entry \ | |
455 | _TP_COMBINE_TOKENS(_TP_COMBINE_TOKENS(TRACEPOINT_PROVIDER, __tp_loglevel_enum_entry__), _identifier) = \ | |
456 | { \ | |
457 | .identifier = #_identifier, \ | |
458 | .value = (_value), \ | |
459 | }; | |
460 | ||
461 | #include TRACEPOINT_INCLUDE | |
462 | ||
463 | /* | |
464 | * Stage 7.2 of tracepoint event generation. | |
465 | * | |
466 | * Tracepoint loglevel enumeration array generation. | |
467 | */ | |
468 | ||
469 | /* Reset all macros within TRACEPOINT_EVENT */ | |
470 | #include <lttng/ust-tracepoint-event-reset.h> | |
471 | ||
472 | #undef TRACEPOINT_LOGLEVEL_ENUM | |
473 | #define TRACEPOINT_LOGLEVEL_ENUM(...) __VA_ARGS__ | |
474 | ||
475 | #undef TP_LOGLEVEL | |
476 | #define TP_LOGLEVEL(_identifier, _value) \ | |
477 | &_TP_COMBINE_TOKENS(_TP_COMBINE_TOKENS(TRACEPOINT_PROVIDER, __tp_loglevel_enum_entry__), _identifier), | |
478 | ||
479 | static const struct tracepoint_loglevel_enum_entry *_TP_COMBINE_TOKENS(__tracepoint_loglevel_enum__, TRACEPOINT_PROVIDER)[] __attribute__((unused)) = | |
480 | { | |
481 | #include TRACEPOINT_INCLUDE | |
482 | }; | |
483 | ||
1c324e59 MD |
484 | /* |
485 | * Stage 8 of tracepoint event generation. | |
486 | * | |
05ceaafd MD |
487 | * Tracepoint loglevel definition generation. |
488 | */ | |
489 | ||
490 | /* Reset all macros within TRACEPOINT_EVENT */ | |
491 | #include <lttng/ust-tracepoint-event-reset.h> | |
492 | ||
493 | #undef TRACEPOINT_LOGLEVEL | |
494 | #define TRACEPOINT_LOGLEVEL(__provider, __name, __loglevel) \ | |
495 | { \ | |
496 | .name = #__provider ":" #__name, \ | |
497 | .loglevel = &_TP_COMBINE_TOKENS(_TP_COMBINE_TOKENS(TRACEPOINT_PROVIDER, __tp_loglevel_enum_entry__), __loglevel), \ | |
498 | }, | |
499 | ||
500 | static struct tracepoint_loglevel _TP_COMBINE_TOKENS(__tracepoint_loglevels__, TRACEPOINT_PROVIDER)[] = { | |
501 | #include TRACEPOINT_INCLUDE | |
502 | }; | |
503 | ||
504 | /* | |
505 | * Stage 9 of tracepoint event generation. | |
506 | * | |
507 | * Create a toplevel descriptor for the whole probe. | |
508 | */ | |
509 | ||
510 | /* non-const because list head will be modified when registered. */ | |
511 | static struct lttng_probe_desc _TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER) = { | |
512 | .event_desc = _TP_COMBINE_TOKENS(__event_desc___, TRACEPOINT_PROVIDER), | |
513 | .nr_events = _TP_ARRAY_SIZE(_TP_COMBINE_TOKENS(__event_desc___, TRACEPOINT_PROVIDER)), | |
514 | .loglevels = _TP_COMBINE_TOKENS(__tracepoint_loglevels__, TRACEPOINT_PROVIDER), | |
515 | }; | |
516 | ||
517 | /* | |
518 | * Stage 10 of tracepoint event generation. | |
519 | * | |
1c324e59 MD |
520 | * Register/unregister probes at module load/unload. |
521 | */ | |
522 | ||
523 | /* Reset all macros within TRACEPOINT_EVENT */ | |
524 | #include <lttng/ust-tracepoint-event-reset.h> | |
525 | ||
526 | static void __attribute__((constructor)) | |
527 | _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void) | |
528 | { | |
529 | int ret; | |
530 | ||
531 | ret = ltt_probe_register(&_TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER)); | |
532 | assert(!ret); | |
533 | } | |
534 | ||
535 | static void __attribute__((destructor)) | |
536 | _TP_COMBINE_TOKENS(__lttng_events_exit__, TRACEPOINT_PROVIDER)(void) | |
537 | { | |
538 | ltt_probe_unregister(&_TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER)); | |
539 | } |