X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=include%2Flttng%2Ftracepoint.h;h=52513d1278f832a92fcaac8dc615e3e668891c43;hb=882a56d75d6054e1bf35d1bcddd668be4da4980f;hp=2753d95a6f7b44c39ac6e71796c8970303248b92;hpb=7f0aeeba637b9586e4657ca3b5fa1df38b8c150a;p=lttng-ust.git diff --git a/include/lttng/tracepoint.h b/include/lttng/tracepoint.h index 2753d95a..52513d12 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-tracepoint.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,68 +331,110 @@ 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 */ #ifndef TRACEPOINT_LOGLEVEL /* - * Tracepoint Loglevel Declaration Facility - * - * This is a place-holder the tracepoint loglevel declaration, - * overridden by the tracer implementation. + * Tracepoint Loglevels * * 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. - * - * TRACEPOINT_LOGLEVEL_ENUM( - * 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) - * ) - * - * 2) Then, declare tracepoint loglevels for tracepoints. A - * TRACEPOINT_EVENT should be declared prior to the the - * TRACEPOINT_LOGLEVEL for a given tracepoint name. The first field - * is the name of the tracepoint, the second field is the loglevel - * name. + * The loglevels go from 0 to 15. Higher numbers imply the most + * verbosity (higher event throughput expected. + * + * Loglevels 0 through 6, and loglevel 15, match syslog(3) loglevels + * semantic. Loglevels 7 through 14 offer more fine-grained selection of + * traced information. + * + * TRACE_EMERG 0 + * system is unusable + * + * TRACE_ALERT 1 + * action must be taken immediately + * + * TRACE_CRIT 2 + * critical conditions + * + * TRACE_ERR 3 + * error conditions + * + * TRACE_WARNING 4 + * warning conditions + * + * TRACE_NOTICE 5 + * normal, but significant, condition + * + * TRACE_INFO 6 + * informational message + * + * TRACE_SYSTEM 7 + * information has system-level scope + * + * TRACE_PROCESS 8 + * information has process-level scope + * + * TRACE_MODULE 9 + * information has module (executable/library) scope + * + * TRACE_UNIT 10 + * information has compilation unit scope + * + * TRACE_CLASS 11 + * information has class-level scope + * + * TRACE_OBJECT 12 + * information has object-level scope + * + * TRACE_FUNCTION 13 + * information has function-level scope + * + * TRACE_PRINTF 14 + * tracepoint_printf message + * + * TRACE_DEBUG 15 + * debug-level message + * + * Declare tracepoint loglevels for tracepoints. A TRACEPOINT_EVENT + * should be declared prior to the the TRACEPOINT_LOGLEVEL for a given + * tracepoint name. The first field is the name of the tracepoint, the + * second field is the loglevel name. * * TRACEPOINT_LOGLEVEL(< [com_company_]project[_component] >, < event >, * < loglevel_name >) * - * The TRACEPOINT_PROVIDER must be defined when declaring a - * TRACEPOINT_LOGLEVEL_ENUM and TRACEPOINT_LOGLEVEL. The tracepoint - * loglevel enumeration apply to the entire TRACEPOINT_PROVIDER. Only one - * tracepoint loglevel enumeration should be declared per tracepoint - * provider. + * The TRACEPOINT_PROVIDER must be already declared before declaring a + * TRACEPOINT_LOGLEVEL. */ -#define TRACEPOINT_LOGLEVEL_ENUM() -#define TRACEPOINT_LOGLEVEL(name, loglevel) +enum { + TRACE_EMERG = 0, + TRACE_ALERT = 1, + TRACE_CRIT = 2, + TRACE_ERR = 3, + TRACE_WARNING = 4, + TRACE_NOTICE = 5, + TRACE_INFO = 6, + TRACE_SYSTEM = 7, + TRACE_PROCESS = 8, + TRACE_MODULE = 9, + TRACE_UNIT = 10, + TRACE_CLASS = 11, + TRACE_OBJECT = 12, + TRACE_FUNCTION = 13, + TRACE_PRINTF = 14, + TRACE_DEBUG = 15, +}; + +#define TRACEPOINT_LOGLEVEL(provider, name, loglevel) #endif /* #ifndef TRACEPOINT_LOGLEVEL */