X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=urcu-call-rcu-impl.h;h=9beb58cbf59cfba7d8f82aae5e85fb8882db9e70;hb=bf33aaea06cbf8257cc49c38abca6d26c0c31c78;hp=69edd49f422dfdbe36524b64f7037ca66cec34fa;hpb=263e3cf98bd9b7e6b352e25b8007bd1b6df250b8;p=urcu.git diff --git a/urcu-call-rcu-impl.h b/urcu-call-rcu-impl.h index 69edd49..9beb58c 100644 --- a/urcu-call-rcu-impl.h +++ b/urcu-call-rcu-impl.h @@ -48,7 +48,7 @@ struct call_rcu_data { unsigned long flags; pthread_mutex_t mtx; int futex; - unsigned long qlen; + unsigned long qlen; /* maintained for debugging. */ pthread_t tid; int cpu_affinity; struct cds_list_head list; @@ -212,6 +212,11 @@ static void *call_rcu_thread(void *arg) thread_call_rcu_data = crdp; for (;;) { + if (!(crdp->flags & URCU_CALL_RCU_RT)) { + uatomic_dec(&crdp->futex); + /* Decrement futex before reading call_rcu list */ + cmm_smp_mb(); + } if (&crdp->cbs.head != _CMM_LOAD_SHARED(crdp->cbs.tail)) { while ((cbs = _CMM_LOAD_SHARED(crdp->cbs.head)) == NULL) poll(NULL, 0, 1); @@ -235,15 +240,21 @@ static void *call_rcu_thread(void *arg) } while (cbs != NULL); uatomic_sub(&crdp->qlen, cbcount); } - if (crdp->flags & URCU_CALL_RCU_STOP) + if (crdp->flags & URCU_CALL_RCU_STOP) { + if (!(crdp->flags & URCU_CALL_RCU_RT)) { + /* + * Read call_rcu list before write futex. + */ + cmm_smp_mb(); + uatomic_set(&crdp->futex, 0); + } break; - if (crdp->flags & URCU_CALL_RCU_RT) - poll(NULL, 0, 10); - else { + } + if (!(crdp->flags & URCU_CALL_RCU_RT)) { if (&crdp->cbs.head == _CMM_LOAD_SHARED(crdp->cbs.tail)) call_rcu_wait(crdp); - poll(NULL, 0, 10); } + poll(NULL, 0, 10); } call_rcu_lock(&crdp->mtx); crdp->flags |= URCU_CALL_RCU_STOPPED;