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

Reply via email to