* IBM's contributions to this file may be relicensed under LGPLv2 or later.
*/
+#define _BSD_SOURCE
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
/* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */
#include "urcu.h"
-#ifndef RCU_MB
+#ifdef RCU_MEMBARRIER
static int init_done;
+int has_sys_membarrier;
void __attribute__((constructor)) rcu_init(void);
-void __attribute__((destructor)) rcu_exit(void);
-#else
+#endif
+
+#ifdef RCU_MB
void rcu_init(void)
{
}
#endif
+#ifdef RCU_SIGNAL
+static int init_done;
+
+void __attribute__((constructor)) rcu_init(void);
+void __attribute__((destructor)) rcu_exit(void);
+#endif
+
static pthread_mutex_t rcu_mutex = PTHREAD_MUTEX_INITIALIZER;
int gp_futex;
STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR_PHASE);
}
+#ifdef RCU_MEMBARRIER
+static void smp_mb_heavy(void)
+{
+ if (likely(has_sys_membarrier))
+ membarrier(MEMBARRIER_EXPEDITED);
+ else
+ smp_mb();
+}
+#endif
+
#ifdef RCU_MB
-static void smp_mb_heavy()
+static void smp_mb_heavy(void)
{
smp_mb();
}
-#else
+#endif
+
+#ifdef RCU_SIGNAL
static void force_mb_all_readers(void)
{
struct rcu_reader *index;
smp_mb(); /* read ->need_mb before ending the barrier */
}
-static void smp_mb_heavy()
+static void smp_mb_heavy(void)
{
force_mb_all_readers();
}
-#endif /* #else #ifdef RCU_MB */
+#endif /* #ifdef RCU_SIGNAL */
/*
* synchronize_rcu() waiting. Single thread.
internal_rcu_unlock();
}
-#ifndef RCU_MB
+#ifdef RCU_MEMBARRIER
+void rcu_init(void)
+{
+ if (init_done)
+ return;
+ init_done = 1;
+ if (!membarrier(MEMBARRIER_EXPEDITED | MEMBARRIER_QUERY))
+ has_sys_membarrier = 1;
+}
+#endif
+
+#ifdef RCU_SIGNAL
static void sigrcu_handler(int signo, siginfo_t *siginfo, void *context)
{
/*
assert(act.sa_sigaction == sigrcu_handler);
assert(list_empty(®istry));
}
-#endif /* #ifndef RCU_MB */
+#endif /* #ifdef RCU_SIGNAL */