AioContext: acquire/release AioContext during aio_poll

This is the first step in pushing down acquire/release, and will let
rfifolock drop the contention callback feature.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1424449612-18215-3-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Paolo Bonzini 2015-02-20 17:26:51 +01:00 committed by Kevin Wolf
parent e98ab09709
commit 49110174f8
3 changed files with 24 additions and 6 deletions

View File

@ -238,6 +238,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
bool progress; bool progress;
int64_t timeout; int64_t timeout;
aio_context_acquire(ctx);
was_dispatching = ctx->dispatching; was_dispatching = ctx->dispatching;
progress = false; progress = false;
@ -267,7 +268,13 @@ bool aio_poll(AioContext *ctx, bool blocking)
timeout = blocking ? aio_compute_timeout(ctx) : 0; timeout = blocking ? aio_compute_timeout(ctx) : 0;
/* wait until next event */ /* wait until next event */
if (timeout) {
aio_context_release(ctx);
}
ret = qemu_poll_ns((GPollFD *)pollfds, npfd, timeout); ret = qemu_poll_ns((GPollFD *)pollfds, npfd, timeout);
if (timeout) {
aio_context_acquire(ctx);
}
/* if we have any readable fds, dispatch event */ /* if we have any readable fds, dispatch event */
if (ret > 0) { if (ret > 0) {
@ -286,5 +293,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
} }
aio_set_dispatching(ctx, was_dispatching); aio_set_dispatching(ctx, was_dispatching);
aio_context_release(ctx);
return progress; return progress;
} }

View File

@ -283,6 +283,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
int count; int count;
int timeout; int timeout;
aio_context_acquire(ctx);
have_select_revents = aio_prepare(ctx); have_select_revents = aio_prepare(ctx);
if (have_select_revents) { if (have_select_revents) {
blocking = false; blocking = false;
@ -323,7 +324,13 @@ bool aio_poll(AioContext *ctx, bool blocking)
timeout = blocking timeout = blocking
? qemu_timeout_ns_to_ms(aio_compute_timeout(ctx)) : 0; ? qemu_timeout_ns_to_ms(aio_compute_timeout(ctx)) : 0;
if (timeout) {
aio_context_release(ctx);
}
ret = WaitForMultipleObjects(count, events, FALSE, timeout); ret = WaitForMultipleObjects(count, events, FALSE, timeout);
if (timeout) {
aio_context_acquire(ctx);
}
aio_set_dispatching(ctx, true); aio_set_dispatching(ctx, true);
if (first && aio_bh_poll(ctx)) { if (first && aio_bh_poll(ctx)) {
@ -349,5 +356,6 @@ bool aio_poll(AioContext *ctx, bool blocking)
progress |= timerlistgroup_run_timers(&ctx->tlg); progress |= timerlistgroup_run_timers(&ctx->tlg);
aio_set_dispatching(ctx, was_dispatching); aio_set_dispatching(ctx, was_dispatching);
aio_context_release(ctx);
return progress; return progress;
} }

View File

@ -118,13 +118,14 @@ void aio_context_ref(AioContext *ctx);
void aio_context_unref(AioContext *ctx); void aio_context_unref(AioContext *ctx);
/* Take ownership of the AioContext. If the AioContext will be shared between /* Take ownership of the AioContext. If the AioContext will be shared between
* threads, a thread must have ownership when calling aio_poll(). * threads, and a thread does not want to be interrupted, it will have to
* take ownership around calls to aio_poll(). Otherwise, aio_poll()
* automatically takes care of calling aio_context_acquire and
* aio_context_release.
* *
* Note that multiple threads calling aio_poll() means timers, BHs, and * Access to timers and BHs from a thread that has not acquired AioContext
* callbacks may be invoked from a different thread than they were registered * is possible. Access to callbacks for now must be done while the AioContext
* from. Therefore, code must use AioContext acquire/release or use * is owned by the thread (FIXME).
* fine-grained synchronization to protect shared state if other threads will
* be accessing it simultaneously.
*/ */
void aio_context_acquire(AioContext *ctx); void aio_context_acquire(AioContext *ctx);