Re: [PATCH] Futexes IV (Fast Lightweight Userspace Semaphores)

Martin Wirth
2002-03-16T11:25:18Z

Rusty Russell wrote:

>
>The solution I was referring to before, using full semaphores, would
>look like so:
>
>struct pthread_cond_t
>{
> int num_waiting;
> struct futex wait, ack;
>};
>
>#define PTHREAD_COND_INITIALIZER { 0, { 0 }, { 0 } }
>
>int pthread_cond_signal(pthread_cond_t *cond)
>{
> if (cond->num_waiters)
> return futex_up(&cond->futex, 1);
> return 0;
>}
>
>int pthread_cond_broadcast(pthread_cond_t *cond)
>{
> unsigned int waiters = cond->num_waiting;
>
> if (waiters) {
> futex_up(&cond->futex, waiters);
> /* Wait for ack before returning. */
> futex_down(&cond->ack);
> }
> return 0;
>}
>
>int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
>{
> int ret;
>
> /* Increment first so broadcaster knows we are waiting. */
> atomic_inc(cond->num_waiting);
> futex_up(&mutex, 1);
> ret = futex_down(&cond);
> if (atomic_dec_and_test(cond->num_waiting))
> futex_up(&cond->ack);
> futex_down(&mutex->futex);
> return ret;
>}
>
In principle that works. But one of things that's less nice with
pthread_cond_wait is
that you sometimes have a (most of the time) unnecessary schedule
ping-pong, and with the
approach above you always have this (due to ack). And secondly if
futex_up(&f, N) for N > 1
relies on the chained wakeup in the kernels futex_up routine the
broadcast may take a while to
complete (the lowest priority waiter penalizes all others queued behind
him). A semaphore simply is no full replacement for a waitqueue with
wake_all.

Martin

P.S. With respect to pthreads I was not thinking of a bloated N:M
library, but of some simple
fast pthread semantics compatible wrapper for _clone etc.