[lttng-dev] [RFC Patch Ust 3/5] Add the macros to generate the data structures for CTF global structures
Geneviève Bastien
gbastien+lttng at versatic.net
Wed Mar 26 10:47:10 EDT 2014
The structure global type is very similar to an event, and thus reuse most of
the macros for the event fields.
Signed-off-by: Geneviève Bastien <gbastien+lttng at versatic.net>
---
include/lttng/tracepoint.h | 67 ++++++++++++++
include/lttng/ust-tracepoint-event-nowrite.h | 4 +
include/lttng/ust-tracepoint-event-reset.h | 12 +++
include/lttng/ust-tracepoint-event-write.h | 4 +
include/lttng/ust-tracepoint-event.h | 128 ++++++++++++++++++++++++++-
5 files changed, 211 insertions(+), 4 deletions(-)
diff --git a/include/lttng/tracepoint.h b/include/lttng/tracepoint.h
index 27aa01c..4b2e85f 100644
--- a/include/lttng/tracepoint.h
+++ b/include/lttng/tracepoint.h
@@ -466,6 +466,70 @@ __tracepoints__ptrs_destroy(void)
#endif /* #ifndef TRACEPOINT_ENUM */
+#ifndef TRACEPOINT_STRUCT
+
+/*
+ * Tracepoint Structures
+ *
+ * Structures are compound types used to group fields together. These types
+ * can be reused by different tracepoints.
+ *
+ * An example:
+ *
+ * TRACEPOINT_STRUCT(someproject_component, structname,
+ *
+ * * TP_ARGS takes from 0 to 10 "type, field_name" pairs *
+ *
+ * TP_ARGS(int, arg0, void *, arg1, char *, string, size_t, strlen,
+ * long *, arg4, size_t, arg4_len),
+ *
+ * * TP_FIELDS describes the structure payload layout in the trace *
+ *
+ * TP_FIELDS(
+ * * Integer, printed in base 10 *
+ * ctf_integer(int, field_a, arg0)
+ *
+ * * Integer, printed with 0x base 16 *
+ * ctf_integer_hex(unsigned long, field_d, arg1)
+ *
+ * * Enumeration *
+ * ctf_enum(component, name, field_e, arg)
+ *
+ * * Array Sequence, printed as UTF8-encoded array of bytes *
+ * ctf_array_text(char, field_b, string, FIXED_LEN)
+ * ctf_sequence_text(char, field_c, string, size_t, strlen)
+ *
+ * * String, printed as UTF8-encoded string *
+ * ctf_string(field_e, string)
+ *
+ * * Array sequence of signed integer values *
+ * ctf_array(long, field_f, arg4, FIXED_LEN4)
+ * ctf_sequence(long, field_g, arg4, size_t, arg4_len)
+ *
+ * * Structures *
+ * ctf_struct(component, struct_name, field_s, args...)
+ * )
+ * )
+ *
+ * Where "someproject_component" is the name of the component this structure
+ * belongs to and "structname" identifies this structure. The arguments and
+ * fields described after are the same as for an event. See the event
+ * documentation for more information.
+ *
+ * That structure can then be used in a field inside the TP_FIELD macro, either
+ * in another structure or in an event using the following line:
+ *
+ * ctf_struct(someproject_component, structname, field, arguments...)
+ *
+ * Where "someproject_component" and "structname" match those in the
+ * TRACEPOINT_STRUCT, "field" is the name of the field and the arguments
+ * correspond to what the TRACEPOINT_STRUCT receives.
+ */
+
+#define TRACEPOINT_STRUCT(provider, name, args, fields)
+
+#endif /* #ifndef TRACEPOINT_STRUCT */
+
#ifndef TRACEPOINT_EVENT
/*
@@ -502,6 +566,9 @@ __tracepoints__ptrs_destroy(void)
* * Array sequence of signed integer values *
* ctf_array(long, field_f, arg4, FIXED_LEN4)
* ctf_sequence(long, field_g, arg4, size_t, arg4_len)
+ *
+ * * Structures *
+ * ctf_struct(component, struct_name, field_s, args...)
* )
* )
*
diff --git a/include/lttng/ust-tracepoint-event-nowrite.h b/include/lttng/ust-tracepoint-event-nowrite.h
index 7f5b1d9..68efb73 100644
--- a/include/lttng/ust-tracepoint-event-nowrite.h
+++ b/include/lttng/ust-tracepoint-event-nowrite.h
@@ -53,3 +53,7 @@
#undef ctf_enum_nowrite
#define ctf_enum_nowrite(_provider, _name, _item, _src) \
_ctf_enum(_provider, _name, _item, _src, 1)
+
+#undef ctf_struct_nowrite
+#define ctf_struct_nowrite(_provider, _name, _item, _src...) \
+ _ctf_struct(_provider, _name, _item, 1, _src)
diff --git a/include/lttng/ust-tracepoint-event-reset.h b/include/lttng/ust-tracepoint-event-reset.h
index 4b795c9..6342d25 100644
--- a/include/lttng/ust-tracepoint-event-reset.h
+++ b/include/lttng/ust-tracepoint-event-reset.h
@@ -31,6 +31,9 @@
#undef TRACEPOINT_ENUM
#define TRACEPOINT_ENUM(_provider, _name, _type, _values)
+#undef TRACEPOINT_STRUCT
+#define TRACEPOINT_STRUCT(_provider, _name, _args, _fields)
+
#undef TP_ARGS
#define TP_ARGS(...)
@@ -67,6 +70,9 @@
#undef _ctf_enum
#define _ctf_enum(_provider, _name, _item, _src, _nowrite)
+#undef _ctf_struct
+#define _ctf_struct(_provider, _name, _item, _nowrite, _src...)
+
#undef ctf_enum_integer
#define ctf_enum_integer(_type)
@@ -104,6 +110,9 @@
#undef ctf_enum
#define ctf_enum(_provider, _name, _item, _src)
+#undef ctf_struct
+#define ctf_struct(_provider, _name, _item, _src...)
+
/* "nowrite" */
#undef ctf_integer_nowrite
#define ctf_integer_nowrite(_type, _item, _src)
@@ -128,3 +137,6 @@
#undef ctf_enum_nowrite
#define ctf_enum_nowrite(_provider, _name, _item, _src)
+
+#undef ctf_struct_nowrite
+#define ctf_struct_nowrite(_provider, _name, _item, _src...)
diff --git a/include/lttng/ust-tracepoint-event-write.h b/include/lttng/ust-tracepoint-event-write.h
index 7dd06ed..4844a72 100644
--- a/include/lttng/ust-tracepoint-event-write.h
+++ b/include/lttng/ust-tracepoint-event-write.h
@@ -65,3 +65,7 @@
#undef ctf_enum
#define ctf_enum(_provider, _name, _item, _src) \
_ctf_enum(_provider, _name, _item, _src, 0)
+
+#undef ctf_struct
+#define ctf_struct(_provider, _name, _item, _src...) \
+ _ctf_struct(_provider, _name, _item, 0, _src)
diff --git a/include/lttng/ust-tracepoint-event.h b/include/lttng/ust-tracepoint-event.h
index c75ed73..9c351a3 100644
--- a/include/lttng/ust-tracepoint-event.h
+++ b/include/lttng/ust-tracepoint-event.h
@@ -255,6 +255,21 @@ static const char \
.encoding = lttng_encode_none, \
}
+#undef _ctf_struct
+#define _ctf_struct(_provider, _name, _item, _nowrite, _src...) \
+ { \
+ .name = #_item, \
+ .type = { \
+ .atype = atype_structure, \
+ .u = { \
+ .structure = { \
+ .name = #_provider "_" #_name, \
+ }, \
+ }, \
+ }, \
+ .nowrite = _nowrite, \
+ }
+
#undef TP_FIELDS
#define TP_FIELDS(...) __VA_ARGS__ /* Only one used in this phase */
@@ -273,6 +288,13 @@ static const char \
.len = _TP_ARRAY_SIZE(__enum_values__##_provider##_##_name), \
};
+#undef TRACEPOINT_STRUCT
+#define TRACEPOINT_STRUCT(_provider, _name, _args, _fields) \
+ static const struct lttng_event_field __struct_fields___##_provider##___##_name[] = { \
+ _fields \
+ };
+
+
#include TRACEPOINT_INCLUDE
/*
@@ -296,6 +318,16 @@ static const char \
}, \
},
+#undef _ctf_struct
+#define _ctf_struct(_provider, _name, _item, _nowrite, _src...) \
+ { \
+ .mtype = mtype_structure, \
+ .nowrite = _nowrite, \
+ .u = { \
+ .ctf_structure = &__structure_##_provider##_##_name \
+ }, \
+ }
+
#undef TP_FIELDS
#define TP_FIELDS(...) __VA_ARGS__ /* Only one used in this phase */
@@ -305,6 +337,19 @@ static const char \
_fields \
};
+#undef TRACEPOINT_STRUCT
+#define TRACEPOINT_STRUCT(_provider, _name, _args, _fields) \
+ static const struct lttng_global_type_decl __global_types_for_struct___##_provider##___##_name[] = { \
+ _fields \
+ }; \
+ static const struct lttng_structure __structure_##_provider##_##_name = { \
+ .name = #_provider "_" #_name, \
+ .nr_fields = _TP_ARRAY_SIZE(__struct_fields___##_provider##___##_name), \
+ .fields = __struct_fields___##_provider##___##_name, \
+ .nr_global_type_decl = _TP_ARRAY_SIZE(__global_types_for_struct___##_provider##___##_name), \
+ .global_type_decl = __global_types_for_struct___##_provider##___##_name, \
+ };
+
#include TRACEPOINT_INCLUDE
/*
@@ -372,6 +417,10 @@ static void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args));
#define ctf_enum_integer(_type) \
_type
+#undef _ctf_struct
+#define _ctf_struct(_provider, _name, _item, _nowrite, _src...) \
+ __event_len += __struct_get_size__##_provider##___##_name(__dynamic_len, __dynamic_len_idx, _src);
+
#undef TP_ARGS
#define TP_ARGS(...) __VA_ARGS__
@@ -405,6 +454,17 @@ size_t __enum_get_size__##_provider##___##_name(size_t __event_len) \
return __enum_len; \
}
+#undef TRACEPOINT_STRUCT
+#define TRACEPOINT_STRUCT(_provider, _name, _args, _fields) \
+static inline \
+size_t __struct_get_size__##_provider##___##_name(size_t *__dynamic_len,\
+ unsigned int __dynamic_len_idx, _TP_ARGS_PROTO(_args)) \
+{ \
+ size_t __event_len = 0; \
+ _fields \
+ return __event_len; \
+}
+
#include TRACEPOINT_INCLUDE
/*
@@ -638,6 +698,10 @@ void __event_prepare_filter_stack__##_provider##___##_name(char *__stack_data,\
#define _ctf_enum(_provider, _name, _item, _src, _nowrite) \
__event_align = _tp_max_t(size_t, __event_align, __enum_get_align__##_provider##___##_name());
+#undef _ctf_struct
+#define _ctf_struct(_provider, _name, _item, _nowrite, _src...) \
+ __event_align = _tp_max_t(size_t, __event_align, __struct_get_align__##_provider##___##_name(_src));
+
#undef TP_ARGS
#define TP_ARGS(...) __VA_ARGS__
@@ -664,8 +728,43 @@ size_t __enum_get_align__##_provider##___##_name(void) \
return lttng_alignof(_type); \
}
+#undef TRACEPOINT_STRUCT
+#define TRACEPOINT_STRUCT(_provider, _name, _args, _fields) \
+static inline \
+size_t __struct_get_align__##_provider##___##_name(_TP_ARGS_PROTO(_args))\
+{ \
+ size_t __event_align = 1; \
+ _fields \
+ return __event_align; \
+}
+
#include TRACEPOINT_INCLUDE
+/*
+ * State 4.9 of tracepoint event generation
+ *
+ * Get the maximum field count from event fields recursively
+ */
+/* Reset all macros within TRACEPOINT_EVENT */
+#include <lttng/ust-tracepoint-event-reset.h>
+#include <lttng/ust-tracepoint-event-write.h>
+
+#undef _ctf_struct
+#define _ctf_struct(_provider, _name, _item, _nowrite, _src...) \
+ + __struct_event_count___##_provider##___##_name
+
+#undef TRACEPOINT_STRUCT
+#define TRACEPOINT_STRUCT(_provider, _name, _args, _fields) \
+static const size_t __struct_field_count___##_provider##___##_name = \
+ _TP_ARRAY_SIZE(__struct_fields___##_provider##___##_name) _fields;
+
+#undef TRACEPOINT_EVENT_CLASS
+#define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
+static const size_t __event_field_count___##_provider##___##_name = \
+ _TP_ARRAY_SIZE(__event_fields___##_provider##___##_name) _fields;
+
+
+#include TRACEPOINT_INCLUDE
/*
* Stage 5 of tracepoint event generation.
@@ -703,7 +802,7 @@ size_t __enum_get_align__##_provider##___##_name(void) \
#define _ctf_sequence_encoded(_type, _item, _src, _length_type, \
_src_length, _encoding, _nowrite) \
{ \
- _length_type __tmpl = __stackvar.__dynamic_len[__dynamic_len_idx]; \
+ _length_type __tmpl = __dynamic_len[__dynamic_len_idx]; \
lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_length_type));\
__chan->ops->event_write(&__ctx, &__tmpl, sizeof(_length_type));\
} \
@@ -790,9 +889,13 @@ size_t __enum_get_align__##_provider##___##_name(void) \
} \
}
+#undef _ctf_struct
+#define _ctf_struct(_provider, _name, _item, _nowrite, _src...) \
+ __struct_probe__##_provider##___##_name(__chan, __ctx, __dynamic_len_idx, __dynamic_len, _src);
+
/* Beware: this get len actually consumes the len value */
#undef __get_dynamic_len
-#define __get_dynamic_len(field) __stackvar.__dynamic_len[__dynamic_len_idx++]
+#define __get_dynamic_len(field) __dynamic_len[__dynamic_len_idx++]
#undef TP_ARGS
#define TP_ARGS(...) __VA_ARGS__
@@ -801,6 +904,22 @@ size_t __enum_get_align__##_provider##___##_name(void) \
#define TP_FIELDS(...) __VA_ARGS__
/*
+ * Probe for structures will call this method
+ */
+#undef TRACEPOINT_STRUCT
+#define TRACEPOINT_STRUCT(_provider, _name, _args, _fields) \
+static inline \
+void __struct_probe__##_provider##___##_name(struct lttng_channel *__chan, \
+ struct lttng_ust_lib_ring_buffer_ctx __ctx, size_t __dynamic_len_idx, \
+ size_t *__dynamic_len, _TP_ARGS_PROTO(_args)) \
+{ \
+ if (0) { \
+ (void) __dynamic_len; \
+ } \
+ _fields \
+}
+
+/*
* 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.
@@ -832,9 +951,10 @@ void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args)) \
size_t __event_len, __event_align; \
size_t __dynamic_len_idx = 0; \
union { \
- size_t __dynamic_len[_TP_ARRAY_SIZE(__event_fields___##_provider##___##_name)]; \
+ size_t __dynamic_len[__event_field_count___##_provider##___##_name]; \
char __filter_stack_data[2 * sizeof(unsigned long) * _TP_ARRAY_SIZE(__event_fields___##_provider##___##_name)]; \
} __stackvar; \
+ size_t *__dynamic_len = __stackvar.__dynamic_len; \
int __ret; \
\
if (0) \
@@ -863,7 +983,7 @@ void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args)) \
if (caa_likely(!__filter_record)) \
return; \
} \
- __event_len = __event_get_size__##_provider##___##_name(__stackvar.__dynamic_len, \
+ __event_len = __event_get_size__##_provider##___##_name(__dynamic_len, \
_TP_ARGS_DATA_VAR(_args)); \
__event_align = __event_get_align__##_provider##___##_name(_TP_ARGS_VAR(_args)); \
lib_ring_buffer_ctx_init(&__ctx, __chan->chan, __event, __event_len, \
--
1.9.1
More information about the lttng-dev
mailing list