Conditional Variable pseudocode.
================================

       int pthread_cond_timedwait (pthread_cond_t *cv, pthread_mutex_t *mutex);
       int pthread_cond_signal    (pthread_cond_t *cv);
       int pthread_cond_broadcast (pthread_cond_t *cv);

struct pthread_cond_t {

   unsigned int cond_lock;

         internal mutex

   uint64_t total_seq;

     Total number of threads using the conditional variable.

   uint64_t wakeup_seq;

     sequence number for next wakeup.

   uint64_t woken_seq;

     sequence number of last woken thread.

}



cleanup_handler(cv)
{
  lll_lock(cv->lock);

  ++cv->wakeup_seq;
  ++cv->woken_seq;

  /* make sure no signal gets lost.  */
  FUTEX_WAKE(cv->wakeup_seq, ALL);

  lll_unlock(cv->lock);
}


cond_timedwait(cv, mutex, timeout):
{
   lll_lock(cv->lock);
   mutex_unlock(mutex);

   cleanup_push

   ++cv->total_seq;
   val = seq =  cv->wakeup_seq;

   while (1) {

     lll_unlock(cv->lock);

     enable_async

     ret = FUTEX_WAIT(cv->wakeup_seq, val, timeout);

     restore_async

     lll_lock(cv->lock);

     val = cv->wakeup_seq;

     if (val > seq && cv->woken_seq < val) {
       ret = 0;
       break;
     }

     if (ret == TIMEDOUT) {
       ++cv->wakeup_seq;
       break;
     }
   }

   ++cv->woken_seq;

   lll_unlock(cv->lock);

   cleanup_pop

   mutex_lock(mutex);

   return ret;
}

cond_signal(cv)
{
   lll_lock(cv->lock);

   if (cv->total_seq > cv->wakeup_seq) {
     ++cv->wakeup_seq;
     FUTEX_WAKE(cv->wakeup_seq, 1);
   }

   lll_unlock(cv->lock);
}

cond_broadcast(cv)
{
   lll_lock(cv->lock);

   if (cv->total_seq > cv->wakeup_seq) {
     cv->wakeup_seq = cv->total_seq;
     FUTEX_WAKE(cv->wakeup_seq, ALL);
   }

   lll_unlock(cv->lock);
}