| 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);}
 |