X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=urcu-defer.c;h=3cc1a0c0b32b9132673b47a361ea116f9a8bf338;hb=83dd659a88275ec009113aba20c98b7d0b61109f;hp=a38b5c0b9418af76287b3e552fd089f278cb5e55;hpb=dbc6128f26035b2903e3278c6c41990c90831511;p=urcu.git diff --git a/urcu-defer.c b/urcu-defer.c index a38b5c0..3cc1a0c 100644 --- a/urcu-defer.c +++ b/urcu-defer.c @@ -32,14 +32,11 @@ #include #include +#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); @@ -101,7 +98,7 @@ static void wake_up_defer(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); } } @@ -134,7 +131,7 @@ static void wait_defer(void) } 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); } } @@ -233,11 +230,17 @@ end: } /* - * _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_ratelimit(void (*fct)(void *p), void *p, int (*rl)(void *p)) { unsigned long head, tail; + int sync; + + /* + * Verify if we reached the rate limiter threshold. + */ + sync = rl ? rl(p) : 0; /* * Head is only modified by ourself. Tail can be modified by reclamation @@ -247,10 +250,10 @@ void _rcu_defer_queue(void (*fct)(void *p), void *p) 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); @@ -318,9 +321,9 @@ void *thr_defer(void *args) * library wrappers to be used by non-LGPL compatible source code. */ -void rcu_defer_queue(void (*fct)(void *p), void *p) +void defer_rcu_ratelimit(void (*fct)(void *p), void *p, int (*rl)(void *p)) { - _rcu_defer_queue(fct, p); + _defer_rcu_ratelimit(fct, p, rl); } static void start_defer_thread(void)