#include <urcu/arch.h>
#include <urcu/futex.h>
+#include <urcu/system.h>
/*
* Using attribute "weak" for __urcu_compat_futex_lock and
assert(!ret);
switch (op) {
case FUTEX_WAIT:
- if (*uaddr != val)
- goto end;
- pthread_cond_wait(&__urcu_compat_futex_cond, &__urcu_compat_futex_lock);
+ /*
+ * Wait until *uaddr is changed to something else than "val".
+ * Comparing *uaddr content against val figures out which
+ * thread has been awakened.
+ */
+ while (CMM_LOAD_SHARED(*uaddr) == val)
+ pthread_cond_wait(&__urcu_compat_futex_cond,
+ &__urcu_compat_futex_lock);
break;
case FUTEX_WAKE:
+ /*
+ * Each wake is sending a broadcast, thus attempting wakeup of
+ * all awaiting threads, independently of their respective
+ * uaddr.
+ */
pthread_cond_broadcast(&__urcu_compat_futex_cond);
break;
default:
gret = -EINVAL;
}
-end:
ret = pthread_mutex_unlock(&__urcu_compat_futex_lock);
assert(!ret);
return gret;
switch (op) {
case FUTEX_WAIT:
- while (*uaddr == val)
+ while (CMM_LOAD_SHARED(*uaddr) == val)
poll(NULL, 0, 10);
break;
case FUTEX_WAKE: