All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: hreitz@redhat.com, qemu-block@nongnu.org, qemu-devel@nongnu.org,
	Stefan Hajnoczi <stefanha@redhat.com>,
	sguelton@redhat.com
Subject: Re: [PATCH experiment 00/35] stackless coroutine backend
Date: Fri, 11 Mar 2022 12:17:06 +0000	[thread overview]
Message-ID: <Yis9wszzwwu2CGmZ@redhat.com> (raw)
In-Reply-To: <a92b23e8-e545-a43d-7283-6c6d215a10f8@redhat.com>

On Fri, Mar 11, 2022 at 01:04:33PM +0100, Paolo Bonzini wrote:
> On 3/11/22 10:27, Stefan Hajnoczi wrote:
> > > Not quite voluntarily, but I noticed I had to add one 0 to make them run for
> > > a decent amount of time.  So yeah, it's much faster than siglongjmp.
> > That's a nice first indication that performance will be good. I guess
> > that deep coroutine_fn stacks could be less efficient with stackless
> > coroutines compared to ucontext, but the cost of switching between
> > coroutines (enter/yield) will be lower with stackless coroutines.
> 
> Note that right now I'm not placing the coroutine_fn stack on the heap, it's
> still allocated from a contiguous area in virtual address space. The
> contiguous allocation is wrapped by coroutine_stack_alloc and
> coroutine_stack_free, so it's really easy to change them to malloc and free.
> 
> I also do not have to walk up the whole call stack on coroutine_fn yields,
> because calls from one coroutine_fn to the next are tail calls; in exchange
> for that, I have more indirect calls than if the code did
> 
>     if (next_call() == COROUTINE_YIELD) {
>         return COROUTINE_YIELD;
>     }
> 
> For now the choice was again just the one that made the translation easiest.
> 
> Today I also managed to implement a QEMU-like API on top of C++ coroutines:
> 
>     CoroutineFn<int> return_int() {
>         co_await qemu_coroutine_yield();
>         co_return 30;
>     }
> 
>     CoroutineFn<void> return_void() {
>         co_await qemu_coroutine_yield();
>     }
> 
>     CoroutineFn<void> co(void *) {
>         co_await return_void();
>         printf("%d\n", co_await return_int())
>         co_await qemu_coroutine_yield();
>     }
> 
>     int main() {
>         Coroutine *f = qemu_coroutine_create(co, NULL);
>         printf("--- 0\n");
>         qemu_coroutine_enter(f);
>         printf("--- 1\n");
>         qemu_coroutine_enter(f);
>         printf("--- 2\n");
>         qemu_coroutine_enter(f);
>         printf("--- 3\n");
>         qemu_coroutine_enter(f);
>         printf("--- 4\n");
>     }
> 
> The runtime code is absurdly obscure; my favorite bit is
> 
>     Yield qemu_coroutine_yield()
>     {
>         return Yield();
>     }
> 
> :) However, at 200 lines of code it's certainly smaller than a
> source-to-source translator.  It might be worth investigating a bit more.
> Only files that define or use a coroutine_fn (which includes callers of
> qemu_coroutine_create) would have to be compiled as C++.

Unless I'm misunderstanding what you mean, "define a coroutine_fn"
is a very large number of functions/files

  $ git grep coroutine_fn | wc -l
  806
  $ git grep -l coroutine_fn | wc -l
  132

Dominated by the block layer of course, but tentacles spreading
out into alot of other code.

Feels like identifying all callers would be tedious/unpleasant enough,
that practically speaking we would have to just compile all of QEMU
as C++.

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



  reply	other threads:[~2022-03-11 12:20 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-10 12:43 [PATCH experiment 00/35] stackless coroutine backend Paolo Bonzini
2022-03-10 12:43 ` [PATCH 01/35] coroutine: add missing coroutine_fn annotations for CoRwlock functions Paolo Bonzini
2022-03-10 12:43 ` [PATCH 02/35] coroutine: qemu_coroutine_get_aio_context is not a coroutine_fn Paolo Bonzini
2022-03-10 12:43 ` [PATCH 03/35] coroutine: introduce QemuCoLockable Paolo Bonzini
2022-03-10 12:43 ` [PATCH 04/35] coroutine: introduce coroutine_only_fn Paolo Bonzini
2022-03-10 12:43 ` [PATCH 05/35] coroutine: small code cleanup in qemu_co_rwlock_wrlock Paolo Bonzini
2022-03-10 14:10   ` Philippe Mathieu-Daudé
2022-03-10 12:43 ` [PATCH 06/35] disable some code Paolo Bonzini
2022-03-10 12:43 ` [PATCH 07/35] coroutine: introduce the "stackless coroutine" backend Paolo Bonzini
2022-03-10 12:43 ` [PATCH 08/35] /basic/lifecycle Paolo Bonzini
2022-03-10 12:43 ` [PATCH 09/35] convert qemu-coroutine-sleep.c to stackless coroutines Paolo Bonzini
2022-03-10 12:43 ` [PATCH 10/35] enable tail call optimization of qemu_co_mutex_lock Paolo Bonzini
2022-03-10 12:43 ` [PATCH 11/35] convert CoMutex to stackless coroutines Paolo Bonzini
2022-03-10 12:43 ` [PATCH 12/35] define magic macros for " Paolo Bonzini
2022-03-10 12:43 ` [PATCH 13/35] /basic/yield Paolo Bonzini
2022-03-10 12:43 ` [PATCH 14/35] /basic/nesting Paolo Bonzini
2022-03-10 12:43 ` [PATCH 15/35] /basic/self Paolo Bonzini
2022-03-10 12:43 ` [PATCH 16/35] /basic/entered Paolo Bonzini
2022-03-10 12:43 ` [PATCH 17/35] /basic/in_coroutine Paolo Bonzini
2022-03-10 12:43 ` [PATCH 18/35] /basic/order Paolo Bonzini
2022-03-10 12:43 ` [PATCH 19/35] /perf/lifecycle Paolo Bonzini
2022-03-10 12:43 ` [PATCH 20/35] /perf/nesting Paolo Bonzini
2022-03-10 12:43 ` [PATCH 21/35] /perf/yield Paolo Bonzini
2022-03-10 12:44 ` [PATCH 22/35] /perf/function-call Paolo Bonzini
2022-03-10 12:44 ` [PATCH 23/35] /perf/cost Paolo Bonzini
2022-03-10 12:44 ` [PATCH 24/35] /basic/no-dangling-access Paolo Bonzini
2022-03-10 12:44 ` [PATCH 25/35] /locking/co-mutex Paolo Bonzini
2022-03-10 12:44 ` [PATCH 26/35] convert qemu_co_mutex_lock_slowpath to magic macros Paolo Bonzini
2022-03-10 12:44 ` [PATCH 27/35] /locking/co-mutex/lockable Paolo Bonzini
2022-03-10 12:44 ` [PATCH 28/35] qemu_co_rwlock_maybe_wake_one Paolo Bonzini
2022-03-10 12:44 ` [PATCH 29/35] qemu_co_rwlock_rdlock Paolo Bonzini
2022-03-10 12:44 ` [PATCH 30/35] qemu_co_rwlock_unlock Paolo Bonzini
2022-03-10 12:44 ` [PATCH 31/35] qemu_co_rwlock_downgrade Paolo Bonzini
2022-03-10 12:44 ` [PATCH 32/35] qemu_co_rwlock_wrlock Paolo Bonzini
2022-03-10 12:44 ` [PATCH 33/35] qemu_co_rwlock_upgrade Paolo Bonzini
2022-03-10 12:44 ` [PATCH 34/35] /locking/co-rwlock/upgrade Paolo Bonzini
2022-03-10 12:44 ` [PATCH 35/35] /locking/co-rwlock/downgrade Paolo Bonzini
2022-03-10 17:42 ` [PATCH experiment 00/35] stackless coroutine backend Stefan Hajnoczi
2022-03-10 20:14   ` Paolo Bonzini
2022-03-11  9:27     ` Stefan Hajnoczi
2022-03-11 12:04       ` Paolo Bonzini
2022-03-11 12:17         ` Daniel P. Berrangé [this message]
2022-03-13 15:18           ` Paolo Bonzini
2022-03-14 13:43             ` 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=Yis9wszzwwu2CGmZ@redhat.com \
    --to=berrange@redhat.com \
    --cc=hreitz@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=sguelton@redhat.com \
    --cc=stefanha@redhat.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.