]> sourceware.org Git - glibc.git/blame - nptl/DESIGN-condvar.txt
Initial revision
[glibc.git] / nptl / DESIGN-condvar.txt
CommitLineData
76a50749
UD
1Conditional Variable pseudocode.
2================================
3
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);
7
8struct pthread_cond_t {
9
10 unsigned int lock:
11
12 internal mutex
13
14 unsigned int nr_wakers:
15
16 number of threads signalled to be woken up.
17
18 unsigned int nr_sleepers:
19
20 number of threads waiting for the cv.
21
22}
23
24#define ALL_THREADS (1 << (BITS_PER_LONG-1))
25
26cond_wait_timeout(cv, mutex, timeout):
27{
28 lll_lock(cv->lock);
29 mutex_unlock(mutex);
30
31 cv->nr_sleepers++;
32 for (;;) {
33
34 if (cv->nr_wakers) {
35 cv->nr_wakers--;
36 break;
37 }
38 val = cv->nr_wakers;
39
40 lll_unlock(cv->lock);
41
42 ret = FUTEX WAIT (cv->nr_wakers, val, timeout)
43
44 lll_lock(cv->lock);
45
46 if (ret == TIMEOUT)
47 break;
48 ret = 0;
49 }
50 if (!--cv->nr_sleepers)
51 cv->nr_wakers = 0; /* no memory of wakeups */
52 lll_unlock(cv->lock);
53 mutex_lock(mutex);
54
55 return ret;
56}
57
58cond_signal(cv)
59{
60 int do_wakeup = 0;
61
62 lll_lock(cv->lock);
63 if (cv->nr_sleepers) {
64 if (!++cv->nr_wakers) /* overflow detection for the nutcase */
65 cv->nr_wakers = ALL_THREADS;
66 do_wakeup = 1;
67 }
68 lll_unlock(cv->lock);
69 if (do_wakeup)
70 FUTEX WAKE (cv->nr_wakers, 1)
71}
72
73cond_broadcast(cv)
74{
75 int do_wakeup = 0;
76
77 lll_lock(cv->lock);
78 if (cv->nr_sleepers) {
79 cv->nr_wakers |= ALL_THREADS;
80 do_wakeup = 1;
81 }
82 lll_unlock(cv->lock);
83 if (do_wakeup)
84 FUTEX WAKE (cv->nr_wakers, ALL_THREADS);
85}
86
87weaknesses of the implementation:
88
89 it might generate spurious wakeups in the broadcast case, but those are
90 allowed by POSIX.
This page took 0.035183 seconds and 5 git commands to generate.