#include <sched.h>
#include "config.h"
+#include "compat-getcpu.h"
#include "urcu/wfcqueue.h"
#include "urcu-call-rcu.h"
#include "urcu-pointer.h"
* CPUs rather than only to specific threads.
*/
-#ifdef HAVE_SCHED_GETCPU
-
-static int urcu_sched_getcpu(void)
-{
- return sched_getcpu();
-}
-
-#else /* #ifdef HAVE_SCHED_GETCPU */
-
-static int urcu_sched_getcpu(void)
-{
- return -1;
-}
-
-#endif /* #else #ifdef HAVE_SCHED_GETCPU */
-
-#if defined(HAVE_SYSCONF) && defined(HAVE_SCHED_GETCPU)
+#if defined(HAVE_SYSCONF) && (defined(HAVE_SCHED_GETCPU) || defined(HAVE_GETCPUID))
/*
* Pointer to array of pointers to per-CPU call_rcu_data structures
{
/* Read call_rcu list before read futex */
cmm_smp_mb();
- if (uatomic_read(&crdp->futex) == -1)
- futex_async(&crdp->futex, FUTEX_WAIT, -1,
- NULL, NULL, 0);
+ if (uatomic_read(&crdp->futex) != -1)
+ return;
+ while (futex_async(&crdp->futex, FUTEX_WAIT, -1,
+ NULL, NULL, 0)) {
+ switch (errno) {
+ case EWOULDBLOCK:
+ /* Value already changed. */
+ return;
+ case EINTR:
+ /* Retry if interrupted by signal. */
+ break; /* Get out of switch. */
+ default:
+ /* Unexpected error. */
+ urcu_die(errno);
+ }
+ }
}
static void call_rcu_wake_up(struct call_rcu_data *crdp)
cmm_smp_mb();
if (caa_unlikely(uatomic_read(&crdp->futex) == -1)) {
uatomic_set(&crdp->futex, 0);
- futex_async(&crdp->futex, FUTEX_WAKE, 1,
- NULL, NULL, 0);
+ if (futex_async(&crdp->futex, FUTEX_WAKE, 1,
+ NULL, NULL, 0) < 0)
+ urcu_die(errno);
}
}
{
/* Read completion barrier count before read futex */
cmm_smp_mb();
- if (uatomic_read(&completion->futex) == -1)
- futex_async(&completion->futex, FUTEX_WAIT, -1,
- NULL, NULL, 0);
+ if (uatomic_read(&completion->futex) != -1)
+ return;
+ while (futex_async(&completion->futex, FUTEX_WAIT, -1,
+ NULL, NULL, 0)) {
+ switch (errno) {
+ case EWOULDBLOCK:
+ /* Value already changed. */
+ return;
+ case EINTR:
+ /* Retry if interrupted by signal. */
+ break; /* Get out of switch. */
+ default:
+ /* Unexpected error. */
+ urcu_die(errno);
+ }
+ }
}
static void call_rcu_completion_wake_up(struct call_rcu_completion *completion)
cmm_smp_mb();
if (caa_unlikely(uatomic_read(&completion->futex) == -1)) {
uatomic_set(&completion->futex, 0);
- futex_async(&completion->futex, FUTEX_WAKE, 1,
- NULL, NULL, 0);
+ if (futex_async(&completion->futex, FUTEX_WAKE, 1,
+ NULL, NULL, 0) < 0)
+ urcu_die(errno);
}
}