1 #include "threads_impl.h"
2 
pthread_rwlock_timedrdlock(pthread_rwlock_t * restrict rw,const struct timespec * restrict at)3 int pthread_rwlock_timedrdlock(pthread_rwlock_t* restrict rw, const struct timespec* restrict at) {
4     int r, t;
5 
6     r = pthread_rwlock_tryrdlock(rw);
7     if (r != EBUSY)
8         return r;
9 
10     int spins = 100;
11     while (spins-- && atomic_load(&rw->_rw_lock) && !atomic_load(&rw->_rw_waiters))
12         a_spin();
13 
14     while ((r = pthread_rwlock_tryrdlock(rw)) == EBUSY) {
15         if (!(r = atomic_load(&rw->_rw_lock)) || (r & PTHREAD_MUTEX_OWNED_LOCK_MASK) != PTHREAD_MUTEX_OWNED_LOCK_MASK)
16             continue;
17         t = r | PTHREAD_MUTEX_OWNED_LOCK_BIT;
18         atomic_fetch_add(&rw->_rw_waiters, 1);
19         a_cas_shim(&rw->_rw_lock, r, t);
20         r = __timedwait(&rw->_rw_lock, t, CLOCK_REALTIME, at);
21         atomic_fetch_sub(&rw->_rw_waiters, 1);
22         if (r)
23             return r;
24     }
25     return r;
26 }
27