[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: nptl 0.26



>
> No, you are wrong.  As soon as the lock is released another thread can
> come in and try to get the condvar.  It'll end up in the kernel, waiting
> for the futex.  If it is this one thread which gets woken by the
> cond_signal call (rmember: time gap between release and FUTEX_WAKE) the
> thread will find that the condition
>
>   if (cv->woken_seq >= seq && cv->woken_seq < val) {
>
> is still wrong and it will go to sleep again.  Now no thread got woken.

Ah I see... I didnt look carefully to the cond_wait() function, that uses a
different condition than signal/broadcast

We could use 2 32bits sequence numbers per cond if we allow spurious returns
for wait & timedwait functions as allowed by the standard.

typedef struct {
     int lock ; /* could be unecessary on ia32 */
     int seq ;
     int total ;
     } cond_t ;

cond_wait(cond, mutex)
{
int seq ;
lll_lock(cond->lock); /* could be unecessary on ia32 */
seq = cond->seq ;
cond->total++;
mutex_unlock(mutex);
lll_unlock(cond->lock);  /* could be unecessary on ia32 */
cleanup push (cond_signal(cond))
allow async
futex_wait(&cond->seq, seq, NULL);
restore async ;
cleanup pop
mutex_lock(mutex);
return 0 ;
}

cond_signal(cond)
{
int oval , nval ;

while (1) {
  oval = cond->seq ;
  if (oval == cond->total) break ;
    nval = oval+1 ;
   if (cmpxchg(&cond->seq, oval, nval)) {
        futex_wake(&cond->seq, 1) ;
        break ;
        }
    }
}

cond_broadcast(cond)
{
if (cond->seq != cond->total) {
    cond->seq = cond->total ;
    futex_wake(&cond->seq, ALL) ;
    }
}


Eric





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]