#include <pthread.h>
#include <assert.h>
#include <limits.h>
-#include <syscall.h>
-#include <unistd.h>
+#include <sched.h>
#include <compiler.h>
#include <arch.h>
(_________p1); \
})
-#define futex(...) syscall(__NR_futex, __VA_ARGS__)
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
/*
* This code section can only be included in LGPL 2.1 compatible source code.
* See below for the function call wrappers which can be used in code meant to
#define KICK_READER_LOOPS 10000
/*
- * Active attempts to check for reader Q.S. before calling futex().
+ * Active attempts to check for reader Q.S. before calling sched_yield().
*/
#define RCU_QS_ACTIVE_ATTEMPTS 100
}
#define RCU_GP_ONLINE (1UL << 0)
-#define RCU_GP_CTR (1UL << 1)
+#define RCU_GP_ONGOING (1UL << 1)
+#define RCU_GP_CTR (1UL << 2)
/*
* Global quiescent period counter with low-order bits unused.
extern unsigned long __thread rcu_reader_qs_gp;
-extern int gp_futex;
-
-/*
- * Wake-up waiting synchronize_rcu(). Called from many concurrent threads.
- */
-static inline void wake_up_gp(void)
-{
- if (unlikely(atomic_read(&gp_futex) == -1)) {
- atomic_set(&gp_futex, 0);
- futex(&gp_futex, FUTEX_WAKE, 1,
- NULL, NULL, 0);
- }
-}
-
#if (BITS_PER_LONG < 64)
static inline int rcu_gp_ongoing(unsigned long *value)
{
static inline void _rcu_quiescent_state(void)
{
- smp_mb();
- _STORE_SHARED(rcu_reader_qs_gp, _LOAD_SHARED(urcu_gp_ctr));
- smp_mb(); /* write rcu_reader_qs_gp before read futex */
- wake_up_gp();
+ long gp_ctr;
+
+ smp_mb();
+ gp_ctr = LOAD_SHARED(urcu_gp_ctr);
+ if (unlikely(gp_ctr & RCU_GP_ONGOING)) {
+ sched_yield();
+ gp_ctr = LOAD_SHARED(urcu_gp_ctr);
+ }
+ _STORE_SHARED(rcu_reader_qs_gp, gp_ctr);
smp_mb();
}
{
smp_mb();
STORE_SHARED(rcu_reader_qs_gp, 0);
- smp_mb(); /* write rcu_reader_qs_gp before read futex */
- wake_up_gp();
}
static inline void _rcu_thread_online(void)
{
- _STORE_SHARED(rcu_reader_qs_gp, LOAD_SHARED(urcu_gp_ctr));
+ long gp_ctr;
+
+ gp_ctr = LOAD_SHARED(urcu_gp_ctr);
+ if (unlikely(gp_ctr & RCU_GP_ONGOING)) {
+ sched_yield();
+ gp_ctr = LOAD_SHARED(urcu_gp_ctr);
+ }
+ _STORE_SHARED(rcu_reader_qs_gp, gp_ctr);
smp_mb();
}