1 Reader Writer Locks pseudocode
2 ==============================
4 pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
5 pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
6 pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
8 struct pthread_rwlock_t {
13 unsigned int writers_preferred;
14 - locking mode: 0 recursive, readers preferred
15 1 nonrecursive, writers preferred
18 - number of read-only references various threads have
21 - descriptor of the writer or 0
23 unsigned int readers_wakeup;
24 - 'all readers should wake up' futex.
26 unsigned int writer_wakeup;
27 - 'one writer should wake up' futex.
29 unsigned int nr_readers_queued;
30 - number of readers queued up.
32 unsigned int nr_writers_queued;
33 - number of writers queued up.
36 pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
38 lll_lock(rwlock->lock);
40 if (!rwlock->writer && (!rwlock->nr_writers_queued ||
41 !rwlock->writers_preferred))
44 rwlock->nr_readers_queued++;
45 val = rwlock->readers_wakeup;
46 lll_unlock(rwlock->lock);
48 futex_wait(&rwlock->readers_wakeup, val)
50 lll_lock(rwlock->lock);
53 lll_unlock(rwlock->lock);
56 pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
59 lll_lock(rwlock->lock);
60 if (!rwlock->writer && (!rwlock->nr_writers_queued ||
61 !rwlock->writers_preferred))
63 lll_unlock(rwlock->lock);
67 pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
69 lll_lock(rwlock->lock);
71 if (!rwlock->writer && !rwlock->readers)
74 rwlock->nr_writers_queued++;
75 val = rwlock->writer_wakeup;
76 lll_unlock(rwlock->lock);
78 futex_wait(&rwlock->writer_wakeup, val);
80 lll_lock(rwlock->lock);
81 rwlock->nr_writers_queued--;
83 rwlock->writer = pthread_self();
84 lll_unlock(rwlock->lock);
87 pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
89 lll_lock(rwlock->lock);
96 if (!rwlock->readers) {
97 if (rwlock->nr_writers_queued) {
98 ++rwlock->writer_wakeup;
99 lll_unlock(rwlock->lock);
100 futex_wake(&rwlock->writer_wakeup, 1);
103 if (rwlock->nr_readers_queued) {
104 ++rwlock->readers_wakeup;
105 lll_unlock(rwlock->lock);
106 futex_wake(&rwlock->readers_wakeup, MAX_INT);
111 lll_unlock(rwlock->lock);