urcu:urcu/busyloop

Last commit made on 2009-09-24
Get this branch:
git clone -b urcu/busyloop https://git.launchpad.net/urcu

Branch merges

Branch information

Name:
urcu/busyloop
Repository:
lp:urcu

Recent commits

8fd3b21... by Mathieu Desnoyers <email address hidden> on 2009-09-24

urcu-defer: fix futex wakeup value

Signed-off-by: Mathieu Desnoyers <email address hidden>

17999ad... by Mathieu Desnoyers <email address hidden> on 2009-09-24

Remove extra LDFLAGS from makefile

> cc: -lpthread: linker input file unused because linking not done

Signed-off-by: Mathieu Desnoyers <email address hidden>

1315d27... by Mathieu Desnoyers <email address hidden> on 2009-09-24

Add missing include compiler.h

Signed-off-by: Mathieu Desnoyers <email address hidden>

6ee91d8... by Mathieu Desnoyers <email address hidden> on 2009-09-24

rcu torture and api.h: remove duplicated atomic primitives

Signed-off-by: Mathieu Desnoyers <email address hidden>

4d78cb5... by Mathieu Desnoyers <email address hidden> on 2009-09-24

test_atomic: test for byte/short atomic support

Signed-off-by: Mathieu Desnoyers <email address hidden>

8f41d19... by Mathieu Desnoyers <email address hidden> on 2009-09-23

ppc atomic: fix atomic_dec/inc

Only require 1 arg.

Signed-off-by: Mathieu Desnoyers <email address hidden>

80cca31... by Mathieu Desnoyers <email address hidden> on 2009-09-23

urcu-defer: remove dependency on linux/futex.h

> cc -fPIC -Wall -I. -O2 -g -lpthread -c -o urcu-defer.o `echo urcu-defer.c urcu-defer.h | sed 's/[^ ]*\.h//g'`
> In file included from urcu-defer.c:31:
> /usr/include/linux/futex.h:96: error: expected ‘)’ before ‘*’ token
> /usr/include/linux/futex.h:100: error: expected ‘)’ before ‘*’ token

Seems broken on ppc. Just for two defines, it's not worth depending on it.

Signed-off-by: Mathieu Desnoyers <email address hidden>

834a45b... by Mathieu Desnoyers <email address hidden> on 2009-09-23

urcu: Move urcu_init within ifdef

Signed-off-by: Mathieu Desnoyers <email address hidden>

da1c163... by Mathieu Desnoyers <email address hidden> on 2009-09-23

atomic ppc: fix missing casts and inline

Signed-off-by: Mathieu Desnoyers <email address hidden>

04eb9c4... by Mathieu Desnoyers <email address hidden> on 2009-09-23

urcu-defer: ensure callbacks will never be enqueued forever

Even if there are no further callbacks enqueued, ensure that after a 100ms
delay, the callback queue will be dealt with.

Required proper ordering of queue vs futex.

e.g.

 The idea is to perform the "check for empty queue" between the
&defer_thread_futex decrement and the test in wait_defer. It skips the
futex call and proceed if the list is non-empty.

As I am drilling into the problem, it looks very much like an attempt to
implement efficient wait queues in userspace based on sys_futex().

/*
 * Wake-up any waiting defer thread. Called from many concurrent
 * threads.
 */
static void wake_up_defer(void)
{
        if (unlikely(atomic_read(&defer_thread_futex) == -1)) {
                atomic_set(&defer_thread_futex, 0);
                futex(&defer_thread_futex, FUTEX_WAKE, 0,
                      NULL, NULL, 0);
        }
}

/*
 * Defer thread waiting. Single thread.
 */
static void wait_defer(void)
{
        atomic_dec(&defer_thread_futex);
        smp_mb(); /* Write futex before read queue */
        if (rcu_defer_num_callbacks()) {
                smp_mb(); /* Read queue before write futex */
                /* Callbacks are queued, don't wait. */
                atomic_set(&defer_thread_futex, 0);
        } else {
                smp_rmb(); /* Read queue before read futex */
                if (atomic_read(&defer_thread_futex) == -1)
                        futex(&defer_thread_futex, FUTEX_WAIT, -1,
                              NULL, NULL, 0);
        }
}

- call_rcu():
  * queue callbacks to perform
  * smp_mb()
  * wake_up_defer()

- defer thread:
  * for (;;)
    * wait_defer()
    * sleep 100ms (wait for more callbacks to be enqueued)
    * dequeue callbacks, execute them

The goal here is that if call_rcu() enqueues a callback (even if it
races with defer thread going to sleep), there should not be a
potentially infinite delay before it gets executed. Therefore, being
blocked in sys_futex while there is a callback to execute, without any
hope to be woken up unless another callback is queued, would not meet
that design requirement. I think that checking the number of queued
callbacks within wait_defer() as I propose here should address this
situation.

Signed-off-by: Mathieu Desnoyers <email address hidden>