* sysdeps/unix/sysv/linux/m68k/semtimedop.S: New file.
[glibc/pb-stable.git] / nptl / DESIGN-condvar.txt
blob4a8212bae1d688d3058959a72618bc9261596c06
1 Conditional Variable pseudocode.
2 ================================
4        int pthread_cond_timedwait (pthread_cond_t *cv, pthread_mutex_t *mutex);
5        int pthread_cond_signal    (pthread_cond_t *cv);
6        int pthread_cond_broadcast (pthread_cond_t *cv);
8 struct pthread_cond_t {
10    unsigned int cond_lock;
12          internal mutex
14    uint64_t total_seq;
16      Total number of threads using the conditional variable.
18    uint64_t wakeup_seq;
20      sequence number for next wakeup.
22    uint64_t woken_seq;
24      sequence number of last woken thread.
30 cleanup_handler(cv)
32   lll_lock(cv->lock);
34   ++cv->wakeup_seq;
35   ++cv->woken_seq;
37   /* make sure no signal gets lost.  */
38   FUTEX_WAKE(cv->wakeup_seq, ALL);
40   lll_unlock(cv->lock);
44 cond_timedwait(cv, mutex, timeout):
46    lll_lock(cv->lock);
47    mutex_unlock(mutex);
49    cleanup_push
51    ++cv->total_seq;
52    val = seq =  cv->wakeup_seq;
54    while (1) {
56      lll_unlock(cv->lock);
58      enable_async
60      ret = FUTEX_WAIT(cv->wakeup_seq, val, timeout);
62      restore_async
64      lll_lock(cv->lock);
66      val = cv->wakeup_seq;
68      if (val > seq && cv->woken_seq < val) {
69        ret = 0;
70        break;
71      }
73      if (ret == TIMEDOUT) {
74        ++cv->wakeup_seq;
75        break;
76      }
77    }
79    ++cv->woken_seq;
81    lll_unlock(cv->lock);
83    cleanup_pop
85    mutex_lock(mutex);
87    return ret;
90 cond_signal(cv)
92    lll_lock(cv->lock);
94    if (cv->total_seq > cv->wakeup_seq) {
95      ++cv->wakeup_seq;
96      FUTEX_WAKE(cv->wakeup_seq, 1);
97    }
99    lll_unlock(cv->lock);
102 cond_broadcast(cv)
104    lll_lock(cv->lock);
106    if (cv->total_seq > cv->wakeup_seq) {
107      cv->wakeup_seq = cv->total_seq;
108      FUTEX_WAKE(cv->wakeup_seq, ALL);
109    }
111    lll_unlock(cv->lock);