[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