]> git.ipfire.org Git - thirdparty/glibc.git/blame - nptl/DESIGN-rwlock.txt
Initialize tunable list with the GLIBC_TUNABLES environment variable
[thirdparty/glibc.git] / nptl / DESIGN-rwlock.txt
CommitLineData
76a50749
UD
1Reader Writer Locks pseudocode
2==============================
3
4 pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
5 pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
6 pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
7
8struct pthread_rwlock_t {
9
10 unsigned int lock:
11 - internal mutex
12
13 unsigned int writers_preferred;
14 - locking mode: 0 recursive, readers preferred
15 1 nonrecursive, writers preferred
16
17 unsigned int readers;
18 - number of read-only references various threads have
19
20 pthread_t writer;
21 - descriptor of the writer or 0
22
23 unsigned int readers_wakeup;
24 - 'all readers should wake up' futex.
25
26 unsigned int writer_wakeup;
27 - 'one writer should wake up' futex.
28
29 unsigned int nr_readers_queued;
30 - number of readers queued up.
31
32 unsigned int nr_writers_queued;
33 - number of writers queued up.
34}
35
36pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
37{
38 lll_lock(rwlock->lock);
39 for (;;) {
40 if (!rwlock->writer && (!rwlock->nr_writers_queued ||
41 !rwlock->writers_preferred))
42 break;
43
44 rwlock->nr_readers_queued++;
18a53579 45 val = rwlock->readers_wakeup;
76a50749
UD
46 lll_unlock(rwlock->lock);
47
18a53579 48 futex_wait(&rwlock->readers_wakeup, val)
76a50749
UD
49
50 lll_lock(rwlock->lock);
644eff0c 51 rwlock->nr_readers_queued--;
76a50749
UD
52 }
53 rwlock->readers++;
54 lll_unlock(rwlock->lock);
55}
56
57pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
58{
59 int result = EBUSY;
60 lll_lock(rwlock->lock);
61 if (!rwlock->writer && (!rwlock->nr_writers_queued ||
62 !rwlock->writers_preferred))
63 rwlock->readers++;
64 lll_unlock(rwlock->lock);
65 return result;
66}
67
68pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
69{
70 lll_lock(rwlock->lock);
71 for (;;) {
72 if (!rwlock->writer && !rwlock->readers)
73 break;
74
75 rwlock->nr_writers_queued++;
18a53579 76 val = rwlock->writer_wakeup;
76a50749
UD
77 lll_unlock(rwlock->lock);
78
18a53579 79 futex_wait(&rwlock->writer_wakeup, val);
76a50749
UD
80
81 lll_lock(rwlock->lock);
82 rwlock->nr_writers_queued--;
76a50749
UD
83 }
84 rwlock->writer = pthread_self();
85 lll_unlock(rwlock->lock);
86}
87
88pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
89{
90 lll_lock(rwlock->lock);
91
92 if (rwlock->writer)
93 rwlock->writer = 0;
94 else
95 rwlock->readers--;
96
97 if (!rwlock->readers) {
98 if (rwlock->nr_writers_queued) {
18a53579 99 ++rwlock->writer_wakeup;
d2637c70 100 lll_unlock(rwlock->lock);
76a50749 101 futex_wake(&rwlock->writer_wakeup, 1);
d2637c70 102 return;
76a50749
UD
103 } else
104 if (rwlock->nr_readers_queued) {
18a53579 105 ++rwlock->readers_wakeup;
d2637c70 106 lll_unlock(rwlock->lock);
76a50749 107 futex_wake(&rwlock->readers_wakeup, MAX_INT);
d2637c70 108 return;
76a50749
UD
109 }
110 }
111
112 lll_unlock(rwlock->lock);
113}