{
/* Read reader_gp before read futex */
cmm_smp_rmb();
- if (uatomic_read(&rcu_gp.futex) == -1)
- futex_noasync(&rcu_gp.futex, FUTEX_WAIT, -1,
- NULL, NULL, 0);
+ if (uatomic_read(&rcu_gp.futex) != -1)
+ return;
+ while (futex_noasync(&rcu_gp.futex, FUTEX_WAIT, -1,
+ NULL, NULL, 0)) {
+ switch (errno) {
+ case EWOULDBLOCK:
+ /* Value already changed. */
+ return;
+ case EINTR:
+ /* Retry if interrupted by signal. */
+ break; /* Get out of switch. */
+ default:
+ /* Unexpected error. */
+ urcu_die(errno);
+ }
+ }
}
/*
assert(URCU_TLS(rcu_reader).ctr == 0);
mutex_lock(&rcu_registry_lock);
+ assert(!URCU_TLS(rcu_reader).registered);
+ URCU_TLS(rcu_reader).registered = 1;
cds_list_add(&URCU_TLS(rcu_reader).node, ®istry);
mutex_unlock(&rcu_registry_lock);
_rcu_thread_online();
* with a waiting writer.
*/
_rcu_thread_offline();
+ assert(URCU_TLS(rcu_reader).registered);
+ URCU_TLS(rcu_reader).registered = 0;
mutex_lock(&rcu_registry_lock);
cds_list_del(&URCU_TLS(rcu_reader).node);
mutex_unlock(&rcu_registry_lock);