diff options
author | davidxu <davidxu@FreeBSD.org> | 2010-11-22 02:42:02 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2010-11-22 02:42:02 +0000 |
commit | b05094dc42c002877bf4b52a97ccc4af2a03adaf (patch) | |
tree | 5bb190d7a7b8b23e088da11f360c3985ab408467 /sys/kern/kern_umtx.c | |
parent | 08a93ec3b7a224311c5ad5e352f3b55bfb349524 (diff) | |
download | FreeBSD-src-b05094dc42c002877bf4b52a97ccc4af2a03adaf.zip FreeBSD-src-b05094dc42c002877bf4b52a97ccc4af2a03adaf.tar.gz |
Use atomic instruction to set _has_writer, otherwise there is a race
causes userland to not wake up a thread sleeping in kernel.
MFC after: 3 days
Diffstat (limited to 'sys/kern/kern_umtx.c')
-rw-r--r-- | sys/kern/kern_umtx.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index 951fef6..43570ce 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -2839,7 +2839,8 @@ do_sem_wait(struct thread *td, struct _usem *sem, struct timespec *timeout) umtxq_insert(uq); umtxq_unlock(&uq->uq_key); - suword32(__DEVOLATILE(uint32_t *, &sem->_has_waiters), 1); + if (fuword32(__DEVOLATILE(uint32_t *, &sem->_has_waiters)) == 0) + casuword32(__DEVOLATILE(uint32_t *, &sem->_has_waiters), 0, 1); count = fuword32(__DEVOLATILE(uint32_t *, &sem->_count)); if (count != 0) { |