/* 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.
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 */
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) */
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();