Introduce the new macro TRACEPOINT_ENUM to globally define ctf enum metadata that can be used in tracepoints using field_enum as entry and the tp_assign assignation macro. In the TRACE_EVENT_ENUM macro, values and ranges now have to be expressed without commas because it is easier to add commas where necessary than to remove them when a loop through the arguments is necessary.
Signed-off-by: Geneviève Bastien <[email protected]> --- lttng-events.c | 61 +++++++++++++++- lttng-events.h | 4 ++ probes/lttng-events-reset.h | 6 ++ probes/lttng-events.h | 169 +++++++++++++++++++++++++++++++++++++++++++- probes/lttng-type-list.h | 12 ++-- probes/lttng-types.h | 61 +++++++++++++++- 6 files changed, 302 insertions(+), 11 deletions(-) diff --git a/lttng-events.c b/lttng-events.c index fa92222..56ff6a6 100644 --- a/lttng-events.c +++ b/lttng-events.c @@ -588,7 +588,8 @@ int _lttng_field_statedump(struct lttng_session *session, break; case atype_enum: ret = lttng_metadata_printf(session, - " %s _%s;\n", + " enum enum_%s_%s _%s;\n", + field->type.u.basic.enumeration.provider, field->type.u.basic.enumeration.name, field->name); break; @@ -706,6 +707,16 @@ int _lttng_is_type_metadata_dumped(struct lttng_session *session, dumped = dumped->next; } break; + case mtype_enum: + for (i = 0; i < session->dumped_metadata[metadata->mtype].nr_metadata; i++) { + if (metadata->m.ctf_enum == + dumped->dumped_ptr.ctf_enum) { + is_dumped = 1; + break; + } + dumped = dumped->next; + } + break; default: WARN_ON_ONCE(1); return -EINVAL; @@ -728,6 +739,9 @@ static int _lttng_type_metadata_mark_dumped(struct lttng_session *session, case mtype_struct: dumped->dumped_ptr.struct_desc = metadata->m.ctf_st.struct_desc; break; + case mtype_enum: + dumped->dumped_ptr.ctf_enum = metadata->m.ctf_enum; + break; default: WARN_ON_ONCE(1); return -EINVAL; @@ -779,6 +793,51 @@ int _lttng_type_metadata_do_statedump(struct lttng_session *session, if (ret) return ret; break; + case mtype_enum: + ret = lttng_metadata_printf(session, + "enum %s : integer { size = %u; align = %u; signed = %u; base = %u;%s } {\n", + meta->m.ctf_enum->name, + meta->m.ctf_enum->container_type.u.basic.integer.size, + meta->m.ctf_enum->container_type.u.basic.integer.alignment, + meta->m.ctf_enum->container_type.u.basic.integer.signedness, + meta->m.ctf_enum->container_type.u.basic.integer.base, +#ifdef __BIG_ENDIAN + meta->m.ctf_enum->container_type.u.basic.integer.reverse_byte_order ? " byte_order = le;" : "" +#else + meta->m.ctf_enum->container_type.u.basic.integer.reverse_byte_order ? " byte_order = be;" : "" +#endif + ); + if (ret) + return ret; + + /* Print enumerations */ + for (i = 0; i < meta->m.ctf_enum->len; i++) { + const struct lttng_enum_entry *entry; + + entry = &meta->m.ctf_enum->entries[i]; + if (entry->start == entry->end) { + ret = lttng_metadata_printf(session, + " _%s = %d,\n", + entry->string, + entry->start + ); + } else { + ret = lttng_metadata_printf(session, + " _%s = %d ... %d,\n", + entry->string, + entry->start, + entry->end + ); + } + + if (ret) + return ret; + } + ret = lttng_metadata_printf(session, + "};\n\n"); + if (ret) + return ret; + break; default: WARN_ON_ONCE(1); return -EINVAL; diff --git a/lttng-events.h b/lttng-events.h index fa9aba4..f4b5c6e 100644 --- a/lttng-events.h +++ b/lttng-events.h @@ -54,6 +54,7 @@ enum abstract_types { /* Metadata types */ enum metadata_types { mtype_struct, + mtype_enum, NR_METADATA_TYPES, }; @@ -96,6 +97,7 @@ struct lttng_integer_type { union _lttng_basic_type { struct lttng_integer_type integer; struct { + const char *provider; const char *name; } enumeration; struct { @@ -186,12 +188,14 @@ struct lttng_metadata { const struct lttng_metadata *type_metadata; unsigned int nr_metadata; } ctf_st; + const struct lttng_enum *ctf_enum; } m; }; struct lttng_metadata_dumped_data { union { const struct lttng_struct_desc *struct_desc; + const struct lttng_enum *ctf_enum; } dumped_ptr; struct lttng_metadata_dumped_data *next; }; diff --git a/probes/lttng-events-reset.h b/probes/lttng-events-reset.h index 17a8419..94046b2 100644 --- a/probes/lttng-events-reset.h +++ b/probes/lttng-events-reset.h @@ -31,6 +31,9 @@ #undef __field_full #define __field_full(_type, _item, _order, _base) +#undef __field_enum +#define __field_enum(_provider, _type, _item) + #undef __array_enc_ext #define __array_enc_ext(_type, _item, _length, _order, _base, _encoding) @@ -114,3 +117,6 @@ #undef TRACEPOINT_STRUCT_RAW #define TRACEPOINT_STRUCT_RAW(_provider, _name, _proto, _args, _fields) + +#undef TRACEPOINT_ENUM +#define TRACEPOINT_ENUM(_provider, _name, _type, _enum) diff --git a/probes/lttng-events.h b/probes/lttng-events.h index 5976f61..15d07d8 100644 --- a/probes/lttng-events.h +++ b/probes/lttng-events.h @@ -157,6 +157,92 @@ void trace_##_name(void *__data); #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) /* + * Stage 1.7 of the trace events. + * + * Create enum for tracepoint enum strings + */ + +#include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ + +/* Named field types must be defined in lttng-types.h */ + +#undef TP_ENUM +#define TP_ENUM(args...) args /* Only one used in this phase */ + +#define STAGE_EXPORT_ENUM_ENUM +#include "lttng-types.h" + +#undef TRACEPOINT_ENUM +#define TRACEPOINT_ENUM(_provider, _name, _type, _enum) \ + TRACE_EVENT_ENUM(enum_##_provider##_##_name, _enum) + +#undef STAGE_EXPORT_ENUM_ENUM + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +/* + * Stage 1.8 of the trace events. + * + * Create function to return C enum value from a long value + */ + +#include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ + +/* Named field types must be defined in lttng-types.h */ + +#undef TP_ENUM +#define TP_ENUM(...) __VA_ARGS__ /* Only one used in this phase */ + +#undef TP_TYPE +#define TP_TYPE(_type) _type + +#define STAGE_EXPORT_ENUM_FCT +#include "lttng-types.h" + +#undef TRACEPOINT_ENUM +#define TRACEPOINT_ENUM(_provider, _name, _type, _enum) \ +static inline enum __trace_enum__enum_##_provider##_##_name __enum_get_value__##_provider##_##_name(_type value)\ +{ \ + enum __trace_enum__enum_##_provider##_##_name ret; \ + ret = NR_ENUM_DATA_enum_##_provider##_##_name; \ + _enum \ +end: \ + return ret; \ +} + +#undef STAGE_EXPORT_ENUM_FCT + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +/* + * Stage 1.9 of the trace events. + * + * Unfold enum entries + */ + +#include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ + +/* Named field types must be defined in lttng-types.h */ + +#undef TP_ENUM +#define TP_ENUM(args...) args /* Only one used in this phase */ + +#undef TP_TYPE +#define TP_TYPE(_type) + +#define STAGE_EXPORT_ENUMS +#include "lttng-types.h" + +#undef TRACEPOINT_ENUM +#define TRACEPOINT_ENUM(_provider, _name, _type, _enum) \ + TRACE_EVENT_ENUM(enum_##_provider##_##_name, _enum) + +#undef STAGE_EXPORT_ENUMS + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + + +/* * Stage 2 of the trace events. * * Create event field type metadata section. @@ -275,6 +361,18 @@ void trace_##_name(void *__data); }, \ }, +#undef __field_enum +#define __field_enum(_provider, _type, _data_type, _item) \ + { \ + .name = #_item, \ + .type = \ + { \ + .atype = atype_enum, \ + .u.basic.enumeration.provider = #_provider, \ + .u.basic.enumeration.name = #_type, \ + }, \ + }, + #undef TP_STRUCT__entry #define TP_STRUCT__entry(args...) args /* Only one used in this phase */ @@ -340,6 +438,19 @@ static struct lttng_struct_desc __struct_desc___##_provider##_##_name = {\ .owner = THIS_MODULE, \ }; +#undef TP_TYPE +#define TP_TYPE(_type) _type + +#define STAGE_EXPORT_TYPES +#include "lttng-types.h" + +#undef TRACEPOINT_ENUM +#define TRACEPOINT_ENUM(_provider, _name, _type, _enum) \ +static const struct lttng_enum __enum_field__##_provider##_##_name[] = {\ + TRACE_EVENT_TYPE___enum(enum_##_provider##_##_name, _type)}; + +#undef STAGE_EXPORT_TYPES + #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) /* @@ -361,6 +472,12 @@ static struct lttng_struct_desc __struct_desc___##_provider##_##_name = {\ .m.ctf_st.nr_metadata = ARRAY_SIZE(__type_metadata_for__##_provider##_##_type),\ }, +#undef __field_enum +#define __field_enum(_provider, _type, _data_type, _item) \ + { \ + .mtype = mtype_enum, \ + .m.ctf_enum = &__enum_field__##_provider##_##_type[0], \ + }, #undef TP_STRUCT__entry #define TP_STRUCT__entry(args...) args /* Only one used in this phase */ @@ -374,8 +491,6 @@ static const struct lttng_metadata __type_metadata_for__##_provider##_##_name[] _fields \ }; - - #undef DECLARE_EVENT_CLASS_NOARGS #define DECLARE_EVENT_CLASS_NOARGS(_name, _tstruct, _assign, _print) \ static const struct lttng_metadata __type_metadata_for__##_name[] = { \ @@ -516,6 +631,10 @@ static __used struct lttng_probe_desc TP_ID(__probe_desc___, TRACE_SYSTEM) = { #define __struct(_provider, _type, _item, _params) \ __event_len += __struct_get_size__##_provider##_##_type(_params);\ +#undef __field_enum +#define __field_enum(_provider, _type, _data_type, _item) \ + __event_len += __enum_get_size__##_provider##_##_type(); + #undef TP_PROTO #define TP_PROTO(args...) args @@ -525,6 +644,9 @@ static __used struct lttng_probe_desc TP_ID(__probe_desc___, TRACE_SYSTEM) = { #undef TP_FIELDS #define TP_FIELDS(args...) args +#undef TP_TYPE +#define TP_TYPE(_type) _type + #undef TRACEPOINT_STRUCT_RAW #define TRACEPOINT_STRUCT_RAW(_provider, _name, _proto, _args, _fields) \ static inline size_t __struct_get_size__##_provider##_##_name(_proto) \ @@ -535,6 +657,13 @@ static inline size_t __struct_get_size__##_provider##_##_name(_proto) \ return __event_len; \ } +#undef TRACEPOINT_ENUM +#define TRACEPOINT_ENUM(_provider, _name, _type, _enum) \ +static inline size_t __enum_get_size__##_provider##_##_name(void) \ +{ \ + return sizeof(_type); \ +} + #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) /* @@ -574,6 +703,9 @@ static inline size_t __struct_get_size__##_provider##_##_name(_proto) \ #undef TRACEPOINT_STRUCT_RAW #define TRACEPOINT_STRUCT_RAW(_provider, _name, _proto, _args, _fields) +#undef TRACEPOINT_ENUM +#define TRACEPOINT_ENUM(_provider, _name, _type, _enum) + #undef DECLARE_EVENT_CLASS #define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ static inline size_t __event_get_size__##_name(size_t *__dynamic_len, _proto) \ @@ -623,6 +755,11 @@ static inline size_t __event_get_size__##_name(size_t *__dynamic_len, _proto) \ __event_align = max_t(size_t, __event_align, \ __instruct_get_align__##_provider##_##_type(_params)); +#undef __field_enum +#define __field_enum(_provider, _type, _data_type, _item) \ + __event_align = max_t(size_t, __event_align, \ + __enum_get_align__##_provider##_##_type()); + #undef TP_PROTO #define TP_PROTO(args...) args @@ -641,6 +778,9 @@ static inline size_t __event_get_size__##_name(size_t *__dynamic_len, _proto) \ * the compiler will throw an error here because the __instruct... function * is not defined when first called in __struct... */ +#undef TP_TYPE +#define TP_TYPE(type) type + #undef TRACEPOINT_STRUCT_RAW #define TRACEPOINT_STRUCT_RAW(_provider, _name, _proto, _args, _fields) \ static inline size_t __struct_get_align__##_provider##_##_name(_proto) \ @@ -654,6 +794,13 @@ static inline size_t __instruct_get_align__##_provider##_##_name(_proto)\ return __struct_get_align__##_provider##_##_name(_args); \ } +#undef TRACEPOINT_ENUM +#define TRACEPOINT_ENUM(_provider, _name, _type, _enum) \ +static inline size_t __enum_get_align__##_provider##_##_name(void) \ +{ \ + return lttng_alignof(_type); \ +} + #undef DECLARE_EVENT_CLASS #define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ static inline size_t __event_get_align__##_name(_proto) \ @@ -697,6 +844,10 @@ static inline size_t __event_get_align__##_name(_proto) \ #undef __struct #define __struct(_provider, _type, _item, _params) char _item; +#undef __field_enum +#define __field_enum(_provider, _type, _data_type, _item) \ + _data_type _item; + #undef TP_STRUCT__entry #define TP_STRUCT__entry(args...) args @@ -706,6 +857,15 @@ struct __event_typemap__##_name { \ _tstruct \ }; +#undef TP_TYPE +#define TP_TYPE(type) type + +#undef TRACEPOINT_ENUM +#define TRACEPOINT_ENUM(_provider, _name, _type, _enum) \ +struct __enum_struct__##_provider##_##_name { \ + _type item; \ +}; + #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) /* @@ -752,6 +912,11 @@ __end_field_##_item: goto __assign_##_item; \ __end_field_##_item: +#undef __field_enum +#define __field_enum(_provider, _type, _data_type, _item) \ + goto __assign_##_item; \ +__end_field_##_item: + /* * Macros mapping tp_assign() to "=", tp_memcpy() to memcpy() and tp_strcpy() to * strcpy(). diff --git a/probes/lttng-type-list.h b/probes/lttng-type-list.h index 564a13f..ef8cefa 100644 --- a/probes/lttng-type-list.h +++ b/probes/lttng-type-list.h @@ -22,12 +22,12 @@ /* Enumerations */ TRACE_EVENT_ENUM(hrtimer_mode, - V(HRTIMER_MODE_ABS), - V(HRTIMER_MODE_REL), - V(HRTIMER_MODE_PINNED), - V(HRTIMER_MODE_ABS_PINNED), - V(HRTIMER_MODE_REL_PINNED), - R(HRTIMER_MODE_UNDEFINED, 0x04, 0x20), /* Example (to remove) */ + V(HRTIMER_MODE_ABS) + V(HRTIMER_MODE_REL) + V(HRTIMER_MODE_PINNED) + V(HRTIMER_MODE_ABS_PINNED) + V(HRTIMER_MODE_REL_PINNED) + R(HRTIMER_MODE_UNDEFINED, 0x04, 0x20) /* Example (to remove) */ ) TRACE_EVENT_TYPE(hrtimer_mode, enum, unsigned char) diff --git a/probes/lttng-types.h b/probes/lttng-types.h index 9376066..057bb91 100644 --- a/probes/lttng-types.h +++ b/probes/lttng-types.h @@ -50,12 +50,12 @@ /* Enumeration entry (single value) */ #undef V -#define V(_string) { _string, _string, #_string} +#define V(_string) { _string, _string, #_string}, /* Enumeration entry (range) */ #undef R #define R(_string, _range_start, _range_end) \ - { _range_start, _range_end, #_string } + { _range_start, _range_end, #_string }, #endif /* STAGE_EXPORT_ENUMS */ @@ -82,3 +82,60 @@ #define TRACE_EVENT_ENUM(_name, _entries...) #endif /* STAGE_EXPORT_TYPES */ + +/* Creates a C enum with the names of the ctf enumeration */ + +#ifdef STAGE_EXPORT_ENUM_ENUM + +#undef TRACE_EVENT_TYPE +#define TRACE_EVENT_TYPE(_name, _abstract_type, args...) + +#undef TRACE_EVENT_ENUM +#define TRACE_EVENT_ENUM(_name, _entries...) \ +enum __trace_enum__##_name { \ + _entries \ + NR_ENUM_DATA_##_name, \ +}; + +/* Enumeration entry (single value) */ +#undef V +#define V(_string) enum_##_string, + +/* Enumeration entry (range) */ +#undef R +#define R(_string, _range_start, _range_end) \ + enum_##_string, + +#endif /* STAGE_EXPORT_ENUM_ENUM */ + +/* + * Creates a function that will return the C enum value given a long value + * (useful for variants) + */ + +#ifdef STAGE_EXPORT_ENUM_FCT + +#undef TRACE_EVENT_TYPE +#define TRACE_EVENT_TYPE(_name, _abstract_type, args...) + +#undef TRACE_EVENT_ENUM +#define TRACE_EVENT_ENUM(_name, _entries...) + +/* Enumeration entry (single value) */ +#undef V +#define V(_string) \ + if (value == _string) { \ + ret = enum_##_string; \ + goto end; \ + } + + +/* Enumeration entry (range) */ +#undef R +#define R(_string, _range_start, _range_end) \ + if ((value >= _range_start) && (value <= _range_end)) { \ + ret = enum_##_string; \ + goto end; \ + } + +#endif /* STAGE_EXPORT_ENUM_FCT */ -- 1.8.2.1 _______________________________________________ lttng-dev mailing list [email protected] http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
