123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- Reader Writer Locks pseudocode
- ==============================
- pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
- pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
- pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
- struct pthread_rwlock_t {
- unsigned int lock:
- - internal mutex
- unsigned int writers_preferred;
- - locking mode: 0 recursive, readers preferred
- 1 nonrecursive, writers preferred
- unsigned int readers;
- - number of read-only references various threads have
- pthread_t writer;
- - descriptor of the writer or 0
- unsigned int readers_wakeup;
- - 'all readers should wake up' futex.
- unsigned int writer_wakeup;
- - 'one writer should wake up' futex.
- unsigned int nr_readers_queued;
- - number of readers queued up.
- unsigned int nr_writers_queued;
- - number of writers queued up.
- }
- pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
- {
- lll_lock(rwlock->lock);
- for (;;) {
- if (!rwlock->writer && (!rwlock->nr_writers_queued ||
- !rwlock->writers_preferred))
- break;
- rwlock->nr_readers_queued++;
- val = rwlock->readers_wakeup;
- lll_unlock(rwlock->lock);
- futex_wait(&rwlock->readers_wakeup, val)
- lll_lock(rwlock->lock);
- rwlock->nr_readers_queued--;
- }
- rwlock->readers++;
- lll_unlock(rwlock->lock);
- }
- pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
- {
- int result = EBUSY;
- lll_lock(rwlock->lock);
- if (!rwlock->writer && (!rwlock->nr_writers_queued ||
- !rwlock->writers_preferred))
- rwlock->readers++;
- lll_unlock(rwlock->lock);
- return result;
- }
- pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
- {
- lll_lock(rwlock->lock);
- for (;;) {
- if (!rwlock->writer && !rwlock->readers)
- break;
- rwlock->nr_writers_queued++;
- val = rwlock->writer_wakeup;
- lll_unlock(rwlock->lock);
- futex_wait(&rwlock->writer_wakeup, val);
- lll_lock(rwlock->lock);
- rwlock->nr_writers_queued--;
- }
- rwlock->writer = pthread_self();
- lll_unlock(rwlock->lock);
- }
- pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
- {
- lll_lock(rwlock->lock);
- if (rwlock->writer)
- rwlock->writer = 0;
- else
- rwlock->readers--;
- if (!rwlock->readers) {
- if (rwlock->nr_writers_queued) {
- ++rwlock->writer_wakeup;
- lll_unlock(rwlock->lock);
- futex_wake(&rwlock->writer_wakeup, 1);
- return;
- } else
- if (rwlock->nr_readers_queued) {
- ++rwlock->readers_wakeup;
- lll_unlock(rwlock->lock);
- futex_wake(&rwlock->readers_wakeup, MAX_INT);
- return;
- }
- }
- lll_unlock(rwlock->lock);
- }
|