summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormalc2009-02-21 06:48:15 +0100
committermalc2009-02-21 06:48:15 +0100
commit5d47e3728bbd589701f74bb494c9c9825ba23c88 (patch)
tree631efac3d46418b86f7bd47c22066fa29e0b46cd
parentAvoid infinite loop around timed condition variable (diff)
downloadqemu-5d47e3728bbd589701f74bb494c9c9825ba23c88.tar.gz
qemu-5d47e3728bbd589701f74bb494c9c9825ba23c88.tar.xz
qemu-5d47e3728bbd589701f74bb494c9c9825ba23c88.zip
Avoid thundering herd problem
Broadcast was used so that the I/O threads would wakeup, reset their ts values and all but one go to sleep, in other words an optimization to prevent threads from exiting in presence of continuing I/O activity. Spurious wakeups make the looping around cond_timedwait with ever reinitialized ts potentially unsafe and as such ts in no longer reinitilized inside the loop, hence switch to signal is warranted and this benefits of this particlaur optimization are lost. (It's worth noting that timed variants of pthread calls use realtime clock by default, and therefore can hang "forever" should the host time be changed. Unfortunatelly not all host systems QEMU runs on support CLOCK_MONOTONIC and/or pthread_condattr_setclock with this value) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6632 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--posix-aio-compat.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/posix-aio-compat.c b/posix-aio-compat.c
index aa1b6f59c5..27b210cae1 100644
--- a/posix-aio-compat.c
+++ b/posix-aio-compat.c
@@ -61,10 +61,10 @@ static int cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
return ret;
}
-static void cond_broadcast(pthread_cond_t *cond)
+static void cond_signal(pthread_cond_t *cond)
{
- int ret = pthread_cond_broadcast(cond);
- if (ret) die2(ret, "pthread_cond_broadcast");
+ int ret = pthread_cond_signal(cond);
+ if (ret) die2(ret, "pthread_cond_signal");
}
static void thread_create(pthread_t *thread, pthread_attr_t *attr,
@@ -186,7 +186,7 @@ static int qemu_paio_submit(struct qemu_paiocb *aiocb, int is_write)
spawn_thread();
TAILQ_INSERT_TAIL(&request_list, aiocb, node);
mutex_unlock(&lock);
- cond_broadcast(&cond);
+ cond_signal(&cond);
return 0;
}