if there is already a waiter for a lock, spinning on the lock is essentially an attempt to steal it from whichever waiter would obtain it via any priority rules in place, and is therefore undesirable. in the current implementation, there is always an inherent race window at unlock during which a newly-arriving thread may steal the lock from the existing waiters, but we should aim to keep this window minimal rather than enlarging it.
24 lines
610 B
C
24 lines
610 B
C
#include "pthread_impl.h"
|
|
|
|
int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rw, const struct timespec *restrict at)
|
|
{
|
|
int r, t;
|
|
|
|
r = pthread_rwlock_trywrlock(rw);
|
|
if (r != EBUSY) return r;
|
|
|
|
int spins = 100;
|
|
while (spins-- && rw->_rw_lock && !rw->_rw_waiters) a_spin();
|
|
|
|
while ((r=pthread_rwlock_trywrlock(rw))==EBUSY) {
|
|
if (!(r=rw->_rw_lock)) continue;
|
|
t = r | 0x80000000;
|
|
a_inc(&rw->_rw_waiters);
|
|
a_cas(&rw->_rw_lock, r, t);
|
|
r = __timedwait(&rw->_rw_lock, t, CLOCK_REALTIME, at, 0, 0, rw->_rw_shared^128);
|
|
a_dec(&rw->_rw_waiters);
|
|
if (r && r != EINTR) return r;
|
|
}
|
|
return r;
|
|
}
|