X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=include%2Flttng%2Ftracepoint.h;h=1adb149db3994a5dcd40840126bfdef22868cb2b;hb=a334646a99520fdcf81e1460a839cae5c6d06f2c;hp=bce84e53670c7e623a8d838d7e7a21b48eec3525;hpb=05ceaafdd290220147a1faf4ca78d440f1e279b4;p=lttng-ust.git diff --git a/include/lttng/tracepoint.h b/include/lttng/tracepoint.h index bce84e53..1adb149d 100644 --- a/include/lttng/tracepoint.h +++ b/include/lttng/tracepoint.h @@ -14,9 +14,11 @@ * modified is included with the above copyright notice. */ -#include -#include +#include +#include #include +#include /* for dlopen */ +#include #ifdef __cplusplus extern "C" { @@ -36,8 +38,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() @@ -108,8 +120,10 @@ static inline void __tracepoint_cb_##provider##___##name(_TP_ARGS_PROTO(__VA_ARG { \ struct tracepoint_probe *__tp_probe; \ \ - rcu_read_lock_bp(); \ - __tp_probe = rcu_dereference(__tracepoint_##provider##___##name.probes); \ + if (!TP_RCU_LINK_TEST()) \ + return; \ + tp_rcu_read_lock_bp(); \ + __tp_probe = tp_rcu_dereference_bp(__tracepoint_##provider##___##name.probes); \ if (caa_unlikely(!__tp_probe)) \ goto end; \ do { \ @@ -120,7 +134,7 @@ static inline void __tracepoint_cb_##provider##___##name(_TP_ARGS_PROTO(__VA_ARG (_TP_ARGS_DATA_VAR(__VA_ARGS__)); \ } while ((++__tp_probe)->func); \ end: \ - rcu_read_unlock_bp(); \ + tp_rcu_read_unlock_bp(); \ } \ static inline void __tracepoint_register_##provider##___##name(char *name, \ void *func, void *data) \ @@ -133,6 +147,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 +168,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 +189,32 @@ static void __attribute__((constructor)) __tracepoints__init(void) { if (__tracepoint_registered++) return; + + liblttngust_handle = dlopen("liblttng-ust.so.0", 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")); +#ifndef _LGPL_SOURCE + tp_rcu_read_lock_bp = + URCU_FORCE_CAST(void (*)(void), + dlsym(liblttngust_handle, + "tp_rcu_read_lock_bp")); + tp_rcu_read_unlock_bp = + URCU_FORCE_CAST(void (*)(void), + dlsym(liblttngust_handle, + "tp_rcu_read_unlock_bp")); + tp_rcu_dereference_sym_bp = + URCU_FORCE_CAST(void *(*)(void *p), + dlsym(liblttngust_handle, + "tp_rcu_dereference_sym_bp")); +#endif tracepoint_register_lib(__start___tracepoints_ptrs, __stop___tracepoints_ptrs - __start___tracepoints_ptrs); @@ -178,11 +222,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 @@ -273,12 +331,14 @@ static void __attribute__((destructor)) __tracepoints__destroy(void) */ #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 */ @@ -293,29 +353,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