summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Xu <davidxu@FreeBSD.org>2010-02-09 01:19:10 +0000
committerDavid Xu <davidxu@FreeBSD.org>2010-02-09 01:19:10 +0000
commiteb3f7c0c720e63fa2490e08d907365908d971dd5 (patch)
tree86b102d1979a3a8daf3c2b809193e00c36e4244c
parent93524e051677848780d69647a4376e49b8f04211 (diff)
Notes
-rw-r--r--sys/kern/kern_umtx.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
index 2ab099d758fc..a57dc3d903be 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -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);