compiler.h | compiler.h | |||
---|---|---|---|---|
skipping to change at line 89 | skipping to change at line 89 | |||
* usage. | * usage. | |||
*/ | */ | |||
#define __rcu | #define __rcu | |||
#ifdef __cplusplus | #ifdef __cplusplus | |||
#define URCU_FORCE_CAST(type, arg) (reinterpret_cast<type>(arg)) | #define URCU_FORCE_CAST(type, arg) (reinterpret_cast<type>(arg)) | |||
#else | #else | |||
#define URCU_FORCE_CAST(type, arg) ((type) (arg)) | #define URCU_FORCE_CAST(type, arg) ((type) (arg)) | |||
#endif | #endif | |||
#define caa_is_signed_type(type) (((type) (-1)) < 0) | #define caa_is_signed_type(type) ((type) -1 < (type) 0) | |||
#define caa_cast_long_keep_sign(v) \ | /* | |||
(caa_is_signed_type(__typeof__(v)) ? (long) (v) : (unsigned long) (v | * Sign-extend to long if needed, and output type is unsigned long. | |||
)) | */ | |||
#define caa_cast_long_keep_sign(v) \ | ||||
(caa_is_signed_type(__typeof__(v)) ? \ | ||||
(unsigned long) (long) (v) : \ | ||||
(unsigned long) (v)) | ||||
#if defined (__GNUC__) \ | #if defined (__GNUC__) \ | |||
&& ((__GNUC_MAJOR__ == 4) && (__GNUC_MINOR__ >= 5) \ | && ((__GNUC_MAJOR__ == 4) && (__GNUC_MINOR__ >= 5) \ | |||
|| __GNUC_MAJOR__ >= 5) | || __GNUC_MAJOR__ >= 5) | |||
#define CDS_DEPRECATED(msg) \ | #define CDS_DEPRECATED(msg) \ | |||
__attribute__((deprecated(msg))) | __attribute__((deprecated(msg))) | |||
#else | #else | |||
#define CDS_DEPRECATED(msg) \ | #define CDS_DEPRECATED(msg) \ | |||
__attribute__((deprecated)) | __attribute__((deprecated)) | |||
#endif | #endif | |||
End of changes. 2 change blocks. | ||||
4 lines changed or deleted | 8 lines changed or added | |||
tls-compat.h | tls-compat.h | |||
---|---|---|---|---|
skipping to change at line 73 | skipping to change at line 73 | |||
* Moreover, URCU_TLS variables should not be touched from signal | * Moreover, URCU_TLS variables should not be touched from signal | |||
* handlers setup with with sigaltstack(2). | * handlers setup with with sigaltstack(2). | |||
*/ | */ | |||
# define DECLARE_URCU_TLS(type, name) \ | # define DECLARE_URCU_TLS(type, name) \ | |||
CONFIG_RCU_TLS type name | CONFIG_RCU_TLS type name | |||
# define DEFINE_URCU_TLS(type, name) \ | # define DEFINE_URCU_TLS(type, name) \ | |||
CONFIG_RCU_TLS type name | CONFIG_RCU_TLS type name | |||
# define __DEFINE_URCU_TLS_GLOBAL(type, name) \ | ||||
CONFIG_RCU_TLS type name | ||||
# define URCU_TLS(name) (name) | # define URCU_TLS(name) (name) | |||
#else /* #ifndef CONFIG_RCU_TLS */ | #else /* #ifndef CONFIG_RCU_TLS */ | |||
/* | ||||
* The *_1() macros ensure macro parameters are expanded. | ||||
* | ||||
* __DEFINE_URCU_TLS_GLOBAL and __URCU_TLS_CALL exist for the sole | ||||
* purpose of notifying applications compiled against non-fixed 0.7 and | ||||
* 0.8 userspace RCU headers and using multiple flavors concurrently to | ||||
* recompile against fixed userspace RCU headers. | ||||
*/ | ||||
# include <pthread.h> | # include <pthread.h> | |||
struct urcu_tls { | struct urcu_tls { | |||
pthread_key_t key; | pthread_key_t key; | |||
pthread_mutex_t init_mutex; | pthread_mutex_t init_mutex; | |||
int init_done; | int init_done; | |||
}; | }; | |||
# define DECLARE_URCU_TLS_1(type, name) \ | ||||
type *__tls_access2_ ## name(void) | ||||
# define DECLARE_URCU_TLS(type, name) \ | # define DECLARE_URCU_TLS(type, name) \ | |||
type *__tls_access_ ## name(void) | DECLARE_URCU_TLS_1(type, name) | |||
/* | /* | |||
* Note: we don't free memory at process exit, since it will be dealt | * Note: we don't free memory at process exit, since it will be dealt | |||
* with by the OS. | * with by the OS. | |||
*/ | */ | |||
# define DEFINE_URCU_TLS(type, name) \ | # define __URCU_TLS_CALL_1(name) \ | |||
type *__tls_access_ ## name(void) \ | __tls_access2_ ## name | |||
# define __URCU_TLS_CALL(name) \ | ||||
__URCU_TLS_CALL_1(name) | ||||
# define DEFINE_URCU_TLS_1(type, name) \ | ||||
type *__tls_access2_ ## name(void) \ | ||||
{ \ | { \ | |||
static struct urcu_tls __tls_ ## name = { \ | static struct urcu_tls __tls_ ## name = { \ | |||
.init_mutex = PTHREAD_MUTEX_INITIALIZER,\ | .init_mutex = PTHREAD_MUTEX_INITIALIZER,\ | |||
.init_done = 0, \ | .init_done = 0, \ | |||
}; \ | }; \ | |||
void *__tls_p; \ | void *__tls_p; \ | |||
if (!__tls_ ## name.init_done) { \ | if (!__tls_ ## name.init_done) { \ | |||
/* Mutex to protect concurrent init */ \ | /* Mutex to protect concurrent init */ \ | |||
pthread_mutex_lock(&__tls_ ## name.init_mutex); \ | pthread_mutex_lock(&__tls_ ## name.init_mutex); \ | |||
if (!__tls_ ## name.init_done) { \ | if (!__tls_ ## name.init_done) { \ | |||
skipping to change at line 121 | skipping to change at line 142 | |||
cmm_smp_rmb(); /* read init_done before getting key */ \ | cmm_smp_rmb(); /* read init_done before getting key */ \ | |||
__tls_p = pthread_getspecific(__tls_ ## name.key); \ | __tls_p = pthread_getspecific(__tls_ ## name.key); \ | |||
if (caa_unlikely(__tls_p == NULL)) { \ | if (caa_unlikely(__tls_p == NULL)) { \ | |||
__tls_p = calloc(1, sizeof(type)); \ | __tls_p = calloc(1, sizeof(type)); \ | |||
(void) pthread_setspecific(__tls_ ## name.key, \ | (void) pthread_setspecific(__tls_ ## name.key, \ | |||
__tls_p); \ | __tls_p); \ | |||
} \ | } \ | |||
return __tls_p; \ | return __tls_p; \ | |||
} | } | |||
# define URCU_TLS(name) (*__tls_access_ ## name()) | /* | |||
* Define with and without macro expansion to handle erroneous callers. | ||||
* Trigger an abort() if the caller application uses the clashing symbol | ||||
* if a weak symbol is overridden. | ||||
*/ | ||||
# define __DEFINE_URCU_TLS_GLOBAL(type, name) \ | ||||
DEFINE_URCU_TLS_1(type, name) \ | ||||
int __urcu_tls_symbol_refcount_ ## name __attribute__((weak)); \ | ||||
static __attribute__((constructor)) \ | ||||
void __urcu_tls_inc_refcount_ ## name(void) \ | ||||
{ \ | ||||
__urcu_tls_symbol_refcount_ ## name++; \ | ||||
} \ | ||||
type *__tls_access_ ## name(void) \ | ||||
{ \ | ||||
if (__urcu_tls_symbol_refcount_ ## name > 1) { \ | ||||
fprintf(stderr, "Error: Userspace RCU symbol clash f | ||||
or multiple concurrent flavors. Please upgrade liburcu libraries and header | ||||
s, then recompile your application.\n"); \ | ||||
abort(); \ | ||||
} \ | ||||
return __URCU_TLS_CALL(name)(); \ | ||||
} | ||||
# define DEFINE_URCU_TLS(type, name) \ | ||||
DEFINE_URCU_TLS_1(type, name) | ||||
# define URCU_TLS_1(name) (*__tls_access2_ ## name()) | ||||
# define URCU_TLS(name) URCU_TLS_1(name) | ||||
#endif /* #else #ifndef CONFIG_RCU_TLS */ | #endif /* #else #ifndef CONFIG_RCU_TLS */ | |||
#ifdef __cplusplus | #ifdef __cplusplus | |||
} | } | |||
#endif | #endif | |||
#endif /* _URCU_TLS_COMPAT_H */ | #endif /* _URCU_TLS_COMPAT_H */ | |||
End of changes. 6 change blocks. | ||||
4 lines changed or deleted | 54 lines changed or added | |||
urcu-qsbr.h | urcu-qsbr.h | |||
---|---|---|---|---|
skipping to change at line 94 | skipping to change at line 94 | |||
/* | /* | |||
* QSBR read lock/unlock are guaranteed to be no-ops. Therefore, we expose them | * QSBR read lock/unlock are guaranteed to be no-ops. Therefore, we expose them | |||
* in the LGPL header for any code to use. However, the debug version is no t | * in the LGPL header for any code to use. However, the debug version is no t | |||
* nops and may contain sanity checks. To activate it, applications must be | * nops and may contain sanity checks. To activate it, applications must be | |||
* recompiled with -DRCU_DEBUG (even non-LGPL/GPL applications). This is th e | * recompiled with -DRCU_DEBUG (even non-LGPL/GPL applications). This is th e | |||
* best trade-off between license/performance/code triviality and | * best trade-off between license/performance/code triviality and | |||
* library debugging & tracing features we could come up with. | * library debugging & tracing features we could come up with. | |||
*/ | */ | |||
#if (!defined(BUILD_QSBR_LIB) && defined(RCU_DEBUG)) | #if (!defined(BUILD_QSBR_LIB) && !defined(RCU_DEBUG)) | |||
static inline void rcu_read_lock(void) | static inline void rcu_read_lock(void) | |||
{ | { | |||
} | } | |||
static inline void rcu_read_unlock(void) | static inline void rcu_read_unlock(void) | |||
{ | { | |||
} | } | |||
#else /* !RCU_DEBUG */ | #else /* !RCU_DEBUG */ | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||