(prune_cache): Print correct list when debugging.
[glibc.git] / nptl / DESIGN-rwlock.txt
blobcdbd4ce9ef983d0ff3eb37738a9fcd36aa798a1c
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 {
10    unsigned int lock:
11          - internal mutex
13    unsigned int writers_preferred;
14          - locking mode: 0 recursive, readers preferred
15                          1 nonrecursive, writers preferred
17    unsigned int readers;
18          - number of read-only references various threads have
20    pthread_t writer;
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);
39   for (;;) {
40     if (!rwlock->writer && (!rwlock->nr_writers_queued ||
41                                         !rwlock->writers_preferred))
42         break;
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);
51   }
52   rwlock->readers++;
53   lll_unlock(rwlock->lock);
56 pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
58   int result = EBUSY;
59   lll_lock(rwlock->lock);
60   if (!rwlock->writer && (!rwlock->nr_writers_queued ||
61                                         !rwlock->writers_preferred))
62     rwlock->readers++;
63   lll_unlock(rwlock->lock);
64   return result;
67 pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
69   lll_lock(rwlock->lock);
70   for (;;) {
71     if (!rwlock->writer && !rwlock->readers)
72        break;
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--;
82   }
83   rwlock->writer = pthread_self();
84   lll_unlock(rwlock->lock);
87 pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
89   lll_lock(rwlock->lock);
91   if (rwlock->writer)
92     rwlock->writer = 0;
93   else
94     rwlock->readers--;
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);
101       return;
102     } else
103       if (rwlock->nr_readers_queued) {
104         ++rwlock->readers_wakeup;
105         lll_unlock(rwlock->lock);
106         futex_wake(&rwlock->readers_wakeup, MAX_INT);
107         return;
108       }
109   }
111   lll_unlock(rwlock->lock);