MFC r203414:

After busied the lock, re-read state word before checking waiters flag,
otherwise, the waiters bit may not be set and a wakeup is lost.
This commit is contained in:
David Xu 2010-02-08 03:11:55 +00:00
parent 7c2545fb17
commit d430c009c7

View File

@ -2463,6 +2463,12 @@ do_rw_rdlock(struct thread *td, struct urwlock *rwlock, long fflag, int timo)
umtxq_busy(&uq->uq_key);
umtxq_unlock(&uq->uq_key);
/*
* re-read the state, in case it changed between the try-lock above
* and the check below
*/
state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state));
/* set read contention bit */
while ((state & wrflags) && !(state & URWLOCK_READ_WAITERS)) {
oldstate = casuword32(&rwlock->rw_state, state, state | URWLOCK_READ_WAITERS);
@ -2595,6 +2601,12 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock, int timo)
umtxq_busy(&uq->uq_key);
umtxq_unlock(&uq->uq_key);
/*
* re-read the state, in case it changed between the try-lock above
* and the check below
*/
state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state));
while (((state & URWLOCK_WRITE_OWNER) || URWLOCK_READER_COUNT(state) != 0) &&
(state & URWLOCK_WRITE_WAITERS) == 0) {
oldstate = casuword32(&rwlock->rw_state, state, state | URWLOCK_WRITE_WAITERS);