qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH experiment 00/35] stackless coroutine backend


From: Paolo Bonzini
Subject: Re: [PATCH experiment 00/35] stackless coroutine backend
Date: Sun, 13 Mar 2022 16:18:40 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.5.0

On 3/11/22 13:17, Daniel P. Berrangé wrote:
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.

The main other user is 9pfs, then there is:

hw/remote/message.c
io/channel.c
job.c
migration/savevm.c
monitor/hmp-cmds.c
monitor/monitor-internal.h
monitor/qmp.c
nbd/client-connection.c
nbd/client.c
nbd/server.c
net/colo-compare.c
net/filter-mirror.c
scsi/pr-manager.c
scsi/qemu-pr-helper.c
ui/console.c
util/vhost-user-server.c

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

Yes, it's a large amount of code, but it's relatively self-contained. In io/ for example only three functions would have to become C++ (qio_channel_readv_full_all_eof, qio_channel_writev_full_all, qio_channel_yield), and it's easy to move them to a separate file io/channel-coroutine.cc.

Likewise for e.g. util/async.c or util/thread-pool.c (one function each).

The block layer would almost entirely move to C++, that's for sure. The monitor would be a bit more in the middle, but hardware emulation can remain 100% C.

I haven't gotten the thing to compile or run yet, and I'm not sure how much time I'll have this week, but the change for test-coroutine.c to run should be in the ballpark of this:

 include/qemu/coroutine.h                                 |  26
 tests/unit/meson.build                                   |   6
 tests/unit/{test-coroutine.c => test-coroutine.cc}       | 106
 util/meson.build                                         |   4
 util/{qemu-coroutine-lock.c => qemu-coroutine-lock.cc}   |  65
 util/{qemu-coroutine-sleep.c => qemu-coroutine-sleep.cc} |  10

where the changes are for a good part mechanical: switching from "x coroutine_fn" to CoroutineFn<x> entirely so, while adding co_await in front of coroutine calls is half mechanical. For non-void functions, the compiler can identify all callers (because the old type "int" is not compatible with the new type CoroutineFn<int>). For void function one could use warn_unused_result.

The question is what is easier to maintain, stack switching code that is becoming less and less portable (status quo with SafeStack, CET and the TLS issues that Stefan has worked on), a mixed C/C++ codebase (C++ coroutines), a custom source-to-source translator (this series). The third might be more fun, but it would be quite a large enterprise and the C++ compiler writers have already done the work.

A part of the changes is common in both cases, since you cannot have code that can run both inside or outside a coroutine.

Paolo



reply via email to

[Prev in Thread] Current Thread [Next in Thread]