Commit | Line | Data |
---|---|---|
40652b65 | 1 | #include <lttng.h> |
299338c8 | 2 | #include <lttng-types.h> |
d0dd2ecb | 3 | #include <linux/debugfs.h> |
e763dbf5 MD |
4 | #include <linux/ringbuffer/frontend_types.h> |
5 | #include "../ltt-events.h" | |
6db3d13b | 6 | #include "../ltt-tracer-core.h" |
40652b65 | 7 | |
299338c8 MD |
8 | struct lttng_event_field { |
9 | const char *name; | |
10 | const struct lttng_type type; | |
11 | }; | |
12 | ||
13 | struct lttng_event_desc { | |
14 | const struct lttng_event_field *fields; | |
d0dd2ecb | 15 | const char *name; |
19c57fbf | 16 | void *probe_callback; |
d0dd2ecb | 17 | unsigned int nr_fields; |
299338c8 | 18 | }; |
40652b65 MD |
19 | |
20 | /* | |
6db3d13b | 21 | * Macro declarations used for all stages. |
40652b65 MD |
22 | */ |
23 | ||
24 | /* | |
25 | * DECLARE_EVENT_CLASS can be used to add a generic function | |
26 | * handlers for events. That is, if all events have the same | |
27 | * parameters and just have distinct trace points. | |
28 | * Each tracepoint can be defined with DEFINE_EVENT and that | |
29 | * will map the DECLARE_EVENT_CLASS to the tracepoint. | |
30 | * | |
31 | * TRACE_EVENT is a one to one mapping between tracepoint and template. | |
32 | */ | |
6db3d13b | 33 | |
40652b65 MD |
34 | #undef TRACE_EVENT |
35 | #define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ | |
36 | DECLARE_EVENT_CLASS(name, \ | |
37 | PARAMS(proto), \ | |
38 | PARAMS(args), \ | |
39 | PARAMS(tstruct), \ | |
40 | PARAMS(assign), \ | |
299338c8 MD |
41 | PARAMS(print)) \ |
42 | DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args)) | |
40652b65 | 43 | |
6db3d13b MD |
44 | #undef DEFINE_EVENT_PRINT |
45 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ | |
46 | DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) | |
47 | ||
48 | /* Callbacks are meaningless to LTTng. */ | |
49 | #undef TRACE_EVENT_FN | |
50 | #define TRACE_EVENT_FN(name, proto, args, tstruct, \ | |
51 | assign, print, reg, unreg) \ | |
52 | TRACE_EVENT(name, PARAMS(proto), PARAMS(args), \ | |
53 | PARAMS(tstruct), PARAMS(assign), PARAMS(print)) \ | |
54 | ||
55 | /* | |
56 | * Stage 1 of the trace events. | |
57 | * | |
58 | * Create event field type metadata section. | |
59 | * Each event produce an array of fields. | |
60 | */ | |
61 | ||
62 | #include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ | |
63 | ||
1d12cebd MD |
64 | /* Named field types must be defined in lttng-types.h */ |
65 | ||
40652b65 | 66 | #undef __field |
299338c8 MD |
67 | #define __field(_type, _item) \ |
68 | { .name = #_item, .type = { .atype = atype_integer, .name = #_type} }, | |
40652b65 MD |
69 | |
70 | #undef __field_ext | |
6db3d13b | 71 | #define __field_ext(_type, _item, _filter_type) __field(_type, _item) |
40652b65 MD |
72 | |
73 | #undef __array | |
299338c8 MD |
74 | #define __array(_type, _item, _length) \ |
75 | { \ | |
76 | .name = #_item, \ | |
77 | .type = { \ | |
78 | .atype = atype_array, \ | |
79 | .name = NULL, \ | |
80 | .u.array.elem_type = #_type, \ | |
81 | .u.array.length = _length, \ | |
82 | }, \ | |
83 | }, | |
40652b65 MD |
84 | |
85 | #undef __dynamic_array | |
299338c8 MD |
86 | #define __dynamic_array(_type, _item, _length) \ |
87 | { \ | |
88 | .name = #_item, \ | |
89 | .type = { \ | |
90 | .atype = atype_sequence, \ | |
91 | .name = NULL, \ | |
92 | .u.sequence.elem_type = #_type, \ | |
93 | .u.sequence.length_type = "u32", \ | |
94 | }, \ | |
95 | }, | |
40652b65 MD |
96 | |
97 | #undef __string | |
1d12cebd | 98 | #define __string(_item, _src) \ |
299338c8 | 99 | { \ |
0d1d4002 | 100 | .name = #_item, \ |
299338c8 MD |
101 | .type = { \ |
102 | .atype = atype_string, \ | |
103 | .name = NULL, \ | |
104 | .u.string.encoding = lttng_encode_UTF8, \ | |
105 | }, \ | |
106 | }, | |
1d12cebd | 107 | |
40652b65 | 108 | #undef TP_STRUCT__entry |
1d12cebd MD |
109 | #define TP_STRUCT__entry(args...) args /* Only one used in this phase */ |
110 | ||
40652b65 | 111 | #undef DECLARE_EVENT_CLASS |
0d1d4002 MD |
112 | #define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ |
113 | static const struct lttng_event_field __event_fields___##_name[] = { \ | |
114 | _tstruct \ | |
299338c8 MD |
115 | }; |
116 | ||
299338c8 MD |
117 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
118 | ||
19c57fbf MD |
119 | /* |
120 | * Stage 1.1 of the trace events. | |
121 | * | |
122 | * Create probe callback prototypes. | |
123 | */ | |
124 | ||
125 | #include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ | |
126 | ||
127 | #undef TP_PROTO | |
128 | #define TP_PROTO(args...) args | |
129 | ||
130 | #undef DECLARE_EVENT_CLASS | |
131 | #define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ | |
132 | static void __event_probe__##_name(void *__data, _proto); | |
133 | ||
134 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | |
135 | ||
299338c8 MD |
136 | /* |
137 | * Stage 2 of the trace events. | |
138 | * | |
139 | * Create an array of events. | |
140 | */ | |
141 | ||
299338c8 MD |
142 | /* Named field types must be defined in lttng-types.h */ |
143 | ||
6db3d13b | 144 | #include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ |
299338c8 | 145 | |
d32a57a2 MD |
146 | #undef DEFINE_EVENT |
147 | #define DEFINE_EVENT(_template, _name, _proto, _args) \ | |
148 | { \ | |
149 | .fields = __event_fields___##_template, \ | |
150 | .name = #_name, \ | |
19c57fbf | 151 | .probe_callback = (void *) &__event_probe__##_template,\ |
d32a57a2 | 152 | .nr_fields = ARRAY_SIZE(__event_fields___##_template), \ |
6db3d13b | 153 | }, |
40652b65 | 154 | |
d0dd2ecb MD |
155 | #define TP_ID1(_token, _system) _token##_system |
156 | #define TP_ID(_token, _system) TP_ID1(_token, _system) | |
40652b65 | 157 | |
d0dd2ecb | 158 | static const struct lttng_event_desc TP_ID(__event_desc___, TRACE_SYSTEM)[] = { |
40652b65 | 159 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
299338c8 MD |
160 | }; |
161 | ||
d0dd2ecb MD |
162 | #undef TP_ID1 |
163 | #undef TP_ID | |
164 | ||
165 | /* | |
166 | * Stage 3 of the trace events. | |
167 | * | |
168 | * Create seq file metadata output. | |
169 | */ | |
170 | ||
d0dd2ecb MD |
171 | #define TP_ID1(_token, _system) _token##_system |
172 | #define TP_ID(_token, _system) TP_ID1(_token, _system) | |
d0dd2ecb MD |
173 | |
174 | static void *TP_ID(__lttng_seq_start__, TRACE_SYSTEM)(struct seq_file *m, | |
175 | loff_t *pos) | |
176 | { | |
6db3d13b MD |
177 | const struct lttng_event_desc *desc = |
178 | &TP_ID(__event_desc___, TRACE_SYSTEM)[*pos]; | |
d0dd2ecb | 179 | |
6db3d13b MD |
180 | if (desc > &TP_ID(__event_desc___, TRACE_SYSTEM) |
181 | [ARRAY_SIZE(TP_ID(__event_desc___, TRACE_SYSTEM)) - 1]) | |
d0dd2ecb MD |
182 | return NULL; |
183 | return (void *) desc; | |
184 | } | |
185 | ||
186 | static void *TP_ID(__lttng_seq_next__, TRACE_SYSTEM)(struct seq_file *m, | |
187 | void *p, loff_t *ppos) | |
188 | { | |
6db3d13b MD |
189 | const struct lttng_event_desc *desc = |
190 | &TP_ID(__event_desc___, TRACE_SYSTEM)[++(*ppos)]; | |
d0dd2ecb | 191 | |
6db3d13b MD |
192 | if (desc > &TP_ID(__event_desc___, TRACE_SYSTEM) |
193 | [ARRAY_SIZE(TP_ID(__event_desc___, TRACE_SYSTEM)) - 1]) | |
d0dd2ecb MD |
194 | return NULL; |
195 | return (void *) desc; | |
196 | } | |
197 | ||
198 | static void TP_ID(__lttng_seq_stop__, TRACE_SYSTEM)(struct seq_file *m, | |
199 | void *p) | |
200 | { | |
201 | } | |
202 | ||
203 | static int TP_ID(__lttng_seq_show__, TRACE_SYSTEM)(struct seq_file *m, | |
204 | void *p) | |
205 | { | |
206 | const struct lttng_event_desc *desc = p; | |
207 | int i; | |
208 | ||
209 | seq_printf(m, "event {\n" | |
210 | "\tname = %s;\n" | |
211 | "\tid = UNKNOWN;\n" | |
212 | "\tstream = UNKNOWN;\n" | |
213 | "\tfields = {\n", | |
214 | desc->name); | |
215 | for (i = 0; i < desc->nr_fields; i++) { | |
216 | if (desc->fields[i].type.name) /* Named type */ | |
217 | seq_printf(m, "\t\t%s", | |
218 | desc->fields[i].type.name); | |
219 | else /* Nameless type */ | |
220 | lttng_print_event_type(m, 2, &desc->fields[i].type); | |
221 | seq_printf(m, " %s;\n", desc->fields[i].name); | |
222 | } | |
223 | seq_printf(m, "\t};\n"); | |
224 | seq_printf(m, "};\n"); | |
225 | return 0; | |
226 | } | |
227 | ||
228 | static const | |
229 | struct seq_operations TP_ID(__lttng_types_seq_ops__, TRACE_SYSTEM) = { | |
230 | .start = TP_ID(__lttng_seq_start__, TRACE_SYSTEM), | |
231 | .next = TP_ID(__lttng_seq_next__, TRACE_SYSTEM), | |
232 | .stop = TP_ID(__lttng_seq_stop__, TRACE_SYSTEM), | |
233 | .show = TP_ID(__lttng_seq_show__, TRACE_SYSTEM), | |
234 | }; | |
235 | ||
236 | static int | |
237 | TP_ID(__lttng_types_open__, TRACE_SYSTEM)(struct inode *inode, struct file *file) | |
238 | { | |
239 | return seq_open(file, &TP_ID(__lttng_types_seq_ops__, TRACE_SYSTEM)); | |
240 | } | |
241 | ||
6db3d13b MD |
242 | static const |
243 | struct file_operations TP_ID(__lttng_types_fops__, TRACE_SYSTEM) = { | |
d0dd2ecb MD |
244 | .open = TP_ID(__lttng_types_open__, TRACE_SYSTEM), |
245 | .read = seq_read, | |
246 | .llseek = seq_lseek, | |
247 | .release = seq_release_private, | |
248 | }; | |
249 | ||
250 | static struct dentry *TP_ID(__lttng_types_dentry__, TRACE_SYSTEM); | |
251 | ||
252 | static int TP_ID(__lttng_types_init__, TRACE_SYSTEM)(void) | |
253 | { | |
254 | int ret = 0; | |
255 | ||
256 | TP_ID(__lttng_types_dentry__, TRACE_SYSTEM) = | |
6db3d13b MD |
257 | debugfs_create_file("lttng-events-" __stringify(TRACE_SYSTEM), |
258 | S_IWUSR, NULL, NULL, | |
259 | &TP_ID(__lttng_types_fops__, TRACE_SYSTEM)); | |
d0dd2ecb MD |
260 | if (IS_ERR(TP_ID(__lttng_types_dentry__, TRACE_SYSTEM)) |
261 | || !TP_ID(__lttng_types_dentry__, TRACE_SYSTEM)) { | |
262 | printk(KERN_ERR "Error creating LTTng type export file\n"); | |
263 | ret = -ENOMEM; | |
264 | goto error; | |
265 | } | |
266 | error: | |
267 | return ret; | |
268 | } | |
269 | ||
d0dd2ecb MD |
270 | static void TP_ID(__lttng_types_exit__, TRACE_SYSTEM)(void) |
271 | { | |
272 | debugfs_remove(TP_ID(__lttng_types_dentry__, TRACE_SYSTEM)); | |
273 | } | |
274 | ||
d0dd2ecb MD |
275 | #undef TP_ID1 |
276 | #undef TP_ID | |
277 | ||
40652b65 | 278 | /* |
6db3d13b | 279 | * Stage 4 of the trace events. |
40652b65 MD |
280 | * |
281 | * Create static inline function that calculates event size. | |
282 | */ | |
283 | ||
6db3d13b | 284 | #include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ |
40652b65 | 285 | |
6db3d13b MD |
286 | /* Named field types must be defined in lttng-types.h */ |
287 | ||
288 | #undef __field | |
85a80742 MD |
289 | #define __field(_type, _item) \ |
290 | __event_len += lib_ring_buffer_align(__event_len, __alignof__(_type)); \ | |
0d1d4002 | 291 | __event_len += sizeof(_type); |
6db3d13b MD |
292 | |
293 | #undef __field_ext | |
294 | #define __field_ext(_type, _item, _filter_type) __field(_type, _item) | |
295 | ||
296 | #undef __array | |
85a80742 MD |
297 | #define __array(_type, _item, _length) \ |
298 | __event_len += lib_ring_buffer_align(__event_len, __alignof__(_type)); \ | |
0d1d4002 | 299 | __event_len += sizeof(_type) * (_length); |
6db3d13b MD |
300 | |
301 | #undef __dynamic_array | |
85a80742 MD |
302 | #define __dynamic_array(_type, _item, _length) \ |
303 | __event_len += lib_ring_buffer_align(__event_len, __alignof__(u32)); \ | |
304 | __event_len += sizeof(u32); \ | |
305 | __event_len += lib_ring_buffer_align(__event_len, __alignof__(_type)); \ | |
0d1d4002 | 306 | __event_len += sizeof(_type) * (_length); |
6db3d13b MD |
307 | |
308 | #undef __string | |
85a80742 | 309 | #define __string(_item, _src) \ |
0d1d4002 MD |
310 | __event_len += __dynamic_len[__dynamic_len_idx++] = strlen(_src) + 1; |
311 | ||
312 | #undef TP_PROTO | |
313 | #define TP_PROTO(args...) args | |
6db3d13b MD |
314 | |
315 | #undef TP_STRUCT__entry | |
0d1d4002 | 316 | #define TP_STRUCT__entry(args...) args |
6db3d13b MD |
317 | |
318 | #undef DECLARE_EVENT_CLASS | |
0d1d4002 MD |
319 | #define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ |
320 | static inline size_t __event_get_size__##_name(size_t *__dynamic_len, _proto) \ | |
321 | { \ | |
322 | size_t __event_len = 0; \ | |
323 | unsigned int __dynamic_len_idx = 0; \ | |
324 | \ | |
325 | if (0) \ | |
326 | (void) __dynamic_len_idx; /* don't warn if unused */ \ | |
327 | _tstruct \ | |
328 | return __event_len; \ | |
6db3d13b | 329 | } |
40652b65 MD |
330 | |
331 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | |
332 | ||
6db3d13b | 333 | |
6db3d13b | 334 | |
40652b65 | 335 | /* |
e763dbf5 MD |
336 | * Stage 5 of the trace events. |
337 | * | |
338 | * Create static inline function that calculates event payload alignment. | |
339 | */ | |
340 | ||
341 | #include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ | |
342 | ||
343 | /* Named field types must be defined in lttng-types.h */ | |
344 | ||
345 | #undef __field | |
346 | #define __field(_type, _item) \ | |
67e5e60c | 347 | __event_align = max_t(size_t, __event_align, __alignof__(_type)); |
e763dbf5 MD |
348 | |
349 | #undef __field_ext | |
350 | #define __field_ext(_type, _item, _filter_type) __field(_type, _item) | |
351 | ||
352 | #undef __array | |
353 | #define __array(_type, _item, _length) \ | |
67e5e60c | 354 | __event_align = max_t(size_t, __event_align, __alignof__(_type)); |
e763dbf5 MD |
355 | |
356 | #undef __dynamic_array | |
357 | #define __dynamic_array(_type, _item, _length) \ | |
67e5e60c MD |
358 | __event_align = max_t(size_t, __event_align, __alignof__(u32)); \ |
359 | __event_align = max_t(size_t, __event_align, __alignof__(_type)); | |
e763dbf5 MD |
360 | |
361 | #undef __string | |
362 | #define __string(_item, _src) | |
363 | ||
364 | #undef TP_PROTO | |
365 | #define TP_PROTO(args...) args | |
366 | ||
367 | #undef TP_STRUCT__entry | |
368 | #define TP_STRUCT__entry(args...) args | |
369 | ||
370 | #undef DECLARE_EVENT_CLASS | |
371 | #define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ | |
372 | static inline size_t __event_get_align__##_name(_proto) \ | |
373 | { \ | |
374 | size_t __event_align = 1; \ | |
375 | _tstruct \ | |
376 | return __event_align; \ | |
377 | } | |
378 | ||
379 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | |
380 | ||
381 | ||
e763dbf5 MD |
382 | /* |
383 | * Stage 6 of the trace events. | |
40652b65 | 384 | * |
3c4ffab9 MD |
385 | * Create structure declaration that allows the "assign" macros to access the |
386 | * field types. | |
387 | */ | |
388 | ||
389 | #include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ | |
390 | ||
391 | /* Named field types must be defined in lttng-types.h */ | |
392 | ||
393 | #undef __field | |
394 | #define __field(_type, _item) _type _item; | |
395 | ||
396 | #undef __field_ext | |
397 | #define __field_ext(_type, _item, _filter_type) __field(_type, _item) | |
398 | ||
399 | #undef __array | |
400 | #define __array(_type, _item, _length) _type _item; | |
401 | ||
402 | #undef __dynamic_array | |
403 | #define __dynamic_array(_type, _item, _length) _type _item; | |
404 | ||
405 | #undef __string | |
406 | #define __string(_item, _src) char _item; | |
407 | ||
408 | #undef TP_STRUCT__entry | |
409 | #define TP_STRUCT__entry(args...) args | |
410 | ||
411 | #undef DECLARE_EVENT_CLASS | |
412 | #define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ | |
413 | struct __event_typemap__##_name { \ | |
414 | _tstruct \ | |
415 | }; | |
416 | ||
417 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | |
418 | ||
419 | ||
420 | /* | |
421 | * Stage 7 of the trace events. | |
422 | * | |
40652b65 MD |
423 | * Create the probe function : call even size calculation and write event data |
424 | * into the buffer. | |
e763dbf5 | 425 | * |
67e5e60c MD |
426 | * We use both the field and assignment macros to write the fields in the order |
427 | * defined in the field declaration. The field declarations control the | |
428 | * execution order, jumping to the appropriate assignment block. | |
40652b65 MD |
429 | */ |
430 | ||
e763dbf5 MD |
431 | #include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ |
432 | ||
433 | #undef __field | |
434 | #define __field(_type, _item) \ | |
e763dbf5 MD |
435 | goto __assign_##_item; \ |
436 | __end_field_##_item: | |
40652b65 | 437 | |
e763dbf5 MD |
438 | #undef __field_ext |
439 | #define __field_ext(_type, _item, _filter_type) __field(_type, _item) | |
40652b65 | 440 | |
e763dbf5 MD |
441 | #undef __array |
442 | #define __array(_type, _item, _length) \ | |
e763dbf5 MD |
443 | goto __assign_##_item; \ |
444 | __end_field_##_item: | |
40652b65 | 445 | |
e763dbf5 MD |
446 | #undef __dynamic_array |
447 | #define __dynamic_array(_type, _item, _length) \ | |
e763dbf5 MD |
448 | goto __assign_##_item##_1; \ |
449 | __end_field_##_item##_1: \ | |
e763dbf5 MD |
450 | goto __assign_##_item##_2; \ |
451 | __end_field_##_item##_2: | |
40652b65 | 452 | |
e763dbf5 MD |
453 | #undef __string |
454 | #define __string(_item, _src) \ | |
455 | goto __assign_##_item; \ | |
456 | __end_field_##_item: | |
457 | ||
458 | /* | |
459 | * Macros mapping tp_assign() to "=", tp_memcpy() to memcpy() and tp_strcpy() to | |
460 | * strcpy(). | |
461 | */ | |
462 | #undef tp_assign | |
463 | #define tp_assign(dest, src) \ | |
464 | __assign_##dest: \ | |
465 | { \ | |
3c4ffab9 MD |
466 | __typeof__(__typemap.dest) __tmp = (src); \ |
467 | lib_ring_buffer_align_ctx(&ctx, __alignof__(__tmp)); \ | |
468 | __chan->ops->event_write(&ctx, &__tmp, sizeof(__tmp)); \ | |
e763dbf5 MD |
469 | } \ |
470 | goto __end_field_##dest; | |
471 | ||
472 | #undef tp_memcpy | |
473 | #define tp_memcpy(dest, src, len) \ | |
474 | __assign_##dest: \ | |
3c4ffab9 | 475 | lib_ring_buffer_align_ctx(&ctx, __alignof__(__typemap.dest)); \ |
e763dbf5 MD |
476 | __chan->ops->event_write(&ctx, src, len); \ |
477 | goto __end_field_##dest; | |
478 | ||
479 | #undef tp_memcpy_dyn | |
480 | #define tp_memcpy_dyn(dest, src, len) \ | |
481 | __assign_##dest##_1: \ | |
482 | { \ | |
3c4ffab9 MD |
483 | u32 __tmpl = (len); \ |
484 | lib_ring_buffer_align_ctx(&ctx, __alignof__(u32)); \ | |
e763dbf5 MD |
485 | __chan->ops->event_write(&ctx, &__tmpl, sizeof(u32)); \ |
486 | } \ | |
487 | goto __end_field_##dest##_1; \ | |
488 | __assign_##dest##_2: \ | |
3c4ffab9 | 489 | lib_ring_buffer_align_ctx(&ctx, __alignof__(__typemap.dest)); \ |
e763dbf5 MD |
490 | __chan->ops->event_write(&ctx, src, len); \ |
491 | goto __end_field_##dest##_2; | |
492 | ||
493 | #undef tp_strcpy | |
494 | #define tp_strcpy(dest, src) \ | |
3c4ffab9 | 495 | tp_memcpy(dest, src, __get_dynamic_array_len(dest)) |
40652b65 | 496 | |
e763dbf5 MD |
497 | /* Named field types must be defined in lttng-types.h */ |
498 | ||
499 | #undef __get_str | |
500 | #define __get_str(field) field | |
501 | ||
502 | #undef __get_dynamic_array | |
503 | #define __get_dynamic_array(field) field | |
504 | ||
505 | /* Beware: this get len actually consumes the len value */ | |
506 | #undef __get_dynamic_array_len | |
507 | #define __get_dynamic_array_len(field) __dynamic_len[__dynamic_len_idx++] | |
508 | ||
509 | #undef TP_PROTO | |
510 | #define TP_PROTO(args...) args | |
511 | ||
512 | #undef TP_ARGS | |
513 | #define TP_ARGS(args...) args | |
514 | ||
515 | #undef TP_STRUCT__entry | |
516 | #define TP_STRUCT__entry(args...) args | |
517 | ||
518 | #undef TP_fast_assign | |
519 | #define TP_fast_assign(args...) args | |
520 | ||
521 | #undef DECLARE_EVENT_CLASS | |
522 | #define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ | |
523 | static void __event_probe__##_name(void *__data, _proto) \ | |
524 | { \ | |
525 | struct ltt_event *__event = __data; \ | |
526 | struct ltt_channel *__chan = __event->chan; \ | |
527 | struct lib_ring_buffer_ctx ctx; \ | |
528 | size_t __event_len, __event_align; \ | |
529 | size_t __dynamic_len_idx = 0; \ | |
530 | size_t __dynamic_len[ARRAY_SIZE(__event_fields___##_name)]; \ | |
3c4ffab9 | 531 | struct __event_typemap__##_name __typemap; \ |
e763dbf5 MD |
532 | int __ret; \ |
533 | \ | |
534 | if (0) \ | |
535 | (void) __dynamic_len_idx; /* don't warn if unused */ \ | |
52fc2e1f MD |
536 | if (!ACCESS_ONCE(__chan->session->active)) \ |
537 | return; \ | |
e763dbf5 MD |
538 | __event_len = __event_get_size__##_name(__dynamic_len, _args); \ |
539 | __event_align = __event_get_align__##_name(_args); \ | |
540 | lib_ring_buffer_ctx_init(&ctx, __chan->chan, NULL, __event_len, \ | |
541 | __event_align, -1); \ | |
542 | __ret = __chan->ops->event_reserve(&ctx); \ | |
543 | if (__ret < 0) \ | |
544 | return; \ | |
545 | /* Control code (field ordering) */ \ | |
546 | _tstruct \ | |
547 | __chan->ops->event_commit(&ctx); \ | |
548 | return; \ | |
549 | /* Copy code, steered by control code */ \ | |
550 | _assign \ | |
551 | } | |
552 | ||
553 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | |
554 | ||
3afe7aac MD |
555 | /* |
556 | * Stage 8 of the trace events. | |
557 | * | |
558 | * Register/unregister probes at module load/unload. | |
559 | */ | |
560 | ||
561 | #include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ | |
562 | ||
563 | #define TP_ID1(_token, _system) _token##_system | |
564 | #define TP_ID(_token, _system) TP_ID1(_token, _system) | |
565 | #define module_init_eval1(_token, _system) module_init(_token##_system) | |
566 | #define module_init_eval(_token, _system) module_init_eval1(_token, _system) | |
567 | #define module_exit_eval1(_token, _system) module_exit(_token##_system) | |
568 | #define module_exit_eval(_token, _system) module_exit_eval1(_token, _system) | |
569 | ||
3afe7aac MD |
570 | static int TP_ID(__lttng_events_init__, TRACE_SYSTEM)(void) |
571 | { | |
19c57fbf MD |
572 | int ret; |
573 | int i; | |
3afe7aac MD |
574 | |
575 | ret = TP_ID(__lttng_types_init__, TRACE_SYSTEM)(); | |
576 | if (ret) | |
577 | return ret; | |
19c57fbf MD |
578 | for (i = 0; i < ARRAY_SIZE(TP_ID(__event_desc___, TRACE_SYSTEM)); i++) { |
579 | const struct lttng_event_desc *event_desc; | |
580 | ||
581 | event_desc = &TP_ID(__event_desc___, TRACE_SYSTEM)[i]; | |
582 | ret = ltt_probe_register(event_desc->name, | |
583 | event_desc->probe_callback); | |
584 | if (ret) | |
585 | goto error; | |
586 | } | |
587 | return 0; | |
588 | ||
589 | error: | |
590 | for (i--; i >= 0; i--) { | |
591 | const struct lttng_event_desc *event_desc; | |
592 | ||
593 | event_desc = &TP_ID(__event_desc___, TRACE_SYSTEM)[i]; | |
594 | ltt_probe_unregister(event_desc->name); | |
595 | } | |
3afe7aac MD |
596 | return ret; |
597 | } | |
598 | ||
599 | module_init_eval(__lttng_events_init__, TRACE_SYSTEM); | |
600 | ||
3afe7aac MD |
601 | static void TP_ID(__lttng_events_exit__, TRACE_SYSTEM)(void) |
602 | { | |
19c57fbf MD |
603 | int i; |
604 | ||
605 | for (i = 0; i < ARRAY_SIZE(TP_ID(__event_desc___, TRACE_SYSTEM)); i++) { | |
606 | const struct lttng_event_desc *event_desc; | |
607 | ||
608 | event_desc = &TP_ID(__event_desc___, TRACE_SYSTEM)[i]; | |
609 | ltt_probe_unregister(event_desc->name); | |
610 | } | |
3afe7aac MD |
611 | TP_ID(__lttng_types_exit__, TRACE_SYSTEM)(); |
612 | } | |
613 | ||
614 | module_exit_eval(__lttng_events_exit__, TRACE_SYSTEM); | |
615 | ||
616 | #undef module_init_eval | |
617 | #undef module_exit_eval | |
618 | #undef TP_ID1 | |
619 | #undef TP_ID |