From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38004) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VExrm-0000M2-5C for qemu-devel@nongnu.org; Thu, 29 Aug 2013 04:46:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VExrd-0004MX-Lw for qemu-devel@nongnu.org; Thu, 29 Aug 2013 04:46:10 -0400 Received: from mail-ee0-x22f.google.com ([2a00:1450:4013:c00::22f]:40203) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VExrd-0004MO-Dg for qemu-devel@nongnu.org; Thu, 29 Aug 2013 04:46:01 -0400 Received: by mail-ee0-f47.google.com with SMTP id d49so77903eek.34 for ; Thu, 29 Aug 2013 01:45:59 -0700 (PDT) Sender: Paolo Bonzini Message-ID: <521F05B7.9000203@redhat.com> Date: Thu, 29 Aug 2013 10:26:31 +0200 From: Paolo Bonzini MIME-Version: 1.0 References: <1377614385-20466-1-git-send-email-stefanha@redhat.com> In-Reply-To: <1377614385-20466-1-git-send-email-stefanha@redhat.com> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [RFC] aio: add aio_context_acquire() and aio_context_release() List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Stefan Hajnoczi Cc: Kevin Wolf , qemu-devel@nongnu.org, Wenchao Xia Il 27/08/2013 16:39, Stefan Hajnoczi ha scritto: > +void aio_context_acquire(AioContext *ctx) > +{ > + qemu_mutex_lock(&ctx->acquire_lock); > + while (ctx->owner) { > + assert(!qemu_thread_is_self(ctx->owner)); > + aio_notify(ctx); /* kick current owner */ > + qemu_cond_wait(&ctx->acquire_cond, &ctx->acquire_lock); > + } > + qemu_thread_get_self(&ctx->owner_thread); > + ctx->owner = &ctx->owner_thread; > + qemu_mutex_unlock(&ctx->acquire_lock); > +} > + > +void aio_context_release(AioContext *ctx) > +{ > + qemu_mutex_lock(&ctx->acquire_lock); > + assert(ctx->owner && qemu_thread_is_self(ctx->owner)); > + ctx->owner = NULL; > + qemu_cond_signal(&ctx->acquire_cond); > + qemu_mutex_unlock(&ctx->acquire_lock); > +} Thinking more about it, there is a risk of busy waiting here if one thread releases the AioContext and tries to acquire it again (as in the common case of one thread doing acquire/poll/release in a loop). It would only work if mutexes guarantee some level of fairness. If you implement recursive acquisition, however, you can make aio_poll acquire the context up until just before it invokes ppoll, and then again after it comes back from the ppoll. The two acquire/release pair will be no-ops if called during "synchronous" I/O such as /* Another thread */ aio_context_acquire(ctx); bdrv_read(bs, 0x1000, buf, 1); aio_context_release(ctx); Yet they will do the right thing when called from the event loop thread. (where the bdrv_read can actually be something more complicated such as a live snapshot or, in general, anything involving bdrv_drain_all). Paolo