Add the new macro TRACEPOINT_VARIANT to globally define ctf variants that can
be used in tracepoints using the __variant macro for field definition and one
of tp_memcpy_variant (copy the memory for the length of the variant's
selection) or tp_assign_variant (different treatments for each possible
selection) assignation macro.

In the __event_probe... function, references to &__ctx are changed to a ctxptr
so that the ring buffer ctx can be passed to variant assignation functions.

Signed-off-by: Geneviève Bastien <[email protected]>
---
 lttng-events.c              |  50 +++++++++
 lttng-events.h              |  17 +++
 probes/lttng-events-reset.h |  21 ++++
 probes/lttng-events.h       | 260 ++++++++++++++++++++++++++++++++++++++++----
 4 files changed, 327 insertions(+), 21 deletions(-)

diff --git a/lttng-events.c b/lttng-events.c
index 56ff6a6..b0aea34 100644
--- a/lttng-events.c
+++ b/lttng-events.c
@@ -680,6 +680,14 @@ int _lttng_field_statedump(struct lttng_session *session,
                        field->type.u.ctf_struct.name,
                        field->name);
                break;
+       case atype_variant:
+               ret = lttng_metadata_printf(session,
+                       "               variant %s_%s <_%s> _%s;\n",
+                       field->type.u.variant.provider,
+                       field->type.u.variant.name,
+                       field->type.u.variant.enum_field,
+                       field->name);
+               break;
        default:
                WARN_ON_ONCE(1);
                return -EINVAL;
@@ -717,6 +725,16 @@ int _lttng_is_type_metadata_dumped(struct lttng_session 
*session,
                        dumped = dumped->next;
                }
                break;
+       case mtype_variant:
+               for (i = 0; i < 
session->dumped_metadata[metadata->mtype].nr_metadata; i++) {
+                       if (metadata->m.ctf_var.variant_desc ==
+                                       dumped->dumped_ptr.variant_desc) {
+                               is_dumped = 1;
+                               break;
+                       }
+                       dumped = dumped->next;
+               }
+               break;
        default:
                WARN_ON_ONCE(1);
                return -EINVAL;
@@ -742,6 +760,9 @@ static int _lttng_type_metadata_mark_dumped(struct 
lttng_session *session,
        case mtype_enum:
                dumped->dumped_ptr.ctf_enum = metadata->m.ctf_enum;
                break;
+       case mtype_variant:
+               dumped->dumped_ptr.variant_desc = 
metadata->m.ctf_var.variant_desc;
+               break;
        default:
                WARN_ON_ONCE(1);
                return -EINVAL;
@@ -838,6 +859,35 @@ int _lttng_type_metadata_do_statedump(struct lttng_session 
*session,
                if (ret)
                        return ret;
                break;
+       case mtype_variant:
+               ret = _lttng_type_metadata_statedump(session,
+                               meta->m.ctf_var.type_metadata,
+                               meta->m.ctf_var.nr_metadata);
+               if (ret)
+                       return ret;
+
+               ret = lttng_metadata_printf(session,
+                       "variant %s_%s {\n",
+                       meta->m.ctf_var.variant_desc->provider,
+                       meta->m.ctf_var.variant_desc->name
+               );
+               if (ret)
+                       return ret;
+
+               /* Print fields */
+               for (i = 0; i < meta->m.ctf_var.variant_desc->nr_fields; i++) {
+                       const struct lttng_event_field *field;
+
+                       field = &meta->m.ctf_var.variant_desc->fields[i];
+                       ret = _lttng_field_statedump(session, field);
+                       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 f4b5c6e..6a077ee 100644
--- a/lttng-events.h
+++ b/lttng-events.h
@@ -48,6 +48,7 @@ enum abstract_types {
        atype_sequence,
        atype_string,
        atype_struct,
+       atype_variant,
        NR_ABSTRACT_TYPES,
 };
 
@@ -55,6 +56,7 @@ enum abstract_types {
 enum metadata_types {
        mtype_struct,
        mtype_enum,
+       mtype_variant,
        NR_METADATA_TYPES,
 };
 
@@ -127,6 +129,10 @@ struct lttng_type {
                struct {
                        const char *provider, *name;
                } ctf_struct;
+               struct {
+                       const char *provider, *name;
+                       const char *enum_field;
+               } variant;
        } u;
 };
 
@@ -144,6 +150,11 @@ struct lttng_event_field {
        struct lttng_type type;
 };
 
+struct lttng_variant_field {
+       const char *name;
+       struct lttng_event_field field;
+};
+
 /*
  * We need to keep this perf counter field separately from struct
  * lttng_ctx_field because cpu hotplug needs fixed-location addresses.
@@ -189,6 +200,11 @@ struct lttng_metadata {
                        unsigned int nr_metadata;
                } ctf_st;
                const struct lttng_enum *ctf_enum;
+               struct {
+                       const struct lttng_struct_desc *variant_desc;
+                       const struct lttng_metadata *type_metadata;
+                       unsigned int nr_metadata;
+               } ctf_var;
        } m;
 };
 
@@ -196,6 +212,7 @@ struct lttng_metadata_dumped_data {
        union {
                const struct lttng_struct_desc *struct_desc;
                const struct lttng_enum *ctf_enum;
+               const struct lttng_struct_desc *variant_desc;
        } dumped_ptr;
        struct lttng_metadata_dumped_data *next;
 };
diff --git a/probes/lttng-events-reset.h b/probes/lttng-events-reset.h
index 94046b2..f115d5e 100644
--- a/probes/lttng-events-reset.h
+++ b/probes/lttng-events-reset.h
@@ -49,6 +49,9 @@
 #undef __struct
 #define __struct(_provider, _type, _item, _params)
 
+#undef __variant
+#define __variant(_provider, _type, _item, _enum_field, _enum, _src...)
+
 #undef tp_assign
 #define tp_assign(dest, src)
 
@@ -64,6 +67,9 @@
 #undef tp_memcpy_struct
 #define tp_memcpy_struct(provider, name, dest, src)
 
+#undef tp_memcpy_variant
+#define tp_memcpy_variant(provider, name, dest, enum_value, src...)
+
 #undef __get_str
 #define __get_str(field)
 
@@ -85,6 +91,18 @@
 #undef TP_FIELDS
 #define TP_FIELDS(args...)
 
+#undef TP_VARIANTS
+#define TP_VARIANTS(args...)
+
+#undef TP_VARIANT
+#define TP_VARIANT(_value, _field)
+
+#undef TP_variants_assign
+#define TP_variants_assign(args...)
+
+#undef TP_variant_assign
+#define TP_variant_assign(_value, _field)
+
 #undef TP_fast_assign
 #define TP_fast_assign(args...)
 
@@ -120,3 +138,6 @@
 
 #undef TRACEPOINT_ENUM
 #define TRACEPOINT_ENUM(_provider, _name, _type, _enum)
+
+#undef TRACEPOINT_VARIANT
+#define TRACEPOINT_VARIANT(_provider, _name, _proto, _args, _enum_provider, 
_enum_name, _earg, _variants, _assign)
diff --git a/probes/lttng-events.h b/probes/lttng-events.h
index 15d07d8..7e3a5b0 100644
--- a/probes/lttng-events.h
+++ b/probes/lttng-events.h
@@ -373,12 +373,31 @@ end:                                                      
                \
                },                                                      \
        },
 
+#undef __variant
+#define __variant(_provider, _type, _item, _enum_field, _enum, _src...)        
\
+       {                                                               \
+               .name = #_item,                                         \
+               .type =                                                 \
+               {                                                       \
+                       .atype = atype_variant,                         \
+                       .u.variant.provider = #_provider,               \
+                       .u.variant.name = #_type,                       \
+                       .u.variant.enum_field = #_enum_field,           \
+               },                                                      \
+       },
+
 #undef TP_STRUCT__entry
 #define TP_STRUCT__entry(args...) args /* Only one used in this phase */
 
 #undef TP_FIELDS
 #define TP_FIELDS(args...) args        /* Only one used in this phase */
 
+#undef TP_VARIANTS
+#define TP_VARIANTS(args...) args
+
+#undef TP_VARIANT
+#define TP_VARIANT(_value, _field) _field
+
 #undef TRACEPOINT_STRUCT_RAW
 #define TRACEPOINT_STRUCT_RAW(_provider, _name, _proto, _args, _fields)        
\
        static const struct lttng_event_field                   \
@@ -386,6 +405,13 @@ end:                                                       
                \
                        _fields                                 \
        };
 
+#undef TRACEPOINT_VARIANT
+#define TRACEPOINT_VARIANT(_provider, _name, _proto, _args, _enum_provider, 
_enum_name, _earg, _variants, _assign)\
+static const struct lttng_event_field                                  \
+       __variant_fields___##_provider##_##_name[] = {                  \
+                       _variants                                       \
+};
+
 #undef DECLARE_EVENT_CLASS_NOARGS
 #define DECLARE_EVENT_CLASS_NOARGS(_name, _tstruct, _assign, _print) \
        static const struct lttng_event_field __event_fields___##_name[] = { \
@@ -451,6 +477,16 @@ static const struct lttng_enum 
__enum_field__##_provider##_##_name[] = {\
 
 #undef STAGE_EXPORT_TYPES
 
+#undef TRACEPOINT_VARIANT
+#define TRACEPOINT_VARIANT(_provider, _name, _proto, _args, _enum_provider, 
_enum_name, _earg, _variants, _assign)\
+static struct lttng_struct_desc __variant_desc__##_provider##_##_name = {\
+               .fields = __variant_fields___##_provider##_##_name,     \
+               .nr_fields = 
ARRAY_SIZE(__variant_fields___##_provider##_##_name),\
+               .provider = #_provider,                                 \
+               .name = #_name,                                         \
+               .owner = THIS_MODULE,                                   \
+       };
+
 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
 
 /*
@@ -479,18 +515,39 @@ static const struct lttng_enum 
__enum_field__##_provider##_##_name[] = {\
                .m.ctf_enum = &__enum_field__##_provider##_##_type[0],  \
        },
 
+#undef __variant
+#define __variant(_provider, _type, _item, _enum_field, _enum, _src...)        
\
+       {                                                               \
+               .mtype = mtype_variant,                                 \
+               .m.ctf_var.variant_desc = 
&__variant_desc__##_provider##_##_type,\
+               .m.ctf_var.type_metadata = 
__type_metadata_for_var__##_provider##_##_type,\
+               .m.ctf_var.nr_metadata = 
ARRAY_SIZE(__type_metadata_for_var__##_provider##_##_type),\
+       },
+
 #undef TP_STRUCT__entry
 #define TP_STRUCT__entry(args...) args /* Only one used in this phase */
 
 #undef TP_FIELDS
 #define TP_FIELDS(args...) args
 
+#undef TP_VARIANTS
+#define TP_VARIANTS(args...) args
+
+#undef TP_VARIANT
+#define TP_VARIANT(_value, _field) _field
+
 #undef TRACEPOINT_STRUCT_RAW
 #define TRACEPOINT_STRUCT_RAW(_provider, _name, _proto, _args, _fields)        
\
 static const struct lttng_metadata 
__type_metadata_for__##_provider##_##_name[] = {\
        _fields                                                         \
 };
 
+#undef TRACEPOINT_VARIANT
+#define TRACEPOINT_VARIANT(_provider, _name, _proto, _args, _enum_provider, 
_enum_name, _earg, _variants, _assign)\
+static const struct lttng_metadata 
__type_metadata_for_var__##_provider##_##_name[] = {\
+       _variants                                                               
\
+};
+
 #undef DECLARE_EVENT_CLASS_NOARGS
 #define DECLARE_EVENT_CLASS_NOARGS(_name, _tstruct, _assign, _print) \
 static const struct lttng_metadata __type_metadata_for__##_name[] = {  \
@@ -635,6 +692,10 @@ static __used struct lttng_probe_desc 
TP_ID(__probe_desc___, TRACE_SYSTEM) = {
 #define __field_enum(_provider, _type, _data_type, _item)              \
        __event_len += __enum_get_size__##_provider##_##_type();
 
+#undef __variant
+#define __variant(_provider, _type, _item, _enum_field, _enum, _src...)        
\
+       __event_len += __variant_get_size__##_provider##_##_type(_enum, _src);
+
 #undef TP_PROTO
 #define TP_PROTO(args...) args
 
@@ -664,6 +725,27 @@ static inline size_t 
__enum_get_size__##_provider##_##_name(void)  \
        return sizeof(_type);                                           \
 }
 
+#undef TP_VARIANTS
+#define TP_VARIANTS(args...) args
+
+#undef TP_VARIANT
+#define TP_VARIANT(_value, _field)                                     \
+case _value:                                                           \
+       _field                                                          \
+       break;
+
+#undef TRACEPOINT_VARIANT
+#define TRACEPOINT_VARIANT(_provider, _name, _proto, _args, _enum_provider, 
_enum_name, _earg, _variants, _assign)\
+static inline size_t __variant_get_size__##_provider##_##_name(_proto) \
+       {                                                               \
+       size_t __event_len = 0;                                         \
+                                                                       \
+       switch (_earg) {                                                \
+       _variants                                                       \
+       }                                                               \
+       return __event_len;                                             \
+}
+
 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
 
 /*
@@ -700,12 +782,42 @@ static inline size_t 
__enum_get_size__##_provider##_##_name(void) \
        __event_len += __dynamic_len[__dynamic_len_idx++] =             \
                __struct_get_size__##_provider##_##_type(_params);
 
+#undef __variant
+#define __variant(_provider, _type, _item, _enum_field, _enum, _src...)        
\
+       __event_len += __dynamic_len[__dynamic_len_idx++] =             \
+               __variant_get_size__##_provider##_##_type(_enum, _src);
+
 #undef TRACEPOINT_STRUCT_RAW
 #define TRACEPOINT_STRUCT_RAW(_provider, _name, _proto, _args, _fields)
 
 #undef TRACEPOINT_ENUM
 #define TRACEPOINT_ENUM(_provider, _name, _type, _enum)
 
+#undef TP_VARIANTS
+#define TP_VARIANTS(args...) args
+
+#undef TP_VARIANT
+#define TP_VARIANT(_value, _field)                                     \
+case _value:                                                           \
+       _field                                                          \
+       break;
+
+#undef TRACEPOINT_VARIANT
+#define TRACEPOINT_VARIANT(_provider, _name, _proto, _args, _enum_provider, 
_enum_name, _earg, _variants, _assign)\
+static inline size_t __variant_get_size_full__##_provider##_##_name(size_t 
*__dynamic_len, _proto)     \
+       {                                                               \
+       size_t __event_len = 0;                                         \
+       unsigned int __dynamic_len_idx = 0;                             \
+                                                                       \
+       if (0)                                                          \
+               (void) __dynamic_len_idx;       /* don't warn if unused */\
+                                                                       \
+       switch (_earg) {                                                \
+       _variants                                                       \
+       }                                                               \
+       return __event_len;                                             \
+}
+
 #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) \
@@ -760,6 +872,11 @@ static inline size_t __event_get_size__##_name(size_t 
*__dynamic_len, _proto) \
        __event_align = max_t(size_t, __event_align,                    \
                __enum_get_align__##_provider##_##_type());
 
+#undef __variant
+#define __variant(_provider, _type, _item, _enum_field, _enum, _src...)        
\
+       __event_align = max_t(size_t, __event_align,                    \
+               __invar_get_align__##_provider##_##_type(_enum, _src));
+
 #undef TP_PROTO
 #define TP_PROTO(args...) args
 
@@ -801,6 +918,19 @@ static inline size_t 
__enum_get_align__##_provider##_##_name(void) \
        return lttng_alignof(_type);                                    \
 }
 
+#undef TRACEPOINT_VARIANT
+#define TRACEPOINT_VARIANT(_provider, _name, _proto, _args, _enum_provider, 
_enum_name, _earg, _variants, _assign)\
+static inline size_t __variant_get_align__##_provider##_##_name(_proto)        
\
+{                                                                      \
+       size_t __event_align = 1;                                       \
+       _variants                                                       \
+       return __event_align;                                           \
+}                                                                      \
+static inline size_t __invar_get_align__##_provider##_##_name(_proto)\
+{                                                                      \
+       return __variant_get_align__##_provider##_##_name(_earg, _args);\
+}
+
 #undef DECLARE_EVENT_CLASS
 #define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print)  \
 static inline size_t __event_get_align__##_name(_proto)                        
      \
@@ -848,9 +978,25 @@ static inline size_t __event_get_align__##_name(_proto)    
                      \
 #define __field_enum(_provider, _type, _data_type, _item)              \
        _data_type _item;
 
+#undef __variant
+#define __variant(_provider, _type, _item, _enum_field, _enum, _src...)        
\
+       char _item;
+
 #undef TP_STRUCT__entry
 #define TP_STRUCT__entry(args...) args
 
+#undef TP_VARIANTS
+#define TP_VARIANTS(args...) args
+
+#undef TP_VARIANT
+#define TP_VARIANT(_value, _field) _field
+
+#undef TRACEPOINT_VARIANT
+#define TRACEPOINT_VARIANT(_provider, _name, _proto, _args, _enum_provider, 
_enum_name, _earg, _variants, _assign)\
+struct __variant_typemap__##_provider##_##_name {                      \
+       _variants                                                       \
+};
+
 #undef DECLARE_EVENT_CLASS
 #define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print)  \
 struct __event_typemap__##_name {                                            \
@@ -917,6 +1063,11 @@ __end_field_##_item:
        goto __assign_##_item;                                          \
 __end_field_##_item:
 
+#undef __variant
+#define __variant(_provider, _type, _item, _enum_field, _enum, _src...)        
\
+       goto __assign_##_item;                                          \
+__end_field_##_item:
+
 /*
  * Macros mapping tp_assign() to "=", tp_memcpy() to memcpy() and tp_strcpy() 
to
  * strcpy().
@@ -926,8 +1077,8 @@ __end_field_##_item:
 __assign_##dest:                                                       \
        {                                                               \
                __typeof__(__typemap.dest) __tmp = (src);               \
-               lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__tmp));        
\
-               __chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp));\
+               lib_ring_buffer_align_ctx(__ctxptr, lttng_alignof(__tmp));\
+               __chan->ops->event_write(__ctxptr, &__tmp, sizeof(__tmp));\
        }                                                               \
        goto __end_field_##dest;
 
@@ -937,8 +1088,8 @@ __assign_##dest:                                           
        \
 __assign_##dest:                                                       \
        if (0)                                                          \
                (void) __typemap.dest;                                  \
-       lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__typemap.dest));       
\
-       __chan->ops->write_ops(&__ctx, src, len);                       \
+       lib_ring_buffer_align_ctx(__ctxptr, lttng_alignof(__typemap.dest));\
+       __chan->ops->write_ops(__ctxptr, src, len);                     \
        goto __end_field_##dest;
 
 #undef tp_memcpy
@@ -955,13 +1106,13 @@ __assign_##dest:                                         
        \
 __assign_##dest##_1:                                                   \
        {                                                               \
                u32 __tmpl = __dynamic_len[__dynamic_len_idx];          \
-               lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(u32));  \
-               __chan->ops->event_write(&__ctx, &__tmpl, sizeof(u32)); \
+               lib_ring_buffer_align_ctx(__ctxptr, lttng_alignof(u32));\
+               __chan->ops->event_write(__ctxptr, &__tmpl, sizeof(u32));\
        }                                                               \
        goto __end_field_##dest##_1;                                    \
 __assign_##dest##_2:                                                   \
-       lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__typemap.dest));       
\
-       __chan->ops->write_ops(&__ctx, src,                             \
+       lib_ring_buffer_align_ctx(__ctxptr, lttng_alignof(__typemap.dest));\
+       __chan->ops->write_ops(__ctxptr, src,                           \
                sizeof(__typemap.dest) * __get_dynamic_array_len(dest));\
        goto __end_field_##dest##_2;
 
@@ -976,8 +1127,8 @@ __assign_##dest##_2:                                       
                \
 #undef tp_memcpy_struct_gen
 #define tp_memcpy_struct_gen(write_ops, provider, name, dest, src)     \
 __assign_##dest:                                                       \
-       lib_ring_buffer_align_ctx(&__ctx, 
__struct_get_align__##provider##_##name(src));\
-       __chan->ops->write_ops(&__ctx, src,                             \
+       lib_ring_buffer_align_ctx(__ctxptr, 
__struct_get_align__##provider##_##name(src));\
+       __chan->ops->write_ops(__ctxptr, src,                           \
                sizeof(__typemap.dest) * __get_dynamic_array_len(dest));\
        goto __end_field_##dest;
 
@@ -986,6 +1137,31 @@ __assign_##dest:                                          
        \
                tp_memcpy_struct_gen(event_write, provider, name, dest, src)
 
 /*
+ * This supposes that the variant field is at the same place (same src) for
+ * each variant, which is not the case most of the time.
+ */
+#undef tp_memcpy_variant_gen
+#define tp_memcpy_variant_gen(write_ops, provider, name, dest, enum_value, 
src...)\
+__assign_##dest:                                                       \
+       lib_ring_buffer_align_ctx(__ctxptr, 
__variant_get_align__##provider##_##name(enum_value, src));\
+       __chan->ops->write_ops(__ctxptr, src,                           \
+               sizeof(__typemap.dest) * __get_dynamic_array_len(dest));\
+       goto __end_field_##dest;
+
+#undef tp_memcpy_variant
+#define tp_memcpy_variant(provider, name, dest, enum_value, src...)    \
+       tp_memcpy_variant_gen(event_write, provider, name, dest, enum_value, 
src)
+
+/* Still have to consume the array len of this field */
+#undef tp_assign_variant
+#define tp_assign_variant(provider, name, dest, enum_value, src...)    \
+__assign_##dest:                                                       \
+       __dynamic_len_idx++;                                    \
+       __variant_assign__##provider##_##name(__ctxptr, __chan, enum_value, 
src);\
+       goto __end_field_##dest;
+
+
+/*
  * The string length including the final \0.
  */
 #undef tp_copy_string_from_user
@@ -996,13 +1172,13 @@ __assign_##dest:                                         
        \
                                                                        \
                if (0)                                                  \
                        (void) __typemap.dest;                          \
-               lib_ring_buffer_align_ctx(&__ctx, 
lttng_alignof(__typemap.dest));\
+               lib_ring_buffer_align_ctx(__ctxptr, 
lttng_alignof(__typemap.dest));\
                __ustrlen = __get_dynamic_array_len(dest);              \
                if (likely(__ustrlen > 1)) {                            \
-                       __chan->ops->event_write_from_user(&__ctx, src, \
+                       __chan->ops->event_write_from_user(__ctxptr, src,\
                                __ustrlen - 1);                         \
                }                                                       \
-               __chan->ops->event_memset(&__ctx, 0, 1);                \
+               __chan->ops->event_memset(__ctxptr, 0, 1);              \
        }                                                               \
        goto __end_field_##dest;
 #undef tp_strcpy
@@ -1034,6 +1210,46 @@ __assign_##dest:                                         
        \
 #define TP_fast_assign(args...) args
 
 /*
+ * Create a function to assign a variant's values
+ */
+
+#undef TP_variants_assign
+#define TP_variants_assign(args...) args
+
+#undef TP_variant_assign
+#define TP_variant_assign(_value, _field)                              \
+case enum_##_value:                                                    \
+       goto __assign_##_value;                                         \
+       _field                                                          \
+__end_field_##_value:                                                  \
+       break;
+
+#undef TRACEPOINT_VARIANT
+#define TRACEPOINT_VARIANT(_provider, _name, _proto, _args, _enum_provider, 
_enum_name, _earg, _variants, _assign)\
+static void __variant_assign__##_provider##_##_name(struct lib_ring_buffer_ctx 
*__ctxptr,\
+               struct lttng_channel *__chan, _proto)                   \
+{                                                                      \
+       enum __trace_enum__enum_##_enum_provider##_##_enum_name __enum_val = 
__enum_get_value__##_enum_provider##_##_enum_name(_earg);\
+       struct __variant_typemap__##_provider##_##_name __typemap;      \
+       size_t __variant_len, __variant_align;                                \
+       size_t __dynamic_len_idx = 0;                                         \
+       size_t 
__dynamic_len[ARRAY_SIZE(__variant_fields___##_provider##_##_name)];\
+                                                                       \
+       if (0) {                                                        \
+               (void) __dynamic_len_idx;       /* don't warn if unused */\
+               (void) __variant_len;           /* don't warn if unused */\
+               (void) __variant_align;                                 \
+       }                                                               \
+       __variant_len = 
__variant_get_size_full__##_provider##_##_name(__dynamic_len, _earg, _args);\
+       __variant_align = __variant_get_align__##_provider##_##_name(_earg, 
_args);\
+       switch (__enum_val) {                                           \
+       _assign                                                         \
+       default:                                                        \
+               break;                                                  \
+       }                                                               \
+}
+
+/*
  * For state dump, check that "session" argument (mandatory) matches the
  * session this event belongs to. Ensures that we write state dump data only
  * into the started session, not into all sessions.
@@ -1050,7 +1266,7 @@ static void __event_probe__##_name(void *__data, _proto)  
              \
 {                                                                            \
        struct lttng_event *__event = __data;                                 \
        struct lttng_channel *__chan = __event->chan;                         \
-       struct lib_ring_buffer_ctx __ctx;                                     \
+       struct lib_ring_buffer_ctx __ctx, *__ctxptr;                          \
        size_t __event_len, __event_align;                                    \
        size_t __dynamic_len_idx = 0;                                         \
        size_t __dynamic_len[ARRAY_SIZE(__event_fields___##_name)];           \
@@ -1071,14 +1287,15 @@ static void __event_probe__##_name(void *__data, 
_proto)                      \
                return;                                                       \
        __event_len = __event_get_size__##_name(__dynamic_len, _args);        \
        __event_align = __event_get_align__##_name(_args);                    \
-       lib_ring_buffer_ctx_init(&__ctx, __chan->chan, __event, __event_len,  \
+       __ctxptr = &__ctx;                                                    \
+       lib_ring_buffer_ctx_init(__ctxptr, __chan->chan, __event, __event_len,\
                                 __event_align, -1);                          \
-       __ret = __chan->ops->event_reserve(&__ctx, __event->id);              \
+       __ret = __chan->ops->event_reserve(__ctxptr, __event->id);            \
        if (__ret < 0)                                                        \
                return;                                                       \
        /* Control code (field ordering) */                                   \
        _tstruct                                                              \
-       __chan->ops->event_commit(&__ctx);                                    \
+       __chan->ops->event_commit(__ctxptr);                                  \
        return;                                                               \
        /* Copy code, steered by control code */                              \
        _assign                                                               \
@@ -1090,7 +1307,7 @@ static void __event_probe__##_name(void *__data)          
              \
 {                                                                            \
        struct lttng_event *__event = __data;                                 \
        struct lttng_channel *__chan = __event->chan;                         \
-       struct lib_ring_buffer_ctx __ctx;                                     \
+       struct lib_ring_buffer_ctx __ctx, *__ctxptr;                          \
        size_t __event_len, __event_align;                                    \
        int __ret;                                                            \
                                                                              \
@@ -1104,14 +1321,15 @@ static void __event_probe__##_name(void *__data)        
                      \
                return;                                                       \
        __event_len = 0;                                                      \
        __event_align = 1;                                                    \
-       lib_ring_buffer_ctx_init(&__ctx, __chan->chan, __event, __event_len,  \
+       __ctxptr = &__ctx;                                                    \
+       lib_ring_buffer_ctx_init(__ctxptr, __chan->chan, __event, __event_len,\
                                 __event_align, -1);                          \
-       __ret = __chan->ops->event_reserve(&__ctx, __event->id);              \
+       __ret = __chan->ops->event_reserve(__ctxptr, __event->id);            \
        if (__ret < 0)                                                        \
                return;                                                       \
        /* Control code (field ordering) */                                   \
        _tstruct                                                              \
-       __chan->ops->event_commit(&__ctx);                                    \
+       __chan->ops->event_commit(__ctxptr);                                  \
        return;                                                               \
        /* Copy code, steered by control code */                              \
        _assign                                                               \
-- 
1.8.2.1


_______________________________________________
lttng-dev mailing list
[email protected]
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

Reply via email to