Let me clarify my "pthreads are crap" statement.
I firmly believe that there is a place for clone & futex threaded
programs, which is not met by pthreads for cleanliness and performance
reasons, and that such programs will become increasingly important.
Therefore I refuse to penalise such progressive programs so we can
have standards compliance. Hence my insistance on a clean, minimal,
useful interface.
> >> However, it's not too hard to implement condition variables using an
> >> unavailable mutex, if we go for "full" semaphores: ie. not just
> >> mutexes. It requires a bit more of a stretch for kernel atomic ops...
> >>
> > A full semaphore is nice, but not a full replacement for a waitqueue (or
> > a pthread condition variable brr..).
> > For the semaphore you always have to assure that the ups and downs are
> > balanced, what is not the case
> > for the condition variable.
> >
>
> also remember pthread_cond_broadcast - waking up _all_ waiting threads.
> If the woken up threads check their condition and go to sleep again, is
> up to them ( read: the standard mandates that _all_ get woken up)
>
> pthread_cond_signal notifies _one_ thread - which one depends on implementati
on
> ( I would like to see a priority based decision )
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;
}
Hope that clarifies,
Rusty.
-- Anyone who quotes me in their sig is an idiot. -- Rusty Russell. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/