diff options
author | davidxu <davidxu@FreeBSD.org> | 2010-02-08 07:31:05 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2010-02-08 07:31:05 +0000 |
commit | 7d46cfed0ac84dccfd8d90b310cbcab4367c0059 (patch) | |
tree | b0b81336f867b4f10cd207215f7893f78a9197b7 /sys/kern/kern_umtx.c | |
parent | 6da4f04ede85d3e6112c76ee79a1acef19a1db59 (diff) | |
download | FreeBSD-src-7d46cfed0ac84dccfd8d90b310cbcab4367c0059.zip FreeBSD-src-7d46cfed0ac84dccfd8d90b310cbcab4367c0059.tar.gz |
Set waiters flag before checking semaphore's counter,
otherwise we might lose a wakeup. Tested on postgresql database server.
Diffstat (limited to 'sys/kern/kern_umtx.c')
-rw-r--r-- | sys/kern/kern_umtx.c | 7 |
1 files changed, 2 insertions, 5 deletions
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index 80559ba..f80cb15 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -2853,6 +2853,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); + count = fuword32(__DEVOLATILE(uint32_t *, &sem->_count)); if (count != 0) { umtxq_lock(&uq->uq_key); @@ -2863,11 +2865,6 @@ do_sem_wait(struct thread *td, struct _usem *sem, struct timespec *timeout) return (0); } - /* - * set waiters byte and sleep. - */ - suword32(__DEVOLATILE(uint32_t *, &sem->_has_waiters), 1); - umtxq_lock(&uq->uq_key); umtxq_unbusy(&uq->uq_key); umtxq_unlock(&uq->uq_key); |