X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=probes%2Flttng-events.h;h=0c25b955392b8277c6811538d6ab719992798e0d;hb=d0dd2ecbe2f2e614e0469addd1bd962db3cf047b;hp=b4bac43c7dde81eb814cc43d63fe4ccf7ef1aaa7;hpb=1d12cebd26ab7c1ee4a23714ec71660c5352fbd4;p=lttng-modules.git diff --git a/probes/lttng-events.h b/probes/lttng-events.h index b4bac43c..0c25b955 100644 --- a/probes/lttng-events.h +++ b/probes/lttng-events.h @@ -1,4 +1,6 @@ #include +#include +#include /* * Macros mapping tp_assign() to "=", tp_memcpy() to memcpy() and tp_strcpy() to @@ -16,12 +18,24 @@ /* TODO */ #undef tp_strcpy -#define tp_strcpy(dest, src) __assign_str(dest, src) +#define tp_strcpy(dest, src) __assign_str(dest, src); + +struct lttng_event_field { + const char *name; + const struct lttng_type type; +}; + +struct lttng_event_desc { + const struct lttng_event_field *fields; + const char *name; + unsigned int nr_fields; +}; /* * Stage 1 of the trace events. * * Create event field type metadata section. + * Each event produce an array of fields. */ /* @@ -40,30 +54,53 @@ PARAMS(args), \ PARAMS(tstruct), \ PARAMS(assign), \ - PARAMS(print)); \ - DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args)); + PARAMS(print)) \ + DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args)) /* Named field types must be defined in lttng-types.h */ -/* TODO turn into a structure definition ? */ - #undef __field -#define __field(_type, _item) #_type " " #_item ";\n" +#define __field(_type, _item) \ + { .name = #_item, .type = { .atype = atype_integer, .name = #_type} }, #undef __field_ext -#define __field_ext(_type, _item, _filter_type) #_type " " #_item ";\n" +#define __field_ext(_type, _item, _filter_type) \ + { .name = #_item, .type = { .atype = atype_integer, .name = #_type} }, #undef __array -#define __array(_type, _item, _len) \ - "type { parent = array; length = " #_len "; elem_type = " #_type "; } " #_item";\n" +#define __array(_type, _item, _length) \ + { \ + .name = #_item, \ + .type = { \ + .atype = atype_array, \ + .name = NULL, \ + .u.array.elem_type = #_type, \ + .u.array.length = _length, \ + }, \ + }, #undef __dynamic_array -#define __dynamic_array(_type, _item, _len) \ - "type { parent = sequence; length_type = u32; elem_type = " #_type "; } " #_item ";\n" +#define __dynamic_array(_type, _item, _length) \ + { \ + .name = #_item, \ + .type = { \ + .atype = atype_sequence, \ + .name = NULL, \ + .u.sequence.elem_type = #_type, \ + .u.sequence.length_type = "u32", \ + }, \ + }, #undef __string #define __string(_item, _src) \ - "type { parent = string; encoding = UTF8; } " #_item ";\n" + { \ + .name = _item, \ + .type = { \ + .atype = atype_string, \ + .name = NULL, \ + .u.string.encoding = lttng_encode_UTF8, \ + }, \ + }, #undef TP_PROTO #define TP_PROTO(args...) @@ -82,7 +119,9 @@ #undef DECLARE_EVENT_CLASS #define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print) \ - tstruct + static const struct lttng_event_field __event_fields___##name[] = { \ + tstruct \ + }; #undef DEFINE_EVENT #define DEFINE_EVENT(template, name, proto, args) @@ -98,19 +137,288 @@ TRACE_EVENT(name, PARAMS(proto), PARAMS(args), \ PARAMS(tstruct), PARAMS(assign), PARAMS(print)) \ -#undef DEFINE_TRACE_EVENT_METADATA -#define DEFINE_TRACE_EVENT_METADATA \ - const char trace_event_metadata_##TRACE_SYSTEM[] +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +/* + * Stage 2 of the trace events. + * + * Create an array of events. + */ -//static DEFINE_TRACE_EVENT_METADATA = -static const char blah[] = +/* + * DECLARE_EVENT_CLASS can be used to add a generic function + * handlers for events. That is, if all events have the same + * parameters and just have distinct trace points. + * Each tracepoint can be defined with DEFINE_EVENT and that + * will map the DECLARE_EVENT_CLASS to the tracepoint. + * + * TRACE_EVENT is a one to one mapping between tracepoint and template. + */ +#undef TRACE_EVENT +#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ + DECLARE_EVENT_CLASS(name, \ + PARAMS(proto), \ + PARAMS(args), \ + PARAMS(tstruct), \ + PARAMS(assign), \ + PARAMS(print)) \ + DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args)) + +/* Named field types must be defined in lttng-types.h */ + +#undef __field +#define __field(_type, _item) + +#undef __field_ext +#define __field_ext(_type, _item, _filter_type) + +#undef __array +#define __array(_type, _item, _length) + +#undef __dynamic_array +#define __dynamic_array(_type, _item, _length) + +#undef __string +#define __string(_item, _src) + +#undef TP_PROTO +#define TP_PROTO(args...) + +#undef TP_ARGS +#define TP_ARGS(args...) + +#undef TP_STRUCT__entry +#define TP_STRUCT__entry(args...) + +#undef TP_fast_assign +#define TP_fast_assign(args...) + +#undef TP_printk +#define TP_printk(args...) + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(_name, proto, args, tstruct, assign, print) \ + { \ + .fields = __event_fields___##_name, \ + .name = #_name, \ + .nr_fields = ARRAY_SIZE(__event_fields___##_name), \ + }, + +#undef DEFINE_EVENT +#define DEFINE_EVENT(template, name, proto, args) + +#undef DEFINE_EVENT_PRINT +#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ + DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) + +/* Callbacks are meaningless to LTTng. */ +#undef TRACE_EVENT_FN +#define TRACE_EVENT_FN(name, proto, args, tstruct, \ + assign, print, reg, unreg) \ + TRACE_EVENT(name, PARAMS(proto), PARAMS(args), \ + PARAMS(tstruct), PARAMS(assign), PARAMS(print)) \ + +#define TP_ID1(_token, _system) _token##_system +#define TP_ID(_token, _system) TP_ID1(_token, _system) + +static const struct lttng_event_desc TP_ID(__event_desc___, TRACE_SYSTEM)[] = { #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) -; +}; + +#undef TP_ID1 +#undef TP_ID + +/* + * Stage 3 of the trace events. + * + * Create seq file metadata output. + */ + +/* + * DECLARE_EVENT_CLASS can be used to add a generic function + * handlers for events. That is, if all events have the same + * parameters and just have distinct trace points. + * Each tracepoint can be defined with DEFINE_EVENT and that + * will map the DECLARE_EVENT_CLASS to the tracepoint. + * + * TRACE_EVENT is a one to one mapping between tracepoint and template. + */ +#undef TRACE_EVENT +#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ + DECLARE_EVENT_CLASS(name, \ + PARAMS(proto), \ + PARAMS(args), \ + PARAMS(tstruct), \ + PARAMS(assign), \ + PARAMS(print)) \ + DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args)) + +/* Named field types must be defined in lttng-types.h */ + +#undef __field +#define __field(_type, _item) + +#undef __field_ext +#define __field_ext(_type, _item, _filter_type) + +#undef __array +#define __array(_type, _item, _length) + +#undef __dynamic_array +#define __dynamic_array(_type, _item, _length) + +#undef __string +#define __string(_item, _src) + +#undef TP_PROTO +#define TP_PROTO(args...) + +#undef TP_ARGS +#define TP_ARGS(args...) + +#undef TP_STRUCT__entry +#define TP_STRUCT__entry(args...) + +#undef TP_fast_assign +#define TP_fast_assign(args...) + +#undef TP_printk +#define TP_printk(args...) + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print) \ +static void () + +#undef DEFINE_EVENT +#define DEFINE_EVENT(template, name, proto, args) + +#undef DEFINE_EVENT_PRINT +#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ + DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) + +/* Callbacks are meaningless to LTTng. */ +#undef TRACE_EVENT_FN +#define TRACE_EVENT_FN(name, proto, args, tstruct, \ + assign, print, reg, unreg) \ + TRACE_EVENT(name, PARAMS(proto), PARAMS(args), \ + PARAMS(tstruct), PARAMS(assign), PARAMS(print)) \ + +#define TP_ID1(_token, _system) _token##_system +#define TP_ID(_token, _system) TP_ID1(_token, _system) +#define module_init_eval1(_token, _system) module_init(_token##_system) +#define module_init_eval(_token, _system) module_init_eval1(_token, _system) +#define module_exit_eval1(_token, _system) module_exit(_token##_system) +#define module_exit_eval(_token, _system) module_exit_eval1(_token, _system) + +static void *TP_ID(__lttng_seq_start__, TRACE_SYSTEM)(struct seq_file *m, + loff_t *pos) +{ + const struct lttng_event_desc *desc = &TP_ID(__event_desc___, TRACE_SYSTEM)[*pos]; + + if (desc > &TP_ID(__event_desc___, TRACE_SYSTEM)[ARRAY_SIZE(TP_ID(__event_desc___, TRACE_SYSTEM)) - 1]) + return NULL; + return (void *) desc; +} + +static void *TP_ID(__lttng_seq_next__, TRACE_SYSTEM)(struct seq_file *m, + void *p, loff_t *ppos) +{ + const struct lttng_event_desc *desc = &TP_ID(__event_desc___, TRACE_SYSTEM)[++(*ppos)]; + + if (desc > &TP_ID(__event_desc___, TRACE_SYSTEM)[ARRAY_SIZE(TP_ID(__event_desc___, TRACE_SYSTEM)) - 1]) + return NULL; + return (void *) desc; +} + +static void TP_ID(__lttng_seq_stop__, TRACE_SYSTEM)(struct seq_file *m, + void *p) +{ +} + +static int TP_ID(__lttng_seq_show__, TRACE_SYSTEM)(struct seq_file *m, + void *p) +{ + const struct lttng_event_desc *desc = p; + int i; + + seq_printf(m, "event {\n" + "\tname = %s;\n" + "\tid = UNKNOWN;\n" + "\tstream = UNKNOWN;\n" + "\tfields = {\n", + desc->name); + for (i = 0; i < desc->nr_fields; i++) { + if (desc->fields[i].type.name) /* Named type */ + seq_printf(m, "\t\t%s", + desc->fields[i].type.name); + else /* Nameless type */ + lttng_print_event_type(m, 2, &desc->fields[i].type); + seq_printf(m, " %s;\n", desc->fields[i].name); + } + seq_printf(m, "\t};\n"); + seq_printf(m, "};\n"); + return 0; +} + +static const +struct seq_operations TP_ID(__lttng_types_seq_ops__, TRACE_SYSTEM) = { + .start = TP_ID(__lttng_seq_start__, TRACE_SYSTEM), + .next = TP_ID(__lttng_seq_next__, TRACE_SYSTEM), + .stop = TP_ID(__lttng_seq_stop__, TRACE_SYSTEM), + .show = TP_ID(__lttng_seq_show__, TRACE_SYSTEM), +}; + +static int +TP_ID(__lttng_types_open__, TRACE_SYSTEM)(struct inode *inode, struct file *file) +{ + return seq_open(file, &TP_ID(__lttng_types_seq_ops__, TRACE_SYSTEM)); +} + +static const struct file_operations TP_ID(__lttng_types_fops__, TRACE_SYSTEM) = { + .open = TP_ID(__lttng_types_open__, TRACE_SYSTEM), + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_private, +}; + +static struct dentry *TP_ID(__lttng_types_dentry__, TRACE_SYSTEM); + +static int TP_ID(__lttng_types_init__, TRACE_SYSTEM)(void) +{ + int ret = 0; + + TP_ID(__lttng_types_dentry__, TRACE_SYSTEM) = + debugfs_create_file("lttng-events-" __stringify(TRACE_SYSTEM), S_IWUSR, + NULL, NULL, &TP_ID(__lttng_types_fops__, TRACE_SYSTEM)); + if (IS_ERR(TP_ID(__lttng_types_dentry__, TRACE_SYSTEM)) + || !TP_ID(__lttng_types_dentry__, TRACE_SYSTEM)) { + printk(KERN_ERR "Error creating LTTng type export file\n"); + ret = -ENOMEM; + goto error; + } +error: + return ret; +} + +module_init_eval(__lttng_types_init__, TRACE_SYSTEM); + +static void TP_ID(__lttng_types_exit__, TRACE_SYSTEM)(void) +{ + debugfs_remove(TP_ID(__lttng_types_dentry__, TRACE_SYSTEM)); +} + +module_exit_eval(__lttng_types_exit__, TRACE_SYSTEM); + +#undef module_init_eval +#undef module_exit_eval +#undef TP_ID1 +#undef TP_ID + #if 0 /* - * Stage 2 of the trace events. + * Stage 3 of the trace events. * * Create static inline function that calculates event size. */ @@ -120,7 +428,7 @@ static const char blah[] = #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) /* - * Stage 3 of the trace events. + * Stage 4 of the trace events. * * Create the probe function : call even size calculation and write event data * into the buffer.