typedef char lttng_ust_static_assert_##c_identifier_msg[2*!!(predicate)-1]
#endif
+/*
+ * Wrap constructor and destructor functions to invoke them as functions with
+ * the constructor/destructor GNU C attributes when building as C, or as the
+ * constructor/destructor of a variable defined within an anonymous namespace
+ * when building as C++.
+ */
+#ifdef __cplusplus
+#define LTTNG_UST_DECLARE_CONSTRUCTOR_DESTRUCTOR(name, constructor_func, \
+ destructor_func, ...) \
+namespace lttng { \
+namespace ust { \
+namespace details { \
+class LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust_constructor_destructor_, \
+ name) { \
+public: \
+ LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust_constructor_destructor_, \
+ name)() __VA_ARGS__ \
+ { \
+ constructor_func(); \
+ } \
+ ~LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust_constructor_destructor_, \
+ name)() __VA_ARGS__ \
+ { \
+ destructor_func(); \
+ } \
+}; \
+} \
+} \
+} \
+ \
+namespace { \
+const lttng::ust::details::LTTNG_UST__TP_COMBINE_TOKENS( \
+ lttng_ust_constructor_destructor_, name) \
+ LTTNG_UST__TP_COMBINE_TOKENS(name, registration_instance); \
+}
+#else /* __cplusplus */
+#define LTTNG_UST_DECLARE_CONSTRUCTOR_DESTRUCTOR(name, constructor_func, \
+ destructor_func, ...) \
+ static void LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust_constructor_, name)(void) \
+ __attribute__((constructor)) __VA_ARGS__; \
+ static void LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust_constructor_, name)(void) \
+ { \
+ constructor_func(); \
+ } \
+ static void LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust_destructor_, name)(void) \
+ __attribute__((destructor)) __VA_ARGS__; \
+ static void LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust_destructor_, name)(void) \
+ { \
+ destructor_func(); \
+ }
+#endif
+
#endif /* _LTTNG_UST_COMPILER_H */
* linking the probe statically.
*
* Register refcount is protected by libc dynamic loader mutex.
+ *
+ * Note that when building this code as C++, the definition of constructors
+ * and destructors invoking the registration and unregistration functions
+ * must be performed _after_ the initialization of the probes.
+ *
+ * This is because we rely on the order of initialization of static variables
+ * and anonymous namespaces (their order of declaration) to ensure probes are
+ * fully initialized, see
+ * https://en.cppreference.com/w/cpp/language/initialization. This is especially
+ * important when LTTNG_UST_ALLOCATE_COMPOUND_LITERAL_ON_HEAP is defined as
+ * compound literals are then dynamically initialized.
*/
/* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
#include <lttng/ust-tracepoint-event-reset.h>
+
static void
-LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__events_init__, LTTNG_UST_TRACEPOINT_PROVIDER)(void)
- lttng_ust_notrace __attribute__((constructor));
+LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__events_init__, LTTNG_UST_TRACEPOINT_PROVIDER)(void) lttng_ust_notrace;
static void
LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__events_init__, LTTNG_UST_TRACEPOINT_PROVIDER)(void)
{
}
static void
-LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__events_exit__, LTTNG_UST_TRACEPOINT_PROVIDER)(void)
- lttng_ust_notrace __attribute__((destructor));
+LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__events_exit__, LTTNG_UST_TRACEPOINT_PROVIDER)(void) lttng_ust_notrace;
static void
LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__events_exit__, LTTNG_UST_TRACEPOINT_PROVIDER)(void)
{
LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__probe_register_cookie___, LTTNG_UST_TRACEPOINT_PROVIDER) = NULL;
}
+LTTNG_UST_DECLARE_CONSTRUCTOR_DESTRUCTOR(
+ LTTNG_UST_TRACEPOINT_PROVIDER,
+ LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__events_init__, LTTNG_UST_TRACEPOINT_PROVIDER),
+ LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__events_exit__, LTTNG_UST_TRACEPOINT_PROVIDER),
+ lttng_ust_notrace)
+
/*
* LTTNG_UST_TRACEPOINT_PROVIDER_HIDDEN_DEFINITION: Define this before
* including a tracepoint instrumentation header to hide symbols