qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Anthony Liguori <anthony@codemonkey.ws>
To: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Cc: Kevin Wolf <kwolf@redhat.com>,
	Anthony Liguori <aliguori@us.ibm.com>,
	qemu-devel@nongnu.org, Blue Swirl <blauwirbel@gmail.com>,
	"Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>,
	Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
Subject: Re: [Qemu-devel] [PATCH v7 2/4] coroutine: implement coroutines using gthread
Date: Mon, 25 Jul 2011 15:38:01 -0500	[thread overview]
Message-ID: <4E2DD429.7010301@codemonkey.ws> (raw)
In-Reply-To: <1311624250-1670-3-git-send-email-stefanha@linux.vnet.ibm.com>

On 07/25/2011 03:04 PM, Stefan Hajnoczi wrote:
> From: "Aneesh Kumar K.V"<aneesh.kumar@linux.vnet.ibm.com>
>
> On platforms that don't support makecontext(3) use gthread based
> coroutine implementation.
>
> Darwin has makecontext(3) but getcontext(3) is stubbed out to return
> ENOTSUP.  Andreas Färber<andreas.faerber@web.de>  debugged this and
> contributed the ./configure test which solves the issue for Darwin/ppc64
> (and ppc) v10.5.
>
> [Original patch by Aneesh, made consistent with coroutine-ucontext.c and
> switched to GStaticPrivate by Stefan.  Tested on Linux and OpenBSD.]
>
> Signed-off-by: Aneesh Kumar K.V<aneesh.kumar@linux.vnet.ibm.com>
> Signed-off-by: Stefan Hajnoczi<stefanha@linux.vnet.ibm.com>
> ---
>   Makefile.objs       |    4 ++
>   configure           |   18 +++++++
>   coroutine-gthread.c |  131 +++++++++++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 153 insertions(+), 0 deletions(-)
>   create mode 100644 coroutine-gthread.c
>
> diff --git a/Makefile.objs b/Makefile.objs
> index 28e1762..5679e1f 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -13,7 +13,11 @@ oslib-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o
>   #######################################################################
>   # coroutines
>   coroutine-obj-y = qemu-coroutine.o
> +ifeq ($(CONFIG_UCONTEXT_COROUTINE),y)
>   coroutine-obj-$(CONFIG_POSIX) += coroutine-ucontext.o
> +else
> +coroutine-obj-$(CONFIG_POSIX) += coroutine-gthread.o
> +endif
>   coroutine-obj-$(CONFIG_WIN32) += coroutine-win32.o
>
>   #######################################################################
> diff --git a/configure b/configure
> index 600da9b..1b6ad87 100755
> --- a/configure
> +++ b/configure
> @@ -2499,6 +2499,20 @@ if test "$trace_backend" = "dtrace"; then
>   fi
>
>   ##########################################
> +# check if we have makecontext
> +
> +ucontext_coroutine=no
> +if test "$darwin" != "yes"; then
> +  cat>  $TMPC<<  EOF
> +#include<ucontext.h>
> +int main(void) { makecontext(0, 0, 0); }
> +EOF
> +  if compile_prog "" "" ; then
> +      ucontext_coroutine=yes
> +  fi
> +fi
> +

Doesn't this make the build non-bisectable on platforms that don't have 
makecontext?  I think the gthread patch needs to come first and then the 
ucontext version can be used on platforms that we detect it's there.

Regards,

Anthony Liguori

> +##########################################
>   # End of CC checks
>   # After here, no more $cc or $ld runs
>
> @@ -2970,6 +2984,10 @@ if test "$rbd" = "yes" ; then
>     echo "CONFIG_RBD=y">>  $config_host_mak
>   fi
>
> +if test "$ucontext_coroutine" = "yes" ; then
> +  echo "CONFIG_UCONTEXT_COROUTINE=y">>  $config_host_mak
> +fi
> +
>   # USB host support
>   case "$usb" in
>   linux)
> diff --git a/coroutine-gthread.c b/coroutine-gthread.c
> new file mode 100644
> index 0000000..f09877e
> --- /dev/null
> +++ b/coroutine-gthread.c
> @@ -0,0 +1,131 @@
> +/*
> + * GThread coroutine initialization code
> + *
> + * Copyright (C) 2006  Anthony Liguori<anthony@codemonkey.ws>
> + * Copyright (C) 2011  Aneesh Kumar K.V<aneesh.kumar@linux.vnet.ibm.com>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.0 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see<http://www.gnu.org/licenses/>.
> + */
> +
> +#include<glib.h>
> +#include "qemu-common.h"
> +#include "qemu-coroutine-int.h"
> +
> +typedef struct {
> +    Coroutine base;
> +    GThread *thread;
> +    bool runnable;
> +    CoroutineAction action;
> +} CoroutineGThread;
> +
> +static GCond *coroutine_cond;
> +static GStaticMutex coroutine_lock = G_STATIC_MUTEX_INIT;
> +static GStaticPrivate coroutine_key = G_STATIC_PRIVATE_INIT;
> +
> +static void __attribute__((constructor)) coroutine_init(void)
> +{
> +    if (!g_thread_supported()) {
> +        g_thread_init(NULL);
> +    }
> +
> +    coroutine_cond = g_cond_new();
> +}
> +
> +static void coroutine_wait_runnable_locked(CoroutineGThread *co)
> +{
> +    while (!co->runnable) {
> +        g_cond_wait(coroutine_cond, g_static_mutex_get_mutex(&coroutine_lock));
> +    }
> +}
> +
> +static void coroutine_wait_runnable(CoroutineGThread *co)
> +{
> +    g_static_mutex_lock(&coroutine_lock);
> +    coroutine_wait_runnable_locked(co);
> +    g_static_mutex_unlock(&coroutine_lock);
> +}
> +
> +static gpointer coroutine_thread(gpointer opaque)
> +{
> +    CoroutineGThread *co = opaque;
> +
> +    g_static_private_set(&coroutine_key, co, NULL);
> +    coroutine_wait_runnable(co);
> +    co->base.entry(co->base.entry_arg);
> +    qemu_coroutine_switch(&co->base, co->base.caller, COROUTINE_TERMINATE);
> +    return NULL;
> +}
> +
> +Coroutine *qemu_coroutine_new(void)
> +{
> +    CoroutineGThread *co;
> +
> +    co = qemu_mallocz(sizeof(*co));
> +    co->thread = g_thread_create_full(coroutine_thread, co, 0, TRUE, TRUE,
> +                                      G_THREAD_PRIORITY_NORMAL, NULL);
> +    if (!co->thread) {
> +        qemu_free(co);
> +        return NULL;
> +    }
> +    return&co->base;
> +}
> +
> +void qemu_coroutine_delete(Coroutine *co_)
> +{
> +    CoroutineGThread *co = DO_UPCAST(CoroutineGThread, base, co_);
> +
> +    g_thread_join(co->thread);
> +    qemu_free(co);
> +}
> +
> +CoroutineAction qemu_coroutine_switch(Coroutine *from_,
> +                                      Coroutine *to_,
> +                                      CoroutineAction action)
> +{
> +    CoroutineGThread *from = DO_UPCAST(CoroutineGThread, base, from_);
> +    CoroutineGThread *to = DO_UPCAST(CoroutineGThread, base, to_);
> +
> +    g_static_mutex_lock(&coroutine_lock);
> +    from->runnable = false;
> +    from->action = action;
> +    to->runnable = true;
> +    to->action = action;
> +    g_cond_broadcast(coroutine_cond);
> +
> +    if (action != COROUTINE_TERMINATE) {
> +        coroutine_wait_runnable_locked(from);
> +    }
> +    g_static_mutex_unlock(&coroutine_lock);
> +    return from->action;
> +}
> +
> +Coroutine *qemu_coroutine_self(void)
> +{
> +    CoroutineGThread *co = g_static_private_get(&coroutine_key);
> +
> +    if (!co) {
> +        co = qemu_mallocz(sizeof(*co));
> +        co->runnable = true;
> +        g_static_private_set(&coroutine_key, co, (GDestroyNotify)qemu_free);
> +    }
> +
> +    return&co->base;
> +}
> +
> +bool qemu_in_coroutine(void)
> +{
> +    CoroutineGThread *co = g_static_private_get(&coroutine_key);
> +
> +    return co&&  co->base.caller;
> +}

  reply	other threads:[~2011-07-25 20:38 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-07-25 20:04 [Qemu-devel] [PATCH v7 0/4] Coroutines for better asynchronous programming Stefan Hajnoczi
2011-07-25 20:04 ` [Qemu-devel] [PATCH v7 1/4] coroutine: introduce coroutines Stefan Hajnoczi
2011-07-25 20:04 ` [Qemu-devel] [PATCH v7 2/4] coroutine: implement coroutines using gthread Stefan Hajnoczi
2011-07-25 20:38   ` Anthony Liguori [this message]
2011-07-26  9:22     ` Stefan Hajnoczi
2011-07-25 20:04 ` [Qemu-devel] [PATCH v7 3/4] coroutine: add test-coroutine automated tests Stefan Hajnoczi
2011-07-25 20:04 ` [Qemu-devel] [PATCH v7 4/4] coroutine: add test-coroutine --benchmark-lifecycle Stefan Hajnoczi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4E2DD429.7010301@codemonkey.ws \
    --to=anthony@codemonkey.ws \
    --cc=aliguori@us.ibm.com \
    --cc=aneesh.kumar@linux.vnet.ibm.com \
    --cc=blauwirbel@gmail.com \
    --cc=jvrao@linux.vnet.ibm.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).