* TO BE INCLUDED ONLY IN LGPL-COMPATIBLE CODE. See urcu-qsbr.h for linking
* dynamically with the userspace rcu QSBR library.
*
- * Copyright (c) 2009 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ * Copyright (c) 2009 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
* Copyright (c) 2009 Paul E. McKenney, IBM Corporation.
*
* This library is free software; you can redistribute it and/or
#include <urcu/compiler.h>
#include <urcu/arch.h>
#include <urcu/system.h>
-#include <urcu/arch_uatomic.h>
+#include <urcu/uatomic_arch.h>
#include <urcu/list.h>
+#include <urcu/urcu-futex.h>
-#define futex(...) syscall(__NR_futex, __VA_ARGS__)
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
+#ifdef __cplusplus
+extern "C" {
+#endif
/*
* This code section can only be included in LGPL 2.1 compatible source code.
/*
* If a reader is really non-cooperative and refuses to commit its
- * urcu_reader.ctr count to memory (there is no barrier in the reader
+ * rcu_reader.ctr count to memory (there is no barrier in the reader
* per-se), kick it after a few loops waiting for it.
*/
#define KICK_READER_LOOPS 10000
}
#endif
-static inline void reader_barrier()
-{
- smp_mb();
-}
-
#define RCU_GP_ONLINE (1UL << 0)
#define RCU_GP_CTR (1UL << 1)
* Using a int rather than a char to eliminate false register dependencies
* causing stalls on some architectures.
*/
-extern unsigned long urcu_gp_ctr;
+extern unsigned long rcu_gp_ctr;
-struct urcu_reader {
+struct rcu_reader {
/* Data used by both reader and synchronize_rcu() */
unsigned long ctr;
/* Data used for registry */
- struct list_head head __attribute__((aligned(CACHE_LINE_SIZE)));
+ struct list_head node __attribute__((aligned(CACHE_LINE_SIZE)));
pthread_t tid;
};
-extern struct urcu_reader __thread urcu_reader;
+extern struct rcu_reader __thread rcu_reader;
extern int gp_futex;
{
if (unlikely(uatomic_read(&gp_futex) == -1)) {
uatomic_set(&gp_futex, 0);
- futex(&gp_futex, FUTEX_WAKE, 1,
+ futex_noasync(&gp_futex, FUTEX_WAKE, 1,
NULL, NULL, 0);
}
}
-#if (BITS_PER_LONG < 64)
-static inline int rcu_gp_ongoing(unsigned long *value)
-{
- unsigned long reader_gp;
-
- if (value == NULL)
- return 0;
- reader_gp = LOAD_SHARED(*value);
- return reader_gp && ((reader_gp ^ urcu_gp_ctr) & RCU_GP_CTR);
-}
-#else /* !(BITS_PER_LONG < 64) */
-static inline int rcu_gp_ongoing(unsigned long *value)
+static inline int rcu_gp_ongoing(unsigned long *ctr)
{
- unsigned long reader_gp;
+ unsigned long v;
- if (value == NULL)
- return 0;
- reader_gp = LOAD_SHARED(*value);
- return reader_gp && (reader_gp - urcu_gp_ctr > ULONG_MAX / 2);
+ v = LOAD_SHARED(*ctr);
+ return v && (v != rcu_gp_ctr);
}
-#endif /* !(BITS_PER_LONG < 64) */
static inline void _rcu_read_lock(void)
{
- rcu_assert(urcu_reader.ctr);
+ rcu_assert(rcu_reader.ctr);
}
static inline void _rcu_read_unlock(void)
static inline void _rcu_quiescent_state(void)
{
smp_mb();
- _STORE_SHARED(urcu_reader.ctr, _LOAD_SHARED(urcu_gp_ctr));
- smp_mb(); /* write urcu_reader.ctr before read futex */
+ _STORE_SHARED(rcu_reader.ctr, _LOAD_SHARED(rcu_gp_ctr));
+ smp_mb(); /* write rcu_reader.ctr before read futex */
wake_up_gp();
smp_mb();
}
static inline void _rcu_thread_offline(void)
{
smp_mb();
- STORE_SHARED(urcu_reader.ctr, 0);
- smp_mb(); /* write urcu_reader.ctr before read futex */
+ STORE_SHARED(rcu_reader.ctr, 0);
+ smp_mb(); /* write rcu_reader.ctr before read futex */
wake_up_gp();
}
static inline void _rcu_thread_online(void)
{
- _STORE_SHARED(urcu_reader.ctr, LOAD_SHARED(urcu_gp_ctr));
+ _STORE_SHARED(rcu_reader.ctr, LOAD_SHARED(rcu_gp_ctr));
smp_mb();
}
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _URCU_QSBR_STATIC_H */