@@ -132,12 +132,21 @@ static int set_thread_cpu_affinity(struct urcu_workqueue *workqueue)
static void futex_wait(int32_t *futex)
{
+ int ret;
+ int err;
/* Read condition before read futex */
cmm_smp_mb();
- if (uatomic_read(futex) != -1)
+ if (uatomic_read(futex) != -1) {
+ fprintf(stderr, "%lu: wq %p: %s futex != -1, don't wait\n",
+ pthread_self(), caa_container_of(futex, struct urcu_workqueue, futex), __func__);
+
return;
- while (futex_async(futex, FUTEX_WAIT, -1, NULL, NULL, 0)) {
- switch (errno) {
+ }
+ while ((ret = futex_async(futex, FUTEX_WAIT, -1, NULL, NULL, 0))) {
+ err = errno;
+ fprintf(stderr, "%lu: wq %p: %s failed, errno %d\n",
+ pthread_self(), caa_container_of(futex, struct urcu_workqueue, futex), __func__, err);
+ switch (err) {
case EWOULDBLOCK:
/* Value already changed. */
return;
@@ -146,17 +155,35 @@ static void futex_wait(int32_t *futex)
break; /* Get out of switch. */
default:
/* Unexpected error. */
- urcu_die(errno);
+ urcu_die(err);
}
}
+
+ fprintf(stderr, "%lu: wq %p: %s wait return %d\n",
+ pthread_self(), caa_container_of(futex, struct urcu_workqueue, futex), __func__, ret);
+
}
static void futex_wake_up(int32_t *futex)
{
/* Write to condition before reading/writing futex */
+ int32_t old;
+
cmm_smp_mb();
- if (caa_unlikely(uatomic_read(futex) == -1)) {
- uatomic_set(futex, 0);
+ old = uatomic_read(futex);
+ if (caa_unlikely(old == -1)) {
+ old = uatomic_xchg(futex, 0);
+ if (old == -1) {
+ fprintf(stderr, "%lu: wq %p, wakeup succeed: old %d\n",
+ pthread_self(),
+ caa_container_of(futex, struct urcu_workqueue, futex),
+ old);
+ } else {
+ fprintf(stderr, "%lu: wq %p, wakeup failed: old %d\n",
+ pthread_self(),
+ caa_container_of(futex, struct urcu_workqueue, futex),
+ old);
+ }
if (futex_async(futex, FUTEX_WAKE, 1,
NULL, NULL, 0) < 0)
urcu_die(errno);
@@ -237,8 +264,16 @@ static void *workqueue_thread(void *arg)
if (!rt) {
if (cds_wfcq_empty(&workqueue->cbs_head,
&workqueue->cbs_tail)) {
+ int32_t new;
futex_wait(&workqueue->futex);
- uatomic_dec(&workqueue->futex);
+ new = uatomic_add_return(&workqueue->futex, -1);
+ if (new == -1) {
+ fprintf(stderr, "%lu: wq %p dec succeed: old %d, new %d\n",
+ pthread_self(), workqueue, new + 1, new);
+ } else {
+ fprintf(stderr, "%lu: wq %p dec failed: old %d\n",
+ pthread_self(), workqueue, new + 1);
+ }
/*
* Decrement futex before reading
* urcu_work list.