X-Git-Url: http://git.liburcu.org/?p=urcu.git;a=blobdiff_plain;f=urcu%2Frcuwfstack.h;h=71ecce8cce1c492f9ec48ccd90fb4c07ee1e5287;hp=300c95e3280b47c809b51a433d08844421f79525;hb=0e2e9380d93d73c246abdeef52c7a97b01deecca;hpb=ad918eeb98d1ac8b12015050ee60b488e850ac0d diff --git a/urcu/rcuwfstack.h b/urcu/rcuwfstack.h index 300c95e..71ecce8 100644 --- a/urcu/rcuwfstack.h +++ b/urcu/rcuwfstack.h @@ -25,11 +25,19 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + #if (!defined(_GNU_SOURCE) && !defined(_LGPL_SOURCE)) #error "Dynamic loader LGPL wrappers not implemented yet" #endif #define RCU_WF_STACK_END ((void *)0x1UL) +#define RCU_WFS_ADAPT_ATTEMPTS 10 /* Retry if being set */ +#define RCU_WFS_WAIT 10 /* Wait 10 ms if being set */ + +extern int rcu_wfs_futex; struct rcu_wfs_node { struct rcu_wfs_node *next; @@ -78,13 +86,12 @@ void rcu_wfs_push(struct rcu_wfs_stack *s, struct rcu_wfs_node *node) * cmpxchg is protected from ABA races by holding a RCU read lock between * s->head read and cmpxchg modifying s->head and requiring that dequeuers wait * for a grace period before freeing the returned node. - * - * TODO: implement adaptative busy-wait and wait/wakeup scheme rather than busy - * loops. Better for UP. */ struct rcu_wfs_node * rcu_wfs_pop_blocking(struct rcu_wfs_stack *s) { + int attempt = 0; + for (;;) { struct rcu_wfs_node *head; @@ -96,6 +103,11 @@ rcu_wfs_pop_blocking(struct rcu_wfs_stack *s) /* Retry while head is being set by push(). */ if (!next) { rcu_read_unlock(); + if (++attempt >= RCU_WFS_ADAPT_ATTEMPTS) { + /* Sleep for 10ms */ + poll(NULL, 0, RCU_WFS_WAIT); + attempt = 0; + } continue; } if (uatomic_cmpxchg(&s->head, head, next) == head) { @@ -114,4 +126,8 @@ rcu_wfs_pop_blocking(struct rcu_wfs_stack *s) } } +#ifdef __cplusplus +} +#endif + #endif /* _URCU_RCUWFSTACK_H */