call_rcu: fix futex-based wakeup
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 8 Jun 2011 22:28:46 +0000 (18:28 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 8 Jun 2011 22:28:46 +0000 (18:28 -0400)
The initial decrement was missing from the implementation. It now
behaves exactly like the urcu.c wait/wakeup code.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
urcu-call-rcu-impl.h

index 69edd49f422dfdbe36524b64f7037ca66cec34fa..cfe1cce43618ea218c241fba4413941825b47b43 100644 (file)
@@ -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;
This page took 0.025907 seconds and 4 git commands to generate.