]> sourceware.org Git - glibc.git/blame - nptl/DESIGN-condvar.txt
* Makefile (nptl-version): Change regexp so case sensitivity is ok.
[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
05df18c3 10 unsigned int cond_lock;
76a50749
UD
11
12 internal mutex
13
05df18c3 14 uint64_t total_seq;
76a50749 15
05df18c3 16 Total number of threads using the conditional variable.
76a50749 17
05df18c3 18 uint64_t wakeup_seq;
76a50749 19
05df18c3
UD
20 sequence number for next wakeup.
21
22 uint64_t woken_seq;
23
24 sequence number of last woken thread.
76a50749
UD
25
26}
27
76a50749 28
05df18c3
UD
29
30cleanup_handler(cv)
31{
32 lll_lock(cv->lock);
33
34 ++cv->wakeup_seq;
35 ++cv->woken_seq;
36
37 lll_unlock(cv->lock);
38}
39
40
41cond_timedwait(cv, mutex, timeout):
76a50749
UD
42{
43 lll_lock(cv->lock);
44 mutex_unlock(mutex);
45
05df18c3
UD
46 cleanup_push
47
48 ++cv->total_seq;
49 val = seq = cv->wakeup_seq;
50
51 while (1) {
52
53 lll_unlock(cv->lock);
54
55 enable_async
76a50749 56
05df18c3 57 ret = FUTEX_WAIT(cv->wakeup_seq, val, timeout);
76a50749 58
05df18c3 59 restore_async
76a50749 60
05df18c3 61 lll_lock(cv->lock);
76a50749 62
05df18c3 63 val = cv->wakeup_seq;
76a50749 64
05df18c3 65 if (cv->woken_seq >= seq && cv->woken_seq < val) {
76a50749 66 ret = 0;
05df18c3
UD
67 break;
68 }
69
70 if (ret == TIMEDOUT) {
71 ++cv->wakeup_seq;
72 break;
73 }
76a50749 74 }
05df18c3
UD
75
76 ++cv->woken_seq;
77
76a50749 78 lll_unlock(cv->lock);
05df18c3
UD
79
80 cleanup_pop
81
76a50749
UD
82 mutex_lock(mutex);
83
84 return ret;
85}
86
87cond_signal(cv)
88{
76a50749 89 lll_lock(cv->lock);
05df18c3
UD
90
91 if (cv->total_seq > cv->wakeup_seq) {
92 ++cv->wakeup_seq;
93 FUTEX_WAKE(cv->wakeup_seq, 1);
76a50749 94 }
05df18c3 95
76a50749 96 lll_unlock(cv->lock);
76a50749
UD
97}
98
99cond_broadcast(cv)
100{
76a50749 101 lll_lock(cv->lock);
05df18c3
UD
102
103 if (cv->total_seq > cv->wakeup_seq) {
104 cv->wakeup_seq = cv->total_seq;
105 FUTEX_WAKE(cv->wakeup_seq, ALL);
76a50749 106 }
05df18c3 107
76a50749 108 lll_unlock(cv->lock);
76a50749 109}
This page took 0.054956 seconds and 5 git commands to generate.