X-Git-Url: http://git.liburcu.org/?p=urcu.git;a=blobdiff_plain;f=urcu-wait.h;h=94f3e3559ba8c32492234f911911db7faa1337a9;hp=ff7d2ccfbafa1073d432645369fdd9a6d81bc30a;hb=2af1c19e6a553878fcb2a5106f050d5ed7ac0f54;hpb=bf6822a6b57e21a18a01731277355ab2e4eb23f3 diff --git a/urcu-wait.h b/urcu-wait.h index ff7d2cc..94f3e35 100644 --- a/urcu-wait.h +++ b/urcu-wait.h @@ -25,6 +25,7 @@ #include #include +#include "urcu-die.h" /* * Number of busy-loop attempts before waiting on futex for grace period @@ -122,8 +123,11 @@ void urcu_adaptative_wake_up(struct urcu_wait_node *wait) cmm_smp_mb(); assert(uatomic_read(&wait->state) == URCU_WAIT_WAITING); uatomic_set(&wait->state, URCU_WAIT_WAKEUP); - if (!(uatomic_read(&wait->state) & URCU_WAIT_RUNNING)) - futex_noasync(&wait->state, FUTEX_WAKE, 1, NULL, NULL, 0); + if (!(uatomic_read(&wait->state) & URCU_WAIT_RUNNING)) { + if (futex_noasync(&wait->state, FUTEX_WAKE, 1, + NULL, NULL, 0) < 0) + urcu_die(errno); + } /* Allow teardown of struct urcu_wait memory. */ uatomic_or(&wait->state, URCU_WAIT_TEARDOWN); } @@ -144,11 +148,23 @@ void urcu_adaptative_busy_wait(struct urcu_wait_node *wait) goto skip_futex_wait; caa_cpu_relax(); } - futex_noasync(&wait->state, FUTEX_WAIT, - URCU_WAIT_WAITING, NULL, NULL, 0); + while (futex_noasync(&wait->state, FUTEX_WAIT, URCU_WAIT_WAITING, + NULL, NULL, 0)) { + switch (errno) { + case EWOULDBLOCK: + /* Value already changed. */ + goto skip_futex_wait; + case EINTR: + /* Retry if interrupted by signal. */ + break; /* Get out of switch. */ + default: + /* Unexpected error. */ + urcu_die(errno); + } + } skip_futex_wait: - /* Tell waker thread than we are runnning. */ + /* Tell waker thread than we are running. */ uatomic_or(&wait->state, URCU_WAIT_RUNNING); /*