Implement enumeration type
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 18 Mar 2016 20:01:54 +0000 (16:01 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 2 May 2016 16:38:13 +0000 (12:38 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
lttng-events.c
lttng-events.h
lttng-syscalls.c
probes/lttng-events-nowrite.h
probes/lttng-events-reset.h
probes/lttng-events-write.h
probes/lttng-tracepoint-event-impl.h
probes/lttng-tracepoint-event.h

index 0c72015fd1a56edc79f4ef9e4106c8aa3745c48c..5307b722b237991935d75a93f61d04caac36e06b 100644 (file)
@@ -1863,6 +1863,110 @@ int _lttng_sequence_compound_statedump(struct lttng_session *session,
        return ret;
 }
 
+/*
+ * Must be called with sessions_mutex held.
+ */
+static
+int _lttng_enum_statedump(struct lttng_session *session,
+               const struct lttng_event_field *field,
+               size_t nesting)
+{
+       const struct lttng_enum_desc *enum_desc;
+       const struct lttng_integer_type *container_type;
+       int ret;
+       unsigned int i, nr_entries;
+
+       enum_desc = field->type.u.basic.enumeration.desc;
+       container_type = &field->type.u.basic.enumeration.container_type;
+       nr_entries = enum_desc->nr_entries;
+
+       ret = print_tabs(session, nesting);
+       if (ret)
+               goto end;
+       ret = lttng_metadata_printf(session,
+               "enum : integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u; } {\n",
+               container_type->size,
+               container_type->alignment,
+               container_type->signedness,
+               (container_type->encoding == lttng_encode_none)
+                       ? "none"
+                       : (container_type->encoding == lttng_encode_UTF8)
+                               ? "UTF8"
+                               : "ASCII",
+               container_type->base);
+       if (ret)
+               goto end;
+       /* Dump all entries */
+       for (i = 0; i < nr_entries; i++) {
+               const struct lttng_enum_entry *entry = &enum_desc->entries[i];
+               int j, len;
+
+               ret = print_tabs(session, nesting + 1);
+               if (ret)
+                       goto end;
+               ret = lttng_metadata_printf(session,
+                               "\"");
+               if (ret)
+                       goto end;
+               len = strlen(entry->string);
+               /* Escape the character '"' */
+               for (j = 0; j < len; j++) {
+                       char c = entry->string[j];
+
+                       switch (c) {
+                       case '"':
+                               ret = lttng_metadata_printf(session,
+                                               "\\\"");
+                               break;
+                       case '\\':
+                               ret = lttng_metadata_printf(session,
+                                               "\\\\");
+                               break;
+                       default:
+                               ret = lttng_metadata_printf(session,
+                                               "%c", c);
+                               break;
+                       }
+                       if (ret)
+                               goto end;
+               }
+               ret = lttng_metadata_printf(session,
+                               "\" = ");
+               if (ret)
+                       goto end;
+               if (entry->start.signedness)
+                       ret = lttng_metadata_printf(session,
+                               "%lld", (long long) entry->start.value);
+               else
+                       ret = lttng_metadata_printf(session,
+                               "%llu", entry->start.value);
+               if (ret)
+                       goto end;
+               if (entry->start.signedness == entry->end.signedness &&
+                               entry->start.value == entry->end.value) {
+                       ret = lttng_metadata_printf(session,
+                               ",\n");
+               } else {
+                       if (entry->end.signedness) {
+                               ret = lttng_metadata_printf(session,
+                                       " ... %lld,\n", (long long) entry->end.value);
+                       } else {
+                               ret = lttng_metadata_printf(session,
+                                       " ... %llu,\n", entry->end.value);
+                       }
+               }
+               if (ret)
+                       goto end;
+       }
+       ret = print_tabs(session, nesting);
+       if (ret)
+               goto end;
+       ret = lttng_metadata_printf(session, "} _%s;\n",
+                       field->name);
+end:
+       return ret;
+}
+
 /*
  * Must be called with sessions_mutex held.
  */
@@ -1897,13 +2001,7 @@ int _lttng_field_statedump(struct lttng_session *session,
                        field->name);
                break;
        case atype_enum:
-               ret = print_tabs(session, nesting);
-               if (ret)
-                       return ret;
-               ret = lttng_metadata_printf(session,
-                       "%s _%s;\n",
-                       field->type.u.basic.enumeration.name,
-                       field->name);
+               ret = _lttng_enum_statedump(session, field, nesting);
                break;
        case atype_array:
        {
index 5d0ef4dc72b307881e57c730be87e385929b6164..9c8f03b8d4fc27849cf31c557e44de78da350fd8 100644 (file)
@@ -69,8 +69,13 @@ enum channel_type {
        METADATA_CHANNEL,
 };
 
+struct lttng_enum_value {
+       unsigned long long value;
+       unsigned int signedness:1;
+};
+
 struct lttng_enum_entry {
-       unsigned long long start, end;  /* start and end are inclusive */
+       struct lttng_enum_value start, end;     /* start and end are inclusive */
        const char *string;
 };
 
@@ -101,7 +106,8 @@ struct lttng_integer_type {
 union _lttng_basic_type {
        struct lttng_integer_type integer;
        struct {
-               const char *name;
+               const struct lttng_enum_desc *desc;     /* Enumeration mapping */
+               struct lttng_integer_type container_type;
        } enumeration;
        struct {
                enum lttng_string_encodings encoding;
@@ -149,11 +155,10 @@ struct lttng_type {
        } u;
 };
 
-struct lttng_enum {
+struct lttng_enum_desc {
        const char *name;
-       struct lttng_type container_type;
        const struct lttng_enum_entry *entries;
-       unsigned int len;
+       unsigned int nr_entries;
 };
 
 /* Event field description */
index a3149d0d01caa4260bc2e0442907207f4f4aac4b..080355f4e00408922e609df45948c044dc1116a1 100644 (file)
@@ -132,6 +132,9 @@ struct user_msghdr;
        LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(syscall_entry_##_name, PARAMS(_fields))
 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name)            \
        LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(syscall_entry_##_template, syscall_entry_##_name)
+/* Enumerations only defined at first inclusion. */
+#define SC_LTTNG_TRACEPOINT_ENUM(_name, _values) \
+       LTTNG_TRACEPOINT_ENUM(_name, PARAMS(_values))
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM syscall_entry_integers
 #define TRACE_INCLUDE_FILE syscalls_integers
@@ -143,6 +146,7 @@ struct user_msghdr;
 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
 #undef TRACE_INCLUDE_FILE
 #undef TRACE_SYSTEM
+#undef SC_LTTNG_TRACEPOINT_ENUM
 #undef SC_LTTNG_TRACEPOINT_EVENT_CODE
 #undef SC_LTTNG_TRACEPOINT_EVENT
 #undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
@@ -164,6 +168,8 @@ struct user_msghdr;
 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name)            \
        LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(compat_syscall_entry_##_template, \
                compat_syscall_entry_##_name)
+/* Enumerations only defined at inital inclusion (not here). */
+#define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
 #define TRACE_SYSTEM compat_syscall_entry_integers
 #define TRACE_INCLUDE_FILE compat_syscalls_integers
 #include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
@@ -174,6 +180,7 @@ struct user_msghdr;
 #include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
 #undef TRACE_INCLUDE_FILE
 #undef TRACE_SYSTEM
+#undef SC_LTTNG_TRACEPOINT_ENUM
 #undef SC_LTTNG_TRACEPOINT_EVENT_CODE
 #undef SC_LTTNG_TRACEPOINT_EVENT
 #undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
@@ -208,6 +215,8 @@ struct user_msghdr;
 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name)            \
        LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(syscall_exit_##_template,        \
                syscall_exit_##_name)
+/* Enumerations only defined at inital inclusion (not here). */
+#define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
 #define TRACE_SYSTEM syscall_exit_integers
 #define TRACE_INCLUDE_FILE syscalls_integers
 #include <instrumentation/syscalls/headers/syscalls_integers.h>
@@ -218,6 +227,7 @@ struct user_msghdr;
 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
 #undef TRACE_INCLUDE_FILE
 #undef TRACE_SYSTEM
+#undef SC_LTTNG_TRACEPOINT_ENUM
 #undef SC_LTTNG_TRACEPOINT_EVENT_CODE
 #undef SC_LTTNG_TRACEPOINT_EVENT
 #undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
@@ -240,6 +250,8 @@ struct user_msghdr;
 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name)            \
        LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(compat_syscall_exit_##_template, \
                compat_syscall_exit_##_name)
+/* Enumerations only defined at inital inclusion (not here). */
+#define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
 #define TRACE_SYSTEM compat_syscall_exit_integers
 #define TRACE_INCLUDE_FILE compat_syscalls_integers
 #include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
@@ -250,6 +262,7 @@ struct user_msghdr;
 #include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
 #undef TRACE_INCLUDE_FILE
 #undef TRACE_SYSTEM
+#undef SC_LTTNG_TRACEPOINT_ENUM
 #undef SC_LTTNG_TRACEPOINT_EVENT_CODE
 #undef SC_LTTNG_TRACEPOINT_EVENT
 #undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
index 20034f385b449c06f0d72c002c4f42da59dbcdef..ff30759dd1e33802a744c8e1635836ab950c2a90 100644 (file)
 #define ctf_string_nowrite(_item, _user_src)                   \
        _ctf_string(_item, _user_src, 0, 1)
 
+#undef ctf_enum_nowrite
+#define ctf_enum_nowrite(_name, _type, _item, _src)            \
+       _ctf_enum(_name, _type, _item, _src, 0, 1)
+
 /* user src */
 #undef ctf_user_integer_nowrite
 #define ctf_user_integer_nowrite(_type, _item, _user_src)      \
 #undef ctf_user_string_nowrite
 #define ctf_user_string_nowrite(_item, _user_src)              \
        _ctf_string(_item, _user_src, 1, 1)
+
+#undef ctf_user_enum_nowrite
+#define ctf_user_enum_nowrite(_name, _type, _item, _src)       \
+       _ctf_enum(_name, _type, _item, _src, 1, 1)
index 3b39233ca69b82a39f9eb4bb565159a09fdab890..a3bef9e2a5bbb2374f1261142c731531b48e5795 100644 (file)
@@ -32,6 +32,9 @@
 #undef LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP_NOARGS
 #define LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP_NOARGS(_template, _name, _map)
 
+#undef LTTNG_TRACEPOINT_ENUM
+#define LTTNG_TRACEPOINT_ENUM(_name, _values)
+
 #undef TP_PROTO
 #define TP_PROTO(args...)
 
@@ -84,6 +87,9 @@
 #undef _ctf_string
 #define _ctf_string(_item, _src, _user, _nowrite)
 
+#undef _ctf_enum
+#define _ctf_enum(_name, _type, _item, _src, _nowrite)
+
 /* "write" */
 #undef ctf_integer
 #define ctf_integer(_type, _item, _src)
 #undef ctf_string
 #define ctf_string(_item, _src)
 
+#undef ctf_enum
+#define ctf_enum(_name, _type, _item, _src)
+
 #undef ctf_custom_field
 #define ctf_custom_field(_type, _item, _code)
 
 #undef ctf_string_nowrite
 #define ctf_string_nowrite(_item, _src)
 
+#undef ctf_enum_nowrite
+#define ctf_enum_nowrite(_name, _type, _item, _src)
+
 /* "user" - "write" */
 #undef ctf_user_integer
 #define ctf_user_integer(_type, _item, _user_src)
 #undef ctf_user_string
 #define ctf_user_string(_item, _user_src)
 
+#undef ctf_user_enum
+#define ctf_user_enum(_name, _type, _item, _src)
+
 /* "user" - "nowrite" */
 #undef ctf_user_integer_nowrite
 #define ctf_user_integer_nowrite(_type, _item, _user_src)
 
 #undef ctf_user_string_nowrite
 #define ctf_user_string_nowrite(_item, _user_src)
+
+#undef ctf_user_enum_nowrite
+#define ctf_user_enum_nowrite(_name, _type, _item, _src)
index a1f252373394a23bfde07ee286ae29523ed4175b..5db66eb70b3c04cb43504af9e421115927e01279 100644 (file)
 #define ctf_string(_item, _src)                                        \
        _ctf_string(_item, _src, 0, 0)
 
+#undef ctf_enum
+#define ctf_enum(_name, _type, _item, _src)                    \
+       _ctf_enum(_name, _type, _item, _src, 0, 0)
+
 /* user src */
 #undef ctf_user_integer
 #define ctf_user_integer(_type, _item, _src)                           \
 #define ctf_user_string(_item, _src)                                   \
        _ctf_string(_item, _src, 1, 0)
 
+#undef ctf_user_enum
+#define ctf_user_enum(_name, _type, _item, _src)                       \
+       _ctf_enum(_name, _type, _item, _src, 1, 0)
+
 /* types */
 #undef ctf_integer_type
 #define ctf_integer_type(_type, _src)                                  \
 #define ctf_string_type(_src)                                          \
        ctf_string(unused, _src)
 
+#undef ctf_enum_type
+#define ctf_enum_type(_name, _type, _src)                              \
+       ctf_enum(_name, _type, unused, _src)
+
 /* user src types */
 #undef ctf_user_integer_type
 #define ctf_user_integer_type(_type, _src)                             \
 #undef ctf_user_string_type
 #define ctf_user_string_type(_src)                                     \
        ctf_user_string(unused, _src)
+
+#undef ctf_user_enum_type
+#define ctf_user_enum_type(_name, _type, _src)                         \
+       ctf_user_enum(_name, _type, unused, _src)
index fbedea1c774d50d7294929bfc9cac17cd01fd037..aa16475d24d181dd3f7c22ce7e786d3759060d1a 100644 (file)
@@ -179,6 +179,59 @@ void __event_template_proto___##_name(void);
 
 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
 
+/*
+ * Stage 1.2 of tracepoint event generation
+ *
+ * Unfolding the enums
+ */
+#include <probes/lttng-events-reset.h> /* Reset all macros within TRACE_EVENT */
+
+/* Enumeration entry (single value) */
+#undef ctf_enum_value
+#define ctf_enum_value(_string, _value)                                        \
+       {                                                               \
+               .start = {                                              \
+                       .signedness = lttng_is_signed_type(__typeof__(_value)), \
+                       .value = lttng_is_signed_type(__typeof__(_value)) ? \
+                               (long long) (_value) : (_value),        \
+               },                                                      \
+               .end = {                                                \
+                       .signedness = lttng_is_signed_type(__typeof__(_value)), \
+                       .value = lttng_is_signed_type(__typeof__(_value)) ? \
+                               (long long) (_value) : (_value),        \
+               },                                                      \
+               .string = (_string),                                    \
+       },
+
+/* Enumeration entry (range) */
+#undef ctf_enum_range
+#define ctf_enum_range(_string, _range_start, _range_end)              \
+       {                                                               \
+               .start = {                                              \
+                       .signedness = lttng_is_signed_type(__typeof__(_range_start)), \
+                       .value = lttng_is_signed_type(__typeof__(_range_start)) ? \
+                               (long long) (_range_start) : (_range_start), \
+               },                                                      \
+               .end = {                                                \
+                       .signedness = lttng_is_signed_type(__typeof__(_range_end)), \
+                       .value = lttng_is_signed_type(__typeof__(_range_end)) ? \
+                               (long long) (_range_end) : (_range_end), \
+               },                                                      \
+               .string = (_string),                                    \
+       },
+
+#undef TP_ENUM_VALUES
+#define TP_ENUM_VALUES(...)                                            \
+       __VA_ARGS__
+
+#undef LTTNG_TRACEPOINT_ENUM
+#define LTTNG_TRACEPOINT_ENUM(_name, _values)                          \
+       const struct lttng_enum_entry __enum_values__##_name[] = { \
+               _values                                                 \
+       };
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
 /*
  * Stage 2 of the trace events.
  *
@@ -303,6 +356,31 @@ void __event_template_proto___##_name(void);
          .user = _user,                                        \
        },
 
+#undef _ctf_enum
+#define _ctf_enum(_name, _type, _item, _src, _user, _nowrite)  \
+       {                                                       \
+               .name = #_item,                                 \
+               .type = {                                       \
+                       .atype = atype_enum,                    \
+                       .u = {                                  \
+                               .basic = {                      \
+                                       .enumeration = {        \
+                                               .desc = &__enum_##_name, \
+                                               .container_type = { \
+                                                       .size = sizeof(_type) * CHAR_BIT, \
+                                                       .alignment = lttng_alignof(_type) * CHAR_BIT, \
+                                                       .signedness = lttng_is_signed_type(_type), \
+                                                       .reverse_byte_order = 0, \
+                                                       .base = 10, \
+                                                       .encoding = lttng_encode_none, \
+                                               },              \
+                                       },                      \
+                                },                             \
+                       },                                      \
+               },                                              \
+               .nowrite = _nowrite,                            \
+               .user = _user,                                  \
+       },
 
 #undef ctf_custom_field
 #define ctf_custom_field(_type, _item, _code)                  \
@@ -329,6 +407,14 @@ void __event_template_proto___##_name(void);
 #define LTTNG_TRACEPOINT_EVENT_CLASS_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
        LTTNG_TRACEPOINT_EVENT_CLASS_CODE_NOARGS(_name, _locvar, _code_pre, PARAMS(_fields), _code_post)
 
+#undef LTTNG_TRACEPOINT_ENUM
+#define LTTNG_TRACEPOINT_ENUM(_name, _values)                                          \
+       static const struct lttng_enum_desc __enum_##_name = {                          \
+               .name = #_name,                                                         \
+               .entries = __enum_values__##_name,                                      \
+               .nr_entries = ARRAY_SIZE(__enum_values__##_name),                       \
+       };
+
 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
 
 /*
@@ -417,6 +503,10 @@ static void __event_probe__##_name(void *__data);
                        strlen(_src) + 1;                                      \
        }
 
+#undef _ctf_enum
+#define _ctf_enum(_name, _type, _item, _src, _user, _nowrite)                 \
+       _ctf_integer_ext(_type, _item, _src, __BYTE_ORDER, 10, _user, _nowrite)
+
 #undef ctf_align
 #define ctf_align(_type)                                               \
        __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type));
@@ -628,6 +718,10 @@ error:                                                                           \
                __stack_data += sizeof(void *);                                \
        }
 
+#undef _ctf_enum
+#define _ctf_enum(_name, _type, _item, _src, _user, _nowrite)                 \
+       _ctf_integer_ext(_type, _item, _src, __BYTE_ORDER, 10, _user, _nowrite)
+
 #undef TP_PROTO
 #define TP_PROTO(...) __VA_ARGS__
 
@@ -699,6 +793,10 @@ void __event_prepare_filter_stack__##_name(char *__stack_data,                   \
 #undef _ctf_string
 #define _ctf_string(_item, _src, _user, _nowrite)
 
+#undef _ctf_enum
+#define _ctf_enum(_name, _type, _item, _src, _user, _nowrite)  \
+       _ctf_integer_ext(_type, _item, _src, __BYTE_ORDER, 10, _user, _nowrite)
+
 #undef ctf_align
 #define ctf_align(_type)                                               \
        __event_align = max_t(size_t, __event_align, lttng_alignof(_type));
@@ -935,6 +1033,9 @@ static inline size_t __event_get_align__##_name(void *__tp_locvar)       \
                        __get_dynamic_len(dest));                       \
        }
 
+#undef _ctf_enum
+#define _ctf_enum(_name, _type, _item, _src, _user, _nowrite)          \
+       _ctf_integer_ext(_type, _item, _src, __BYTE_ORDER, 10, _user, _nowrite)
 
 #undef ctf_align
 #define ctf_align(_type)                                               \
index fc3417cd7fc8d12254688aefb2f6ce86db6f1288..e934b4bab9dbac07883426558c1cdd641a8349a9 100644 (file)
@@ -59,4 +59,6 @@
 #define LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP_NOARGS(_template, _name, _map) \
        _LTTNG_INSTRUMENTATION(DECLARE_TRACE_NOARGS(name))
 
+#define LTTNG_TRACEPOINT_ENUM(_name, _values)
+
 #endif /* LTTNG_TRACEPOINT_EVENT_H */
This page took 0.034897 seconds and 4 git commands to generate.