X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=include%2Flttng%2Ftracepoint.h;h=a224caebcd8485cf731648a0b6ce0e718d8d0bae;hb=5cd29ace704432c7a421f7749ef8591e30e1894c;hp=e177b87d8cfcf119c1b9ba81c67ea25d5a74088a;hpb=23c8854a5fa1120df5cfdfbf08f00e00976f95fa;p=lttng-ust.git diff --git a/include/lttng/tracepoint.h b/include/lttng/tracepoint.h index e177b87d..a224caeb 100644 --- a/include/lttng/tracepoint.h +++ b/include/lttng/tracepoint.h @@ -15,8 +15,9 @@ */ #include -#include +#include #include +#include /* for dlopen */ #ifdef __cplusplus extern "C" { @@ -36,8 +37,18 @@ extern "C" { * fine too). * Each tuple is also separated by a comma. */ -#define _TP_COMBINE_TOKENS1(_tokena, _tokenb) _tokena##_tokenb -#define _TP_COMBINE_TOKENS(_tokena, _tokenb) _TP_COMBINE_TOKENS1(_tokena, _tokenb) +#define __TP_COMBINE_TOKENS(_tokena, _tokenb) \ + _tokena##_tokenb +#define _TP_COMBINE_TOKENS(_tokena, _tokenb) \ + __TP_COMBINE_TOKENS(_tokena, _tokenb) +#define __TP_COMBINE_TOKENS3(_tokena, _tokenb, _tokenc) \ + _tokena##_tokenb##_tokenc +#define _TP_COMBINE_TOKENS3(_tokena, _tokenb, _tokenc) \ + __TP_COMBINE_TOKENS3(_tokena, _tokenb, _tokenc) +#define __TP_COMBINE_TOKENS4(_tokena, _tokenb, _tokenc, _tokend) \ + _tokena##_tokenb##_tokenc##_tokend +#define _TP_COMBINE_TOKENS4(_tokena, _tokenb, _tokenc, _tokend) \ + __TP_COMBINE_TOKENS4(_tokena, _tokenb, _tokenc, _tokend) /* _TP_EXVAR* extract the var names. */ #define _TP_EXVAR0() @@ -102,14 +113,22 @@ extern "C" { #define _TP_ARGS_DATA_VAR(...) _TP_DATA_VAR_N(_TP_NARGS(0, ##__VA_ARGS__), ##__VA_ARGS__) #define _TP_PARAMS(...) __VA_ARGS__ +#ifdef _LGPL_SOURCE +#define _TP_RCU_LINK_TEST() 1 +#else +#define _TP_RCU_LINK_TEST() rcu_read_lock_bp +#endif + #define _DECLARE_TRACEPOINT(provider, name, ...) \ extern struct tracepoint __tracepoint_##provider##___##name; \ static inline void __tracepoint_cb_##provider##___##name(_TP_ARGS_PROTO(__VA_ARGS__)) \ { \ struct tracepoint_probe *__tp_probe; \ \ + if (!_TP_RCU_LINK_TEST()) \ + return; \ rcu_read_lock_bp(); \ - __tp_probe = rcu_dereference(__tracepoint_##provider##___##name.probes); \ + __tp_probe = rcu_dereference_bp(__tracepoint_##provider##___##name.probes); \ if (caa_unlikely(!__tp_probe)) \ goto end; \ do { \ @@ -133,6 +152,11 @@ static inline void __tracepoint_unregister_##provider##___##name(char *name, \ __tracepoint_probe_unregister(name, func, data); \ } +extern int __tracepoint_probe_register(const char *name, void *func, void *data); +extern int __tracepoint_probe_unregister(const char *name, void *func, void *data); + +#ifdef TRACEPOINT_DEFINE + /* * Note: to allow PIC code, we need to allow the linker to update the pointers * in the __tracepoints_ptrs section. @@ -149,11 +173,10 @@ static inline void __tracepoint_unregister_##provider##___##name(char *name, \ __attribute__((used, section("__tracepoints_ptrs"))) = \ &__tracepoint_##provider##___##name; -extern int __tracepoint_probe_register(const char *name, void *func, void *data); -extern int __tracepoint_probe_unregister(const char *name, void *func, void *data); -extern int tracepoint_register_lib(struct tracepoint * const *tracepoints_start, +static int (*tracepoint_register_lib)(struct tracepoint * const *tracepoints_start, int tracepoints_count); -extern int tracepoint_unregister_lib(struct tracepoint * const *tracepoints_start); +static int (*tracepoint_unregister_lib)(struct tracepoint * const *tracepoints_start); +static void *liblttngust_handle; /* * These weak symbols, the constructor, and destructor take care of @@ -171,6 +194,18 @@ static void __attribute__((constructor)) __tracepoints__init(void) { if (__tracepoint_registered++) return; + + liblttngust_handle = dlopen("liblttng-ust.so", RTLD_NOW | RTLD_GLOBAL); + if (!liblttngust_handle) + return; + tracepoint_register_lib = + URCU_FORCE_CAST(int (*)(struct tracepoint * const *, int), + dlsym(liblttngust_handle, + "tracepoint_register_lib")); + tracepoint_unregister_lib = + URCU_FORCE_CAST(int (*)(struct tracepoint * const *), + dlsym(liblttngust_handle, + "tracepoint_unregister_lib")); tracepoint_register_lib(__start___tracepoints_ptrs, __stop___tracepoints_ptrs - __start___tracepoints_ptrs); @@ -178,11 +213,25 @@ static void __attribute__((constructor)) __tracepoints__init(void) static void __attribute__((destructor)) __tracepoints__destroy(void) { + int ret; if (--__tracepoint_registered) return; - tracepoint_unregister_lib(__start___tracepoints_ptrs); + if (tracepoint_unregister_lib) + tracepoint_unregister_lib(__start___tracepoints_ptrs); + if (liblttngust_handle) { + tracepoint_unregister_lib = NULL; + tracepoint_register_lib = NULL; + ret = dlclose(liblttngust_handle); + assert(!ret); + } } +#else /* TRACEPOINT_DEFINE */ + +#define _DEFINE_TRACEPOINT(provider, name) + +#endif /* #else TRACEPOINT_DEFINE */ + #ifdef __cplusplus } #endif @@ -272,14 +321,15 @@ static void __attribute__((destructor)) __tracepoints__destroy(void) * the provider:event identifier is limited to 127 characters. */ - #define TRACEPOINT_EVENT(provider, name, args, fields) \ - _DECLARE_TRACEPOINT(provider, name, _TP_PARAMS(args)) + _DECLARE_TRACEPOINT(provider, name, _TP_PARAMS(args)) \ + _DEFINE_TRACEPOINT(provider, name) #define TRACEPOINT_EVENT_CLASS(provider, name, args, fields) #define TRACEPOINT_EVENT_INSTANCE(provider, _template, name, args) \ - _DECLARE_TRACEPOINT(provider, name, _TP_PARAMS(args)) + _DECLARE_TRACEPOINT(provider, name, _TP_PARAMS(args)) \ + _DEFINE_TRACEPOINT(provider, name) #endif /* #ifndef TRACEPOINT_EVENT */ @@ -294,29 +344,30 @@ static void __attribute__((destructor)) __tracepoints__destroy(void) * Typical use of these loglevels: * * 1) Declare the mapping between loglevel names and an integer values - * within TRACEPOINT_LOGLEVEL_ENUM, using TP_LOGLEVEL for each tuple. - * Do _NOT_ add comma (,) nor semicolon (;) between the - * TRACEPOINT_LOGLEVEL_ENUM entries. Do _NOT_ add comma (,) nor - * semicolon (;) after the TRACEPOINT_LOGLEVEL_ENUM declaration. The - * name should be a proper C99 identifier. + * within TRACEPOINT_LOGLEVEL_ENUM(), using tp_loglevel() for each + * tuple. Do _NOT_ add comma (,) nor semicolon (;) between the + * tp_loglevel entries contained within TRACEPOINT_LOGLEVEL_ENUM(). + * Do _NOT_ add comma (,) nor semicolon (;) after the + * TRACEPOINT_LOGLEVEL_ENUM() declaration. The name should be a + * proper C99 identifier. * * TRACEPOINT_LOGLEVEL_ENUM( - * TP_LOGLEVEL( < loglevel_name >, < value > ) - * TP_LOGLEVEL( < loglevel_name >, < value > ) + * tp_loglevel( < loglevel_name >, < value > ) + * tp_loglevel( < loglevel_name >, < value > ) * ... * ) * * e.g.: * * TRACEPOINT_LOGLEVEL_ENUM( - * TP_LOGLEVEL(LOG_EMERG, 0) - * TP_LOGLEVEL(LOG_ALERT, 1) - * TP_LOGLEVEL(LOG_CRIT, 2) - * TP_LOGLEVEL(LOG_ERR, 3) - * TP_LOGLEVEL(LOG_WARNING, 4) - * TP_LOGLEVEL(LOG_NOTICE, 5) - * TP_LOGLEVEL(LOG_INFO, 6) - * TP_LOGLEVEL(LOG_DEBUG, 7) + * tp_loglevel(LOG_EMERG, 0) + * tp_loglevel(LOG_ALERT, 1) + * tp_loglevel(LOG_CRIT, 2) + * tp_loglevel(LOG_ERR, 3) + * tp_loglevel(LOG_WARNING, 4) + * tp_loglevel(LOG_NOTICE, 5) + * tp_loglevel(LOG_INFO, 6) + * tp_loglevel(LOG_DEBUG, 7) * ) * * 2) Then, declare tracepoint loglevels for tracepoints. A @@ -335,7 +386,7 @@ static void __attribute__((destructor)) __tracepoints__destroy(void) * provider. */ -#define TRACEPOINT_LOGLEVEL_ENUM() -#define TRACEPOINT_LOGLEVEL(name, loglevel) +#define TRACEPOINT_LOGLEVEL_ENUM(...) +#define TRACEPOINT_LOGLEVEL(provider, name, loglevel) #endif /* #ifndef TRACEPOINT_LOGLEVEL */