From: Paolo Bonzini <pbonz...@redhat.com> Threads that run event loops also have places that can sleep for an extended time. Place an extended quiescent state there.
Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> Reviewed-by: Mike Day <ncm...@ncultra.org> --- aio-posix.c | 9 ++++++++- aio-win32.c | 7 +++++++ main-loop.c | 7 ++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/aio-posix.c b/aio-posix.c index b68eccd..562add6 100644 --- a/aio-posix.c +++ b/aio-posix.c @@ -17,6 +17,7 @@ #include "block/block.h" #include "qemu/queue.h" #include "qemu/sockets.h" +#include "qemu/rcu.h" struct AioHandler { @@ -232,10 +233,16 @@ bool aio_poll(AioContext *ctx, bool blocking) } /* wait until next event */ + if (blocking) { + rcu_thread_offline(); + } ret = g_poll((GPollFD *)ctx->pollfds->data, ctx->pollfds->len, blocking ? -1 : 0); - + if (blocking) { + rcu_thread_online(); + } + /* if we have any readable fds, dispatch event */ if (ret > 0) { QLIST_FOREACH(node, &ctx->aio_handlers, node) { diff --git a/aio-win32.c b/aio-win32.c index 38723bf..8a6abb0 100644 --- a/aio-win32.c +++ b/aio-win32.c @@ -175,7 +175,14 @@ bool aio_poll(AioContext *ctx, bool blocking) /* wait until next event */ while (count > 0) { int timeout = blocking ? INFINITE : 0; + + if (timeout) { + rcu_thread_offline(); + } int ret = WaitForMultipleObjects(count, events, FALSE, timeout); + if (timeout) { + rcu_thread_online(); + } /* if we have any signaled events, dispatch event */ if ((DWORD) (ret - WAIT_OBJECT_0) >= count) { diff --git a/main-loop.c b/main-loop.c index a44fff6..79f43da 100644 --- a/main-loop.c +++ b/main-loop.c @@ -27,6 +27,7 @@ #include "qemu/sockets.h" // struct in_addr needed for libslirp.h #include "slirp/libslirp.h" #include "qemu/main-loop.h" +#include "qemu/rcu.h" #include "block/aio.h" #ifndef _WIN32 @@ -220,6 +221,7 @@ static int os_host_main_loop_wait(uint32_t timeout) if (timeout > 0) { spin_counter = 0; qemu_mutex_unlock_iothread(); + rcu_thread_offline(); } else { spin_counter++; } @@ -227,7 +229,8 @@ static int os_host_main_loop_wait(uint32_t timeout) ret = g_poll((GPollFD *)gpollfds->data, gpollfds->len, timeout); if (timeout > 0) { - qemu_mutex_lock_iothread(); + rcu_thread_online(); + qemu_mutex_lock_iothread(); } glib_pollfds_poll(); @@ -424,7 +427,9 @@ static int os_host_main_loop_wait(uint32_t timeout) } qemu_mutex_unlock_iothread(); + rcu_thread_offline(); g_poll_ret = g_poll(poll_fds, n_poll_fds + w->num, poll_timeout); + rcu_thread_online(); qemu_mutex_lock_iothread(); if (g_poll_ret > 0) { for (i = 0; i < w->num; i++) { -- 1.8.3.1