X-Git-Url: http://git.liburcu.org/?p=urcu.git;a=blobdiff_plain;f=urcu.c;h=67a3eb21c8996b0751f9fc1d14ed9d71379f8bf5;hp=53dfbd5286e4ea5a02044fe23a17425fe738cc4f;hb=fdf01eeda9f634a32db3fc90cd342da08d7a259d;hpb=9d7e3f89772f08cca26d727f47d44ecd47c94401 diff --git a/urcu.c b/urcu.c index 53dfbd5..67a3eb2 100644 --- a/urcu.c +++ b/urcu.c @@ -23,6 +23,7 @@ * IBM's contributions to this file may be relicensed under LGPLv2 or later. */ +#define _BSD_SOURCE #include #include #include @@ -36,17 +37,26 @@ /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ #include "urcu.h" -#ifndef RCU_MB +#ifdef RCU_MEMBARRIER static int init_done; +int has_sys_membarrier; void __attribute__((constructor)) rcu_init(void); -void __attribute__((destructor)) rcu_exit(void); -#else +#endif + +#ifdef RCU_MB void rcu_init(void) { } #endif +#ifdef RCU_SIGNAL +static int init_done; + +void __attribute__((constructor)) rcu_init(void); +void __attribute__((destructor)) rcu_exit(void); +#endif + static pthread_mutex_t rcu_mutex = PTHREAD_MUTEX_INITIALIZER; int gp_futex; @@ -118,12 +128,24 @@ static void switch_next_rcu_qparity(void) STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR_PHASE); } +#ifdef RCU_MEMBARRIER +static void smp_mb_heavy(void) +{ + if (likely(has_sys_membarrier)) + membarrier(1); + else + smp_mb(); +} +#endif + #ifdef RCU_MB -static void smp_mb_heavy() +static void smp_mb_heavy(void) { smp_mb(); } -#else +#endif + +#ifdef RCU_SIGNAL static void force_mb_all_readers(void) { struct rcu_reader *index; @@ -167,11 +189,11 @@ static void force_mb_all_readers(void) smp_mb(); /* read ->need_mb before ending the barrier */ } -static void smp_mb_heavy() +static void smp_mb_heavy(void) { force_mb_all_readers(); } -#endif /* #else #ifdef RCU_MB */ +#endif /* #ifdef RCU_SIGNAL */ /* * synchronize_rcu() waiting. Single thread. @@ -364,7 +386,18 @@ void rcu_unregister_thread(void) internal_rcu_unlock(); } -#ifndef RCU_MB +#ifdef RCU_MEMBARRIER +void rcu_init(void) +{ + if (init_done) + return; + init_done = 1; + if (!membarrier(1)) + has_sys_membarrier = 1; +} +#endif + +#ifdef RCU_SIGNAL static void sigrcu_handler(int signo, siginfo_t *siginfo, void *context) { /* @@ -417,4 +450,4 @@ void rcu_exit(void) assert(act.sa_sigaction == sigrcu_handler); assert(list_empty(®istry)); } -#endif /* #ifndef RCU_MB */ +#endif /* #ifdef RCU_SIGNAL */