#include <syscall.h>
#include <unistd.h>
+#include "urcu/urcu-futex.h"
#include "urcu-defer-static.h"
/* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */
#include "urcu-defer.h"
-#define futex(...) syscall(__NR_futex, __VA_ARGS__)
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
void __attribute__((destructor)) urcu_defer_exit(void);
extern void synchronize_rcu(void);
{
if (unlikely(uatomic_read(&defer_thread_futex) == -1)) {
uatomic_set(&defer_thread_futex, 0);
- futex(&defer_thread_futex, FUTEX_WAKE, 1,
+ futex_noasync(&defer_thread_futex, FUTEX_WAKE, 1,
NULL, NULL, 0);
}
}
} else {
smp_rmb(); /* Read queue before read futex */
if (uatomic_read(&defer_thread_futex) == -1)
- futex(&defer_thread_futex, FUTEX_WAIT, -1,
+ futex_noasync(&defer_thread_futex, FUTEX_WAIT, -1,
NULL, NULL, 0);
}
}
}
/*
- * _rcu_defer_queue - Queue a RCU callback.
+ * _defer_rcu - Queue a RCU callback.
*/
-void _rcu_defer_queue(void (*fct)(void *p), void *p)
+void _defer_rcu(void (*fct)(void *p), void *p)
{
unsigned long head, tail;
tail = LOAD_SHARED(defer_queue.tail);
/*
- * If queue is full, empty it ourself.
+ * If queue is full, or reached threshold. Empty queue ourself.
* Worse-case: must allow 2 supplementary entries for fct pointer.
*/
- if (unlikely(head - tail >= DEFER_QUEUE_SIZE - 2)) {
+ if (unlikely(sync || (head - tail >= DEFER_QUEUE_SIZE - 2))) {
assert(head - tail <= DEFER_QUEUE_SIZE);
rcu_defer_barrier_thread();
assert(head - LOAD_SHARED(defer_queue.tail) == 0);
* library wrappers to be used by non-LGPL compatible source code.
*/
-void rcu_defer_queue(void (*fct)(void *p), void *p)
+void defer_rcu(void (*fct)(void *p), void *p)
{
- _rcu_defer_queue(fct, p);
+ _defer_rcu(fct, p);
}
static void start_defer_thread(void)