test_atomic: test for byte/short atomic support
[urcu.git] / urcu-qsbr.c
index a86f6e94d5ae13eb24e5d34610a3d9c5954373b4..5c6eaa014721267da7de5f85fff22835d41a80b2 100644 (file)
@@ -37,7 +37,7 @@
 /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */
 #include "urcu-qsbr.h"
 
-pthread_mutex_t urcu_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t urcu_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 /*
  * Global grace period counter.
@@ -135,12 +135,24 @@ static void switch_next_urcu_qparity(void)
 
 void synchronize_rcu(void)
 {
+       unsigned long was_online;
+
+       was_online = rcu_reader_qs_gp;
+
        /* All threads should read qparity before accessing data structure
         * where new ptr points to.
         */
        /* Write new ptr before changing the qparity */
        smp_mb();
 
+       /*
+        * Mark the writer thread offline to make sure we don't wait for
+        * our own quiescent state. This allows using synchronize_rcu() in
+        * threads registered as readers.
+        */
+       if (was_online)
+               STORE_SHARED(rcu_reader_qs_gp, 0);
+
        internal_urcu_lock();
 
        switch_next_urcu_qparity();     /* 0 -> 1 */
@@ -183,9 +195,12 @@ void synchronize_rcu(void)
 
        internal_urcu_unlock();
 
-       /* Finish waiting for reader threads before letting the old ptr being
+       /*
+        * Finish waiting for reader threads before letting the old ptr being
         * freed.
         */
+       if (was_online)
+               _STORE_SHARED(rcu_reader_qs_gp, LOAD_SHARED(urcu_gp_ctr));
        smp_mb();
 }
 #else /* !(BITS_PER_LONG < 64) */
@@ -240,6 +255,12 @@ void *rcu_assign_pointer_sym(void **p, void *v)
        return STORE_SHARED(p, v);
 }
 
+void *rcu_cmpxchg_pointer_sym(void **p, void *old, void *_new)
+{
+       wmb();
+       return cmpxchg(p, old, _new);
+}
+
 void *rcu_xchg_pointer_sym(void **p, void *v)
 {
        wmb();
This page took 0.023983 seconds and 4 git commands to generate.