X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=urcu%2Fstatic%2Furcu-qsbr.h;h=f3149569b2a2e2573df57936673d82eaadf0e1d7;hb=6d5729f73aabf7cf8f25c198aa97fb5c0f76d078;hp=8b16a4abc4586783fd5a267126e43063050f58f6;hpb=1de4df4b770e5e90440008becc5e14a15c75c6e0;p=urcu.git diff --git a/urcu/static/urcu-qsbr.h b/urcu/static/urcu-qsbr.h index 8b16a4a..f314956 100644 --- a/urcu/static/urcu-qsbr.h +++ b/urcu/static/urcu-qsbr.h @@ -93,7 +93,7 @@ static inline void rcu_debug_yield_write(void) static inline void rcu_debug_yield_init(void) { - URCU_TLS(rcu_rand_yield) = time(NULL) ^ pthread_self(); + URCU_TLS(rcu_rand_yield) = time(NULL) ^ (unsigned long) pthread_self(); } #else static inline void rcu_debug_yield_read(void) @@ -180,20 +180,43 @@ static inline void _rcu_read_unlock(void) { } +/* + * This is a helper function for _rcu_quiescent_state(). + * The first cmm_smp_mb() ensures memory accesses in the prior read-side + * critical sections are not reordered with store to + * URCU_TLS(rcu_reader).ctr, and ensures that mutexes held within an + * offline section that would happen to end with this + * rcu_quiescent_state() call are not reordered with + * store to URCU_TLS(rcu_reader).ctr. + */ +static inline void _rcu_quiescent_state_update_and_wakeup(unsigned long gp_ctr) +{ + cmm_smp_mb(); + _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, gp_ctr); + cmm_smp_mb(); /* write URCU_TLS(rcu_reader).ctr before read futex */ + wake_up_gp(); + cmm_smp_mb(); +} + /* * Inform RCU of a quiescent state. * * This function is less than 10 lines long. The intent is that this * function meets the 10-line criterion for LGPL, allowing this function * to be invoked directly from non-LGPL code. + * + * We skip the memory barriers and gp store if our local ctr already + * matches the global rcu_gp_ctr value: this is OK because a prior + * _rcu_quiescent_state() or _rcu_thread_online() already updated it + * within our thread, so we have no quiescent state to report. */ static inline void _rcu_quiescent_state(void) { - cmm_smp_mb(); - _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); - cmm_smp_mb(); /* write URCU_TLS(rcu_reader).ctr before read futex */ - wake_up_gp(); - cmm_smp_mb(); + unsigned long gp_ctr; + + if ((gp_ctr = CMM_LOAD_SHARED(rcu_gp_ctr)) == URCU_TLS(rcu_reader).ctr) + return; + _rcu_quiescent_state_update_and_wakeup(gp_ctr); } /*