Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-31 Thread Markus Armbruster
Daniel P. Berrangé  writes:

> On Tue, Mar 15, 2022 at 03:50:26PM +0100, Kevin Wolf wrote:

[...]

>> ...using C++ in coroutine code means that all of the block layer would
>> suddenly become C++ and would be most affected by this effect. I'm not
>> sure if that's something I would like to see, at least until there is a
>> clear tree-wide policy (that preferably limits it to a subset that I
>> understand).
>
> Expecting maintainers to enforce a subset during code review feels
> like it would be a tedious burden, that will inevitably let stuff
> through because humans are fallible, especially when presented
> with uninspiring, tedious, repetitive tasks.
>
> Restricting ourselves to a subset is only viable if we have
> an automated tool that can reliably enforce that subset.

Concur.  We're talking about a complex subset of an even more complex
whole, where few to none of us will fully understand either.

>  I'm not
> sure that any such tool exists, and not convinced our time is
> best served by trying to write & maintainer one either.
>
> IOW, I fear one we allow C++ in any level, it won't be practical
> to constrain it as much we desire. I fear us turning QEMU into
> even more of a monster like other big C++ apps I see which take
> all hours to compile while using all available RAM in Fedora RPM
> build hosts.

While I'm certainly concerned about the often poor ergonomics of
compiling C++ code, I'm even more concerned about the poor ergonomics of
*grokking* C++ code.

> My other question is whether adoption of C++ would complicate any
> desire to make more use of Rust in QEMU ? I know Rust came out of
> work by the Mozilla Firefox crew, and Firefox was C++, but I don't
> have any idea how they integrated use of Rust with Firefox, so
> whether there are any gotcha's for us or not ?

Good question.




Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-31 Thread Markus Armbruster
Hanna Reitz  writes:

> On 17.03.22 16:11, Paolo Bonzini wrote:
>> On 3/16/22 13:32, Stefan Hajnoczi wrote:
>>> You can define rules and a way to enforce a subset of C++, but I think
>>> over time the code will be C++. A policy that is complicated discourages
>>> contributors.
>>>
>>> For these reasons I think that if code runs through a C++ compiler we
>>> should just allow C++. Either way, it will take time but that way no one
>>> will feel betrayed when C++ creeps in.
>>
>> Fair enough.  We even already have some conventions that will make
>> any C++ that creeps in less weird (for example, mandatory typedef of 
>> structs).
>>
>> I don't think it would be a big deal overall.  I actually agree that
>> we should "just allow C++", what matters more to have style rules
>> that make QEMU's flavors of C and C++ consistent.
>
> I just want to throw in that I personally am absolutely not confident
> in reviewing C++ code.

Me neither.

> As for Rust, you keep mentioning that we don’t
> have anyone who would “shepherd us through the learning experience”,
> but I find the very same argument applies to C++.
>
> C++ may start out looking like C, but if used ideally, then it is a
> very different language, too.  I understand the difference is that we
> can incrementally convert our C code to C++,

Bad C++ in need of rework, presumably.

>  but I’m not comfortable 
> overseeing that process, which I would have to do as a maintainer. 

That makes two of us.

The plain language version of "I'm not comfortable serving" is of course
"I do not intend to serve".

> Assuming our overall stance does change to “just allowing C++”, I’d
> feel unjust if I were to reject C++isms just based on the fact that I
> don’t know C++, so I’d be forced to learn C++.  I’m not strictly
> opposed to that (though from experience I’m more than hesitant), but
> forcing maintainers to learn C++ is something that has a cost
> associated with it.

I'm a lot more interested in learning Rust than in (re-)learning C++.

> My biggest gripe about C++ is that as far as I understand there are
> many antipatterns, many of which I think stem from the exact fact that
> it is kind of compatible with C, and so you can easily accidentally
> write really bad C++ code; but without years of experience, I’m
> absolutely not confident that I could recognize them.  Now, I might
> say I’d just disallow complicated stuff, and keep everything C-like,
> but from what I’ve heard, C-like C++ seems to be exactly one case that
> is considered bad C++.  I’m really under the impression that I’d need
> years of experience to discern good from bad C++, and I don’t have
> that experience.

Right.




Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-17 Thread Hanna Reitz

On 17.03.22 16:11, Paolo Bonzini wrote:

On 3/16/22 13:32, Stefan Hajnoczi wrote:

You can define rules and a way to enforce a subset of C++, but I think
over time the code will be C++. A policy that is complicated discourages
contributors.

For these reasons I think that if code runs through a C++ compiler we
should just allow C++. Either way, it will take time but that way no one
will feel betrayed when C++ creeps in.


Fair enough.  We even already have some conventions that will make any 
C++ that creeps in less weird (for example, mandatory typedef of 
structs).


I don't think it would be a big deal overall.  I actually agree that 
we should "just allow C++", what matters more to have style rules that 
make QEMU's flavors of C and C++ consistent.


I just want to throw in that I personally am absolutely not confident in 
reviewing C++ code.  As for Rust, you keep mentioning that we don’t have 
anyone who would “shepherd us through the learning experience”, but I 
find the very same argument applies to C++.


C++ may start out looking like C, but if used ideally, then it is a very 
different language, too.  I understand the difference is that we can 
incrementally convert our C code to C++, but I’m not comfortable 
overseeing that process, which I would have to do as a maintainer.  
Assuming our overall stance does change to “just allowing C++”, I’d feel 
unjust if I were to reject C++isms just based on the fact that I don’t 
know C++, so I’d be forced to learn C++.  I’m not strictly opposed to 
that (though from experience I’m more than hesitant), but forcing 
maintainers to learn C++ is something that has a cost associated with it.


My biggest gripe about C++ is that as far as I understand there are many 
antipatterns, many of which I think stem from the exact fact that it is 
kind of compatible with C, and so you can easily accidentally write 
really bad C++ code; but without years of experience, I’m absolutely not 
confident that I could recognize them.  Now, I might say I’d just 
disallow complicated stuff, and keep everything C-like, but from what 
I’ve heard, C-like C++ seems to be exactly one case that is considered 
bad C++.  I’m really under the impression that I’d need years of 
experience to discern good from bad C++, and I don’t have that experience.


Hanna




Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-17 Thread Paolo Bonzini

On 3/16/22 13:32, Stefan Hajnoczi wrote:

You can define rules and a way to enforce a subset of C++, but I think
over time the code will be C++. A policy that is complicated discourages
contributors.

For these reasons I think that if code runs through a C++ compiler we
should just allow C++. Either way, it will take time but that way no one
will feel betrayed when C++ creeps in.


Fair enough.  We even already have some conventions that will make any 
C++ that creeps in less weird (for example, mandatory typedef of structs).


I don't think it would be a big deal overall.  I actually agree that we 
should "just allow C++", what matters more to have style rules that make 
QEMU's flavors of C and C++ consistent.


Most files are leaves (i.e. they just expose an interface via 
type_init/block_init/etc.), where almost always people will copy from 
something that already exists and which will be C.  What matters are the 
core APIs, and maintainers have way more authority there to say no to 
code they're not comfortable reviewing.  This way, code within a 
subsystem will keep some consistency.


Paolo



Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-17 Thread Daniel P . Berrangé
On Wed, Mar 16, 2022 at 12:08:33AM +0100, Paolo Bonzini wrote:
> On 3/15/22 16:55, Daniel P. Berrangé wrote:
> > Expecting maintainers to enforce a subset during code review feels
> > like it would be a tedious burden, that will inevitably let stuff
> > through because humans are fallible, especially when presented
> > with uninspiring, tedious, repetitive tasks.
> > 
> > Restricting ourselves to a subset is only viable if we have
> > an automated tool that can reliably enforce that subset. I'm not
> > sure that any such tool exists, and not convinced our time is
> > best served by trying to write & maintainer one either.
> 
> We don't need to have a policy on which features are used.  We need to have
> goals for what to use C++ for.  I won't go into further details here,
> because I had already posted "When and how to use C++"[1] about an hour
> before your reply.

I see that mail, but I don't think it addresses my point.

We already use GLib and it provides a bunch of data structures,
objects and APIs, alot of which will overlap with C++ standard
library, not to mention QEMU's own stuff that predates GLib.

The guidelines say what we want to use C++ for which fine, but
it doesn't help maintainers/reviewers evaluating whether the
proposed C++ usage is desired.

Do we prefer GLib APIs and data structures for consistency &
interoperability with remaining C-only code, or do we prefer
the libstdc++, or do we allow both but set rules on when
to use each, or do we allow a free-for-all with author or
reviewer deciding based on their personal preference.

If we don't have a policy for C++ feature usage, then we
get the free-for-all by default. May be that is OK, maybe
not. Either way we need to declare our intent, so reviewers
know what to complain about and what to not.

Personally I'm not a fan of having a codebase with many
different APIs/data structures for doing the same job,
so would like a clear policy for what to use / prefer,
ideally one we can enforce with tools rather than rely
on humans to spot.


> > IOW, I fear one we allow C++ in any level, it won't be practical
> > to constrain it as much we desire. I fear us turning QEMU into
> > even more of a monster like other big C++ apps I see which take
> > all hours to compile while using all available RAM in Fedora RPM
> > build hosts.
> 
> Sorry but this is FUD.  There's plenty of C++ apps and libraries that do not
> "take hours to compile while using all available RAM".  You're probably
> thinking of the Chromium/Firefox/Libreoffice triplet but those are an order
> of magnitude larger than QEMU.  And in fact, QEMU is *already* a monster
> that takes longer to compile than most other packages, no matter the
> language they're written in.

I was particularly considering Ceph when I wrote the above, which
is bigger, but still a similar order of magnutude in size compared
to QEMU, but in Fedora Ceph takes 12 hours to compile on the slower
arch, vs QEMU's 3 hrs, or 3 hrs on x86_64 vs QEMU's 1 hr. Maybe I'm
being mistaken in blaming C++ in general, and it is something else
Or maybe certain features trigger this slowness and we can consider
if we should stay away from them

With 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 :|




Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-17 Thread Dr. David Alan Gilbert
* Paolo Bonzini (pbonz...@redhat.com) wrote:
> On 3/15/22 16:55, Daniel P. Berrangé wrote:
> > Expecting maintainers to enforce a subset during code review feels
> > like it would be a tedious burden, that will inevitably let stuff
> > through because humans are fallible, especially when presented
> > with uninspiring, tedious, repetitive tasks.
> > 
> > Restricting ourselves to a subset is only viable if we have
> > an automated tool that can reliably enforce that subset. I'm not
> > sure that any such tool exists, and not convinced our time is
> > best served by trying to write & maintainer one either.
> 
> We don't need to have a policy on which features are used.  We need to have
> goals for what to use C++ for.  I won't go into further details here,
> because I had already posted "When and how to use C++"[1] about an hour
> before your reply.
> 
> > IOW, I fear one we allow C++ in any level, it won't be practical
> > to constrain it as much we desire. I fear us turning QEMU into
> > even more of a monster like other big C++ apps I see which take
> > all hours to compile while using all available RAM in Fedora RPM
> > build hosts.
> 
> Sorry but this is FUD.  There's plenty of C++ apps and libraries that do not
> "take hours to compile while using all available RAM".  You're probably
> thinking of the Chromium/Firefox/Libreoffice triplet but those are an order
> of magnitude larger than QEMU.  And in fact, QEMU is *already* a monster
> that takes longer to compile than most other packages, no matter the
> language they're written in.
> 
> Most of KDE and everything that uses Qt is written in C++, and so is
> Inkscape in GTK+ land.  LLVM and Clang are written in C++.  Hotspot and V8
> are written in C++.  Kodi, MAME and DolphinEmu are written in C++. GCC and
> GDB have migrated to C++ and their compile times have not exploded.

While I think it does take longer to compile, the bigger problem for
the CI setup is the amount of RAM-per-compile-process; it's not so much
the fact that those applications are huge that's the problem, it's that
a make -j ($threads) can run out of RAM.

Dave

> > My other question is whether adoption of C++ would complicate any
> > desire to make more use of Rust in QEMU ? I know Rust came out of
> > work by the Mozilla Firefox crew, and Firefox was C++, but I don't
> > have any idea how they integrated use of Rust with Firefox, so
> > whether there are any gotcha's for us or not ?
> 
> Any Rust integration would go through C APIs.  Using Rust in the block layer
> would certainly be much harder, though perhaps not impossible, if the block
> layer uses C++ coroutines.  Rust supports something similar, but
> two-direction interoperability would be hard.
> 
> For everything else, not much.  Even if using C++, the fact that QEMU's APIs
> are primarily C would not change.  Changing "timer_mod_ns(timer, ns)" to
> "timer.modify_ns(ns)" is not on the table.
> 
> But really, first of all the question should be who is doing work on
> integrating Rust with QEMU.  I typically hear about this topic exactly once
> a year at KVM Forum, and then nothing.  We have seen Marc-André's QAPI
> integration experiment, but it's not clear to me what the path would be from
> there to wider use in QEMU.
> 
> In particular, after ~3 years of talking about it, it is not even clear:
> 
> - what subsystems would benefit the most from the adoption of Rust, and
> whether that would be feasible without a rewrite which will simply never
> happen
> 
> - what the plans would be for coexistence of Rust and C code within a
> subsystem
> 
> - whether maintainers would be on board with adopting a completely different
> language, and who in the community has enough Rust experience to shepherd us
> through the learning experience
> 
> The first two questions have answers in the other message if s/Rust/C++/,
> and as to the last I think we're already further in the discussion.
> 
> Thanks,
> 
> Paolo
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-16 Thread Stefan Hajnoczi
On Wed, Mar 16, 2022 at 01:06:02PM +, Daniel P. Berrangé wrote:
> On Wed, Mar 16, 2022 at 12:32:48PM +, Stefan Hajnoczi wrote:
> > On Tue, Mar 15, 2022 at 06:29:50PM +0100, Paolo Bonzini wrote:
> > > On 3/15/22 15:24, Peter Maydell wrote:
> > > > On Tue, 15 Mar 2022 at 14:09, Stefan Hajnoczi  
> > > > wrote:
> > > > > Also, once C++ is available people will
> > > > > start submitting C++ patches simply because they are more comfortable
> > > > > with C++ (especially one-time/infrequent contributors).
> > > > 
> > > > This to my mind is the major argument against using C++
> > > > for coroutines...
> > > 
> > > I agree on the need for a policy, but _what_ C++ are they going to be
> > > contributing that we should be scared of?  We're talking about:
> > > 
> > > * major features contributed by one-time/infrequent participants (which is
> > > already a once-in-a-year thing or so, at least for me)
> > > 
> > > * ... in an area where there are no examples of using C++ in the tree (or
> > > presumably the maintainer would be comfortable reviewing it)
> > > 
> > > * ... but yet C++ offer killer features (right now there's only C++
> > > coroutines and fpu/)
> > 
> > You are assuming people only choose C++ only when it offers features not
> > available in C. I think they might simply be more comfortable in C++.
> > 
> > In other words, if an existing file is compiled using a C++ compiler or
> > they are adding a new file, they don't need a reason to use C++, they
> > can just use it.
> > 
> > You can define rules and a way to enforce a subset of C++, but I think
> > over time the code will be C++. A policy that is complicated discourages
> > contributors.
> > 
> > For these reasons I think that if code runs through a C++ compiler we
> > should just allow C++. Either way, it will take time but that way no one
> > will feel betrayed when C++ creeps in.
> > 
> > That said, I hope we find an option that doesn't involve C++.
> 
> The real show stopper with our current coroutine impl IIUC, is the
> undefined behaviour when we yield and restore across different threads.
> 
> Is there any relastic hope that we can change QEMU's usage, such that
> each coroutine is confined to a single thread, to avoid the undefined
> behaviour ?

I don't think so. At the point where a coroutine stops executing in the
vCPU thread the call stack is too deep. The benefit of coroutines would
be lost because it would be necessary to use callback functions (BHs).

Fixes that paper over the undefined behavior have been merged so the
bugs should be kept at bay for a while. In theory we can continue with
stack-based coroutines but we're likely to hit issues again in the
future.

Paolo also prototyped C stackless coroutines. That would require a
source-to-source translation that converts a coroutine_fn into a Duff's
device state machine. That solution doesn't require C++ but it would be
necessary to develop the source-to-source translator and maintain it.

Finally it may be possible to get coroutine in C from clang/gcc. They
have the machinery to do it for C++ so maybe they could also offer it in
C compiler mode. It would be great to have coroutines available in the
toolchain - more reliable and supported than if we roll our own.

Stefan


signature.asc
Description: PGP signature


Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-16 Thread Kevin Wolf
Am 16.03.2022 um 13:40 hat Stefan Hajnoczi geschrieben:
> On Wed, Mar 16, 2022 at 12:08:33AM +0100, Paolo Bonzini wrote:
> > On 3/15/22 16:55, Daniel P. Berrangé wrote:
> > > Expecting maintainers to enforce a subset during code review feels
> > > like it would be a tedious burden, that will inevitably let stuff
> > > through because humans are fallible, especially when presented
> > > with uninspiring, tedious, repetitive tasks.
> > > 
> > > Restricting ourselves to a subset is only viable if we have
> > > an automated tool that can reliably enforce that subset. I'm not
> > > sure that any such tool exists, and not convinced our time is
> > > best served by trying to write & maintainer one either.
> > 
> > We don't need to have a policy on which features are used.  We need to have
> > goals for what to use C++ for.  I won't go into further details here,
> > because I had already posted "When and how to use C++"[1] about an hour
> > before your reply.
> > 
> > > IOW, I fear one we allow C++ in any level, it won't be practical
> > > to constrain it as much we desire. I fear us turning QEMU into
> > > even more of a monster like other big C++ apps I see which take
> > > all hours to compile while using all available RAM in Fedora RPM
> > > build hosts.
> > 
> > Sorry but this is FUD.  There's plenty of C++ apps and libraries that do not
> > "take hours to compile while using all available RAM".  You're probably
> > thinking of the Chromium/Firefox/Libreoffice triplet but those are an order
> > of magnitude larger than QEMU.  And in fact, QEMU is *already* a monster
> > that takes longer to compile than most other packages, no matter the
> > language they're written in.
> > 
> > Most of KDE and everything that uses Qt is written in C++, and so is
> > Inkscape in GTK+ land.  LLVM and Clang are written in C++.  Hotspot and V8
> > are written in C++.  Kodi, MAME and DolphinEmu are written in C++. GCC and
> > GDB have migrated to C++ and their compile times have not exploded.
> > 
> > > My other question is whether adoption of C++ would complicate any
> > > desire to make more use of Rust in QEMU ? I know Rust came out of
> > > work by the Mozilla Firefox crew, and Firefox was C++, but I don't
> > > have any idea how they integrated use of Rust with Firefox, so
> > > whether there are any gotcha's for us or not ?
> > 
> > Any Rust integration would go through C APIs.  Using Rust in the block layer
> > would certainly be much harder, though perhaps not impossible, if the block
> > layer uses C++ coroutines.  Rust supports something similar, but
> > two-direction interoperability would be hard.
> 
> I haven't looked at this in depth but there is a solution for Rust-C++
> interop: https://cxx.rs/

"Direct FFI of async functions is absolutely in scope for CXX (on C++20
and up) but is not implemented yet in the current release."

With the current QEMU coroutines, calling Rust async fns from C is
relatively easy, and calling C coroutine_fns from a Rust async fn is
trivial when the Rust async fn is already called from a C coroutine
(because qemu_coroutine_yield() just works, we still have a coroutine
stack from the original C caller).

I suppose calling Rust async fns from C++ could actually have the same
implementation as with C when using Paolo's wrappers, but the other
direction might be a bit harder - to be honest, I can't tell because
I've never checked how C++ coroutines work internally. Could as well be
that a Rust wrapper for them isn't that hard after all.

Kevin


signature.asc
Description: PGP signature


Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-16 Thread Daniel P . Berrangé
On Wed, Mar 16, 2022 at 12:32:48PM +, Stefan Hajnoczi wrote:
> On Tue, Mar 15, 2022 at 06:29:50PM +0100, Paolo Bonzini wrote:
> > On 3/15/22 15:24, Peter Maydell wrote:
> > > On Tue, 15 Mar 2022 at 14:09, Stefan Hajnoczi  wrote:
> > > > Also, once C++ is available people will
> > > > start submitting C++ patches simply because they are more comfortable
> > > > with C++ (especially one-time/infrequent contributors).
> > > 
> > > This to my mind is the major argument against using C++
> > > for coroutines...
> > 
> > I agree on the need for a policy, but _what_ C++ are they going to be
> > contributing that we should be scared of?  We're talking about:
> > 
> > * major features contributed by one-time/infrequent participants (which is
> > already a once-in-a-year thing or so, at least for me)
> > 
> > * ... in an area where there are no examples of using C++ in the tree (or
> > presumably the maintainer would be comfortable reviewing it)
> > 
> > * ... but yet C++ offer killer features (right now there's only C++
> > coroutines and fpu/)
> 
> You are assuming people only choose C++ only when it offers features not
> available in C. I think they might simply be more comfortable in C++.
> 
> In other words, if an existing file is compiled using a C++ compiler or
> they are adding a new file, they don't need a reason to use C++, they
> can just use it.
> 
> You can define rules and a way to enforce a subset of C++, but I think
> over time the code will be C++. A policy that is complicated discourages
> contributors.
> 
> For these reasons I think that if code runs through a C++ compiler we
> should just allow C++. Either way, it will take time but that way no one
> will feel betrayed when C++ creeps in.
> 
> That said, I hope we find an option that doesn't involve C++.

The real show stopper with our current coroutine impl IIUC, is the
undefined behaviour when we yield and restore across different threads.

Is there any relastic hope that we can change QEMU's usage, such that
each coroutine is confined to a single thread, to avoid the undefined
behaviour ?

With 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 :|




Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-16 Thread Stefan Hajnoczi
On Wed, Mar 16, 2022 at 12:08:33AM +0100, Paolo Bonzini wrote:
> On 3/15/22 16:55, Daniel P. Berrangé wrote:
> > Expecting maintainers to enforce a subset during code review feels
> > like it would be a tedious burden, that will inevitably let stuff
> > through because humans are fallible, especially when presented
> > with uninspiring, tedious, repetitive tasks.
> > 
> > Restricting ourselves to a subset is only viable if we have
> > an automated tool that can reliably enforce that subset. I'm not
> > sure that any such tool exists, and not convinced our time is
> > best served by trying to write & maintainer one either.
> 
> We don't need to have a policy on which features are used.  We need to have
> goals for what to use C++ for.  I won't go into further details here,
> because I had already posted "When and how to use C++"[1] about an hour
> before your reply.
> 
> > IOW, I fear one we allow C++ in any level, it won't be practical
> > to constrain it as much we desire. I fear us turning QEMU into
> > even more of a monster like other big C++ apps I see which take
> > all hours to compile while using all available RAM in Fedora RPM
> > build hosts.
> 
> Sorry but this is FUD.  There's plenty of C++ apps and libraries that do not
> "take hours to compile while using all available RAM".  You're probably
> thinking of the Chromium/Firefox/Libreoffice triplet but those are an order
> of magnitude larger than QEMU.  And in fact, QEMU is *already* a monster
> that takes longer to compile than most other packages, no matter the
> language they're written in.
> 
> Most of KDE and everything that uses Qt is written in C++, and so is
> Inkscape in GTK+ land.  LLVM and Clang are written in C++.  Hotspot and V8
> are written in C++.  Kodi, MAME and DolphinEmu are written in C++. GCC and
> GDB have migrated to C++ and their compile times have not exploded.
> 
> > My other question is whether adoption of C++ would complicate any
> > desire to make more use of Rust in QEMU ? I know Rust came out of
> > work by the Mozilla Firefox crew, and Firefox was C++, but I don't
> > have any idea how they integrated use of Rust with Firefox, so
> > whether there are any gotcha's for us or not ?
> 
> Any Rust integration would go through C APIs.  Using Rust in the block layer
> would certainly be much harder, though perhaps not impossible, if the block
> layer uses C++ coroutines.  Rust supports something similar, but
> two-direction interoperability would be hard.

I haven't looked at this in depth but there is a solution for Rust-C++
interop: https://cxx.rs/

Stefan


signature.asc
Description: PGP signature


Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-16 Thread Stefan Hajnoczi
On Tue, Mar 15, 2022 at 06:29:50PM +0100, Paolo Bonzini wrote:
> On 3/15/22 15:24, Peter Maydell wrote:
> > On Tue, 15 Mar 2022 at 14:09, Stefan Hajnoczi  wrote:
> > > Also, once C++ is available people will
> > > start submitting C++ patches simply because they are more comfortable
> > > with C++ (especially one-time/infrequent contributors).
> > 
> > This to my mind is the major argument against using C++
> > for coroutines...
> 
> I agree on the need for a policy, but _what_ C++ are they going to be
> contributing that we should be scared of?  We're talking about:
> 
> * major features contributed by one-time/infrequent participants (which is
> already a once-in-a-year thing or so, at least for me)
> 
> * ... in an area where there are no examples of using C++ in the tree (or
> presumably the maintainer would be comfortable reviewing it)
> 
> * ... but yet C++ offer killer features (right now there's only C++
> coroutines and fpu/)

You are assuming people only choose C++ only when it offers features not
available in C. I think they might simply be more comfortable in C++.

In other words, if an existing file is compiled using a C++ compiler or
they are adding a new file, they don't need a reason to use C++, they
can just use it.

You can define rules and a way to enforce a subset of C++, but I think
over time the code will be C++. A policy that is complicated discourages
contributors.

For these reasons I think that if code runs through a C++ compiler we
should just allow C++. Either way, it will take time but that way no one
will feel betrayed when C++ creeps in.

That said, I hope we find an option that doesn't involve C++.

Stefan


signature.asc
Description: PGP signature


Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-15 Thread Paolo Bonzini

On 3/15/22 16:55, Daniel P. Berrangé wrote:

Expecting maintainers to enforce a subset during code review feels
like it would be a tedious burden, that will inevitably let stuff
through because humans are fallible, especially when presented
with uninspiring, tedious, repetitive tasks.

Restricting ourselves to a subset is only viable if we have
an automated tool that can reliably enforce that subset. I'm not
sure that any such tool exists, and not convinced our time is
best served by trying to write & maintainer one either.


We don't need to have a policy on which features are used.  We need to 
have goals for what to use C++ for.  I won't go into further details 
here, because I had already posted "When and how to use C++"[1] about an 
hour before your reply.



IOW, I fear one we allow C++ in any level, it won't be practical
to constrain it as much we desire. I fear us turning QEMU into
even more of a monster like other big C++ apps I see which take
all hours to compile while using all available RAM in Fedora RPM
build hosts.


Sorry but this is FUD.  There's plenty of C++ apps and libraries that do 
not "take hours to compile while using all available RAM".  You're 
probably thinking of the Chromium/Firefox/Libreoffice triplet but those 
are an order of magnitude larger than QEMU.  And in fact, QEMU is 
*already* a monster that takes longer to compile than most other 
packages, no matter the language they're written in.


Most of KDE and everything that uses Qt is written in C++, and so is 
Inkscape in GTK+ land.  LLVM and Clang are written in C++.  Hotspot and 
V8 are written in C++.  Kodi, MAME and DolphinEmu are written in C++. 
GCC and GDB have migrated to C++ and their compile times have not exploded.



My other question is whether adoption of C++ would complicate any
desire to make more use of Rust in QEMU ? I know Rust came out of
work by the Mozilla Firefox crew, and Firefox was C++, but I don't
have any idea how they integrated use of Rust with Firefox, so
whether there are any gotcha's for us or not ?


Any Rust integration would go through C APIs.  Using Rust in the block 
layer would certainly be much harder, though perhaps not impossible, if 
the block layer uses C++ coroutines.  Rust supports something similar, 
but two-direction interoperability would be hard.


For everything else, not much.  Even if using C++, the fact that QEMU's 
APIs are primarily C would not change.  Changing "timer_mod_ns(timer, 
ns)" to "timer.modify_ns(ns)" is not on the table.


But really, first of all the question should be who is doing work on 
integrating Rust with QEMU.  I typically hear about this topic exactly 
once a year at KVM Forum, and then nothing.  We have seen Marc-André's 
QAPI integration experiment, but it's not clear to me what the path 
would be from there to wider use in QEMU.


In particular, after ~3 years of talking about it, it is not even clear:

- what subsystems would benefit the most from the adoption of Rust, and 
whether that would be feasible without a rewrite which will simply never 
happen


- what the plans would be for coexistence of Rust and C code within a 
subsystem


- whether maintainers would be on board with adopting a completely 
different language, and who in the community has enough Rust experience 
to shepherd us through the learning experience


The first two questions have answers in the other message if 
s/Rust/C++/, and as to the last I think we're already further in the 
discussion.


Thanks,

Paolo



Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-15 Thread Daniel P . Berrangé
On Tue, Mar 15, 2022 at 06:27:57PM +0100, Paolo Bonzini wrote:
> On 3/15/22 10:32, Daniel P. Berrangé wrote:
> > > > So NetBSD is our biggest constraint on requiring GCC 10
> > > 
> > > Do we care about the BSDs since they have newer compilers (including 
> > > gcc10)
> > > available in pkgsrc?  If you go by the base system, then RHEL8 has 8.5.0 
> > > and
> > > newer version are only available with packages such as gcc-toolset-10 and
> > > gcc-toolset-11.
> > 
> > I mention NetBSD because we had an explicit request to support
> > 7.4 GCC from there, as it was the current system compiler.
> 
> Thanks, do you have a reference?  I would like to understand the reason for
> that (adding Werner too).

It was commit 3830df5f83b9b52d9496763ce1a50afb9231c998

> For RHEL8, considering that the switch would be several months away anyway,
> I don't think it would be an issue to require AppStream toolset packages.
> It's unlikely that RHEL8 would rebase QEMU in 2023 and beyond.

It isn't so much RHEL8 rebases I'm thinking of wrt the policy, but
rather our corporate contributors who can be constrained by annoying
corporate policies to only use RHEL-8 for their work.

With 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 :|




Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-15 Thread Paolo Bonzini

On 3/15/22 17:15, Daniel P. Berrangé wrote:

Bear with me as I suggest something potentially/probably silly
given my limited knowledge of C++ coroutines.

Given a function I know about:

   void coroutine_fn qio_channel_yield(QIOChannel *ioc,
   GIOCondition condition);

IIUC, you previously indicated that the header file declaration,
the implementation and any callers of this would need to be in
C++ source files.

The caller is what I'm most curious about, because I feel that
is where the big ripple effects come into play that cause large
parts of QEMU to become C++ code. [...]
I presume there is something special about the CoroutineFn
prototype preventing that from working as needed, thus requiring
the caller to be compiled as C++ ? IIUC compiling as C++ though
is not neccessarily the same as using C++ linkage.


Yes, the CoroutineFn function must either be passed to 
qemu_coroutine_create() or called as "co_await f()".  If you call it as 
"f()" it does nothing except leak the memory needed by its stack frame, 
so that only leaves passing the function to qemu_coroutine_create().


I suppose you could do some games with typedefs, like

#ifdef __cplusplus
typedef CoroutineFn VoidCoroutine
#else
typedef struct VoidCoroutine VoidCoroutine;
#endif

to be able to declare a function that returns CoroutineFn but I'm 
not sure of the advantage.



So I'm assuming the caller as C++ requirement is not recursive,
otherwise it would immediately mean all of QEMU needs to be C++.


Right, qemu_coroutine_create() must be called from C++ but the caller of 
qemu_coroutine_create() can be extern "C".  In the particular case of 
the block layer, callers of qemu_coroutine_create() include 
callback-based functions such as bdrv_aio_readv(), and synchronous 
functions such as bdrv_flush().  Both of these can be called from C.



IOW, can we get it such that the C++ bit is just a thin shim
"C -> C++ wrapper -> C++ CoroutineFn -> C", enabling all the
C++ bits to be well encapsulated and thus prevent arbitrary
usage of C++ features leaking all across the codebase ?


No, unfortunately not.  But in particular, even though the block layer 
would be C++, device models that use it would not.


Paolo



Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-15 Thread Paolo Bonzini

On 3/15/22 15:24, Peter Maydell wrote:

On Tue, 15 Mar 2022 at 14:09, Stefan Hajnoczi  wrote:

Also, once C++ is available people will
start submitting C++ patches simply because they are more comfortable
with C++ (especially one-time/infrequent contributors).


This to my mind is the major argument against using C++
for coroutines...


I agree on the need for a policy, but _what_ C++ are they going to be 
contributing that we should be scared of?  We're talking about:


* major features contributed by one-time/infrequent participants (which 
is already a once-in-a-year thing or so, at least for me)


* ... in an area where there are no examples of using C++ in the tree 
(or presumably the maintainer would be comfortable reviewing it)


* ... but yet C++ offer killer features (right now there's only C++ 
coroutines and fpu/)


* ... and where the one-time contributor has put enough investment in 
using these killer C++ features, that telling them to remove the 
features would amount to a rewrite.


That does not seem to be a common situation, and not even a problematic 
one if it were to happen.


Paolo



Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-15 Thread Paolo Bonzini

On 3/15/22 10:32, Daniel P. Berrangé wrote:

So NetBSD is our biggest constraint on requiring GCC 10


Do we care about the BSDs since they have newer compilers (including gcc10)
available in pkgsrc?  If you go by the base system, then RHEL8 has 8.5.0 and
newer version are only available with packages such as gcc-toolset-10 and
gcc-toolset-11.


I mention NetBSD because we had an explicit request to support
7.4 GCC from there, as it was the current system compiler.


Thanks, do you have a reference?  I would like to understand the reason 
for that (adding Werner too).


For RHEL8, considering that the switch would be several months away 
anyway, I don't think it would be an issue to require AppStream toolset 
packages.  It's unlikely that RHEL8 would rebase QEMU in 2023 and beyond.


Paolo



When and how to use C++ (was Re: [PATCH experiment 00/16] C++20 coroutine backend)

2022-03-15 Thread Paolo Bonzini



On 3/15/22 15:50, Kevin Wolf wrote:

I'm not sure what the C++ lock guards offer that our current lock guards
don't? Passing down lock guards makes sense to me, but why can't you do
that with QemuLockable?


Passing a QemuLockable alone doesn't ensure that the lock has been 
taken.  I guess we could build a QemuLockGuard on top that ensures that.



(Hm, or can the C++ version somehow check at
compile time that it's the _right_ lock that is held rather than just
any lock? It didn't look like it at the first sight.)


It's not related to lock guards but clang++ has thread-safety analysis 
that checks for the right lock.  It is in theory there for C as well but 
it's mostly a joke.  Ironically, the only good use that I've seen of it 
is Marc-André's never committed work to check coroutine_fn markers at 
compile-time[1].



But I do see the benefit of a compiler checked CoroutineFn<> return type
compared to the coroutine_fn markers we have today. On the other hand...


Also, once C++ is available people will start submitting C++ patches
simply because they are more comfortable with C++ (especially
one-time/infrequent contributors).


...using C++ in coroutine code means that all of the block layer would
suddenly become C++ and would be most affected by this effect. I'm not
sure if that's something I would like to see, at least until there is a
clear tree-wide policy (that preferably limits it to a subset that I
understand).


You are the maintainer of the block layer, so you would have the biggest 
impact and obviously have input in such a policy.  I obviously don't 
have a policy ready[2], but I do have some goals:


1) whenever C++ is used to build an API for use in C++ source files:

Those source files and their debugging experience should look
like C, and not any more "foreign" than   the "QEMU C" dialect
that we already have.

Rationale: we might have funky code in headers, but
"QEMU_WITH_LOCK_GUARD(x) { }" is understandable; the same would
hold for "CoroutineFn", "co_await fn();" or if hwaddr
internally used operator overloading.

2) whenever C and C++ provide two different implementations of an API, 
for use in C and C++ source files respectively:


If the same API is implemented in different ways for C and C++,
the semantics should be equivalent, and covered by both
C and C++ testcases.

Rationale: this should be a rare occasion, but there are
features such as _Generic that are C only, so it should be
catered for; QemuLockable came out already in this proof of
concept.  The implementation is completely different for C
and C++, but it works the same (as proved to some extent
by testcases).

Looking again at the hwaddr example, it would be okay to forbid
"hwaddr - hwaddr" subtraction in C++ code.  But it would not be
okay to have it return a signed integer in C++, while it
returns an unsigned integer in C.  Could there be a C++-only
method "hwaddr.diff(hwaddr)" that does return a signed integer?
That would have to be discussed, right now my opinion is
"probably not" but see the next point too.

3) whenever C++ features (templates, classes, etc.) are used in .cc files:

The features should have a clear benefit over equivalent
C-only code (e.g. using the preprocessor instead of templates)
and if applicable they should publish a C API[3] that can be
consumed outside a particular subsystem.

If in doubt, err on the side of moderation, i.e. less C++ and
fewer C++ features.

Example: I can imagine that in some cases the semantic
replacement abilities provided by templates will for example
improve compile-time checking and reduce code duplication
compared to gcc.  However, QEMU already has a wide range of
data structures and auxiliary APIs for C, and those should be
used for C++ code to avoid splitting the code base.

In turn, this should limit the usage of other C++ features.
For example, constructors (as opposed to just being able to
zero-initialize memory) can be more of a pain than a benefit
if you can't use "new", "delete" or "std::vector<>".  Likewise,
it's unlikely that we'll have reasons to use anonymous
namespaces instead of "static", because that's mostly useful
for classes defined in .cc files and their member functions[5].
And VMState will prevent the usage of "private:", thus lowering
the benefit from methods.

Would this kind of formulation be enough?  Maybe, maybe not, but either 
way I don't really believe in prohibiting features by policy.  The QEMU 
community and especially its maintainers won't change overnight if C++ 
is allowed in the codebase; but they should be allowed to evolve their 
opinions as their experience grows.  If some day 

Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-15 Thread Daniel P . Berrangé
On Mon, Mar 14, 2022 at 10:31:47AM +0100, Paolo Bonzini wrote:
> However, there  are no ramifications to actual coroutine code, except
> for the template syntax "CoroutineFn" for the function and
> the mandatory co_await/co_return keywords... both of which are an
> improvement, really: the fact that a single function cannot run either
> inside or outside coroutines is checked by the compiler now, because
> qemu_coroutine_create accepts a function that returns CoroutineFn.
> Therefore I had to disable some more code in util/ and qapi/ that used
> qemu_in_coroutine() or coroutine_fn.

Bear with me as I suggest something potentially/probably silly
given my limited knowledge of C++ coroutines.

Given a function I know about:

  void coroutine_fn qio_channel_yield(QIOChannel *ioc,
  GIOCondition condition);

IIUC, you previously indicated that the header file declaration,
the implementation and any callers of this would need to be in
C++ source files.

The caller is what I'm most curious about, because I feel that
is where the big ripple effects come into play that cause large
parts of QEMU to become C++ code.

In general it is possible to call C++ functions from C.

I presume there is something special about the CoroutineFn
prototype preventing that from working as needed, thus requiring
the caller to be compiled as C++ ? IIUC compiling as C++ though
is not neccessarily the same as using C++ linkage.

So I'm assuming the caller as C++ requirement is not recursive,
otherwise it would immediately mean all of QEMU needs to be C++.

This leads me to wonder if we can workaround this problem with
a wrapper function. eg in a io/channel.hpp file can be declare
something like:

  CoroutineFn qio_channel_yield_impl(QIOChannel *ioc,
   GIOCondition condition);

  extern "C" {
static inline void qio_chanel_yield(QIOChannel *ioc,
GIOCondition condition) {
  qio_channel_yield_impl(ioc, condition)
}
  }

With this qio_channel_yield_impl and qio_channel_yield are both
compiled as C++, but qio_channel_yield is exposed with C linkage
semantics. Thus enabling callers of qio_channel_yield can carry
on being compiled as C, since the invokation of the CoroutineFn
is in the inline C++ function ?

This would mean an extra function call, but perhaps this gets
optimized away, espeically with LTO, such that it doesn't impact
performance negatively ?

The impl of qio_channel_yield_impl() could also call from C++
back to C functions as much as possible.

IOW, can we get it such that the C++ bit is just a thin shim
"C -> C++ wrapper -> C++ CoroutineFn -> C", enabling all the
C++ bits to be well encapsulated and thus prevent arbitrary
usage of C++ features leaking all across the codebase ?

With 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 :|




Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-15 Thread Daniel P . Berrangé
On Tue, Mar 15, 2022 at 03:50:26PM +0100, Kevin Wolf wrote:
> Am 15.03.2022 um 15:05 hat Stefan Hajnoczi geschrieben:
> > On Mon, Mar 14, 2022 at 05:21:22PM +0100, Paolo Bonzini wrote:
> > > On 3/14/22 15:07, Stefan Hajnoczi wrote:
> > > > If we can reach a consensus about C++ language usage in QEMU then I'm in
> > > > favor of using C++ coroutines. It's probably not realistic to think we
> > > > can limit C++ language usage to just coroutines forever. Someone finds
> > > > another C++ feature they absolutely need and over time the codebase
> > > > becomes C++ - with both its advantages and disadvantages.
> > > > 
> > > > [...] although you can write C in C++, it's not idiomatic modern C++.
> > > > The language lends itself to a different style of programming that
> > > > some will embrace while others will not.
> > > 
> > > Yes, this is an important aspect to discuss.  I think coroutines provide a
> > > good blueprint for how QEMU might use C++.
> > > 
> > > I totally agree that, if we go this way, the genie is out of the bottle 
> > > and
> > > other uses of C++ will pop up with 100% probability.  But the important
> > > thing to note is that our dialect of C is already not standard C, and that
> > > some of our or GLib's "innovations" are actually based on experience with
> > > C++.  We can keep on writing "QEMU's C" if we think of C++ as a 
> > > supercharged
> > > way of writing these quality-of-life improvements that we already write.  
> > > In
> > > some sense coroutines are an extreme example of this idea.
> > > 
> > > In fact, a C API would have to remain unless all source files are changed 
> > > to
> > > C++, so QEMU would remain mostly a C project with C idioms, but that 
> > > doesn't
> > > prevent _abstracting_ the use of C++ features (written in modern, 
> > > idiomatic
> > > C++) behind an API that C programmers have no problems learning.  Again,
> > > coroutines are an example of this of keeping the familiar 
> > > create/enter/yield
> > > API and hiding the "magic" of C++ coroutines (and when they don't, that 
> > > had
> > > better be an improvement).
> > > 
> > > In the end, C++ is a tool that you can use if it leads to better code. For
> > > example, I don't see much use of C++ for devices for example, and the
> > > storage devices in particular do not even need coroutines because they use
> > > the callback-based interface.  But perhaps someone will try to use 
> > > templates
> > > to replace repeated inclusion (which is common in hw/display) and others
> > > will follow suit.  Or perhaps not.
> > > 
> > > One example that was brought up on IRC is type-safe operations on things
> > > such as hwaddr (i.e. hwaddr+int is allowed but hwaddr-hwaddr gives back an
> > > int64_t and might even check for overflow).  These would be opt in (you 
> > > get
> > > them just by changing a file from .c to .cc), but the actual C++ code 
> > > would
> > > still look very much like C code that uses hwaddr with no type checking.
> > > All the operator overloading gunk would be in include/.
> > > 
> > > A different topic is what would happen if all of QEMU could be compiled as
> > > C++, and could inform our selection of C++ idioms even long before we get
> > > there.  For example, I'm fine with GLib and our type-safe intrusive lists,
> > > so I don't have much interest in STL containers and I would prefer _not_ 
> > > to
> > > use STL containers even in .cc files[1].  However, perhaps QEMU's 
> > > home-grown
> > > lock guard might be replaced by something that uses C++ destructors 
> > > instead
> > > of g_autoptr, so perhaps we should consider using std::lock_guard<>, or
> > > something like that, instead of QEMU_LOCK_GUARD.  It may be interesting to
> > > pass down lock_guards as arguments to enforce "this lock is taken"
> > > invariants.
> > > 
> > > But really, coroutines would be enough work so my dish would be full for
> > > some time and I wouldn't really have time to look at any of this. :)
> > 
> > I think it will be necessary to compile QEMU with a C++ compiler quite
> > soon. It is possible to provide C APIs like in the case of coroutines,
> > but sometimes C++ features need to be exposed to the caller (like the
> > lock guards you mentioned).
> 
> I'm not sure what the C++ lock guards offer that our current lock guards
> don't? Passing down lock guards makes sense to me, but why can't you do
> that with QemuLockable? (Hm, or can the C++ version somehow check at
> compile time that it's the _right_ lock that is held rather than just
> any lock? It didn't look like it at the first sight.)



> 
> But I do see the benefit of a compiler checked CoroutineFn<> return type
> compared to the coroutine_fn markers we have today. On the other hand...
> 
> > Also, once C++ is available people will start submitting C++ patches
> > simply because they are more comfortable with C++ (especially
> > one-time/infrequent contributors).
> 
> ...using C++ in coroutine code means that all of the block layer 

Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-15 Thread Stefan Hajnoczi
On Tue, Mar 15, 2022 at 03:50:26PM +0100, Kevin Wolf wrote:
> Am 15.03.2022 um 15:05 hat Stefan Hajnoczi geschrieben:
> > On Mon, Mar 14, 2022 at 05:21:22PM +0100, Paolo Bonzini wrote:
> > > On 3/14/22 15:07, Stefan Hajnoczi wrote:
> > > > If we can reach a consensus about C++ language usage in QEMU then I'm in
> > > > favor of using C++ coroutines. It's probably not realistic to think we
> > > > can limit C++ language usage to just coroutines forever. Someone finds
> > > > another C++ feature they absolutely need and over time the codebase
> > > > becomes C++ - with both its advantages and disadvantages.
> > > > 
> > > > [...] although you can write C in C++, it's not idiomatic modern C++.
> > > > The language lends itself to a different style of programming that
> > > > some will embrace while others will not.
> > > 
> > > Yes, this is an important aspect to discuss.  I think coroutines provide a
> > > good blueprint for how QEMU might use C++.
> > > 
> > > I totally agree that, if we go this way, the genie is out of the bottle 
> > > and
> > > other uses of C++ will pop up with 100% probability.  But the important
> > > thing to note is that our dialect of C is already not standard C, and that
> > > some of our or GLib's "innovations" are actually based on experience with
> > > C++.  We can keep on writing "QEMU's C" if we think of C++ as a 
> > > supercharged
> > > way of writing these quality-of-life improvements that we already write.  
> > > In
> > > some sense coroutines are an extreme example of this idea.
> > > 
> > > In fact, a C API would have to remain unless all source files are changed 
> > > to
> > > C++, so QEMU would remain mostly a C project with C idioms, but that 
> > > doesn't
> > > prevent _abstracting_ the use of C++ features (written in modern, 
> > > idiomatic
> > > C++) behind an API that C programmers have no problems learning.  Again,
> > > coroutines are an example of this of keeping the familiar 
> > > create/enter/yield
> > > API and hiding the "magic" of C++ coroutines (and when they don't, that 
> > > had
> > > better be an improvement).
> > > 
> > > In the end, C++ is a tool that you can use if it leads to better code. For
> > > example, I don't see much use of C++ for devices for example, and the
> > > storage devices in particular do not even need coroutines because they use
> > > the callback-based interface.  But perhaps someone will try to use 
> > > templates
> > > to replace repeated inclusion (which is common in hw/display) and others
> > > will follow suit.  Or perhaps not.
> > > 
> > > One example that was brought up on IRC is type-safe operations on things
> > > such as hwaddr (i.e. hwaddr+int is allowed but hwaddr-hwaddr gives back an
> > > int64_t and might even check for overflow).  These would be opt in (you 
> > > get
> > > them just by changing a file from .c to .cc), but the actual C++ code 
> > > would
> > > still look very much like C code that uses hwaddr with no type checking.
> > > All the operator overloading gunk would be in include/.
> > > 
> > > A different topic is what would happen if all of QEMU could be compiled as
> > > C++, and could inform our selection of C++ idioms even long before we get
> > > there.  For example, I'm fine with GLib and our type-safe intrusive lists,
> > > so I don't have much interest in STL containers and I would prefer _not_ 
> > > to
> > > use STL containers even in .cc files[1].  However, perhaps QEMU's 
> > > home-grown
> > > lock guard might be replaced by something that uses C++ destructors 
> > > instead
> > > of g_autoptr, so perhaps we should consider using std::lock_guard<>, or
> > > something like that, instead of QEMU_LOCK_GUARD.  It may be interesting to
> > > pass down lock_guards as arguments to enforce "this lock is taken"
> > > invariants.
> > > 
> > > But really, coroutines would be enough work so my dish would be full for
> > > some time and I wouldn't really have time to look at any of this. :)
> > 
> > I think it will be necessary to compile QEMU with a C++ compiler quite
> > soon. It is possible to provide C APIs like in the case of coroutines,
> > but sometimes C++ features need to be exposed to the caller (like the
> > lock guards you mentioned).
> 
> I'm not sure what the C++ lock guards offer that our current lock guards
> don't? Passing down lock guards makes sense to me, but why can't you do
> that with QemuLockable? (Hm, or can the C++ version somehow check at
> compile time that it's the _right_ lock that is held rather than just
> any lock? It didn't look like it at the first sight.)
> 
> But I do see the benefit of a compiler checked CoroutineFn<> return type
> compared to the coroutine_fn markers we have today. On the other hand...

Sorry, I made a mistake: the C++ coroutines implementation does not hide
everything behind a C API. Coroutine functions need to be defined in C++
source units.

Stefan


signature.asc
Description: PGP signature


Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-15 Thread Kevin Wolf
Am 15.03.2022 um 15:05 hat Stefan Hajnoczi geschrieben:
> On Mon, Mar 14, 2022 at 05:21:22PM +0100, Paolo Bonzini wrote:
> > On 3/14/22 15:07, Stefan Hajnoczi wrote:
> > > If we can reach a consensus about C++ language usage in QEMU then I'm in
> > > favor of using C++ coroutines. It's probably not realistic to think we
> > > can limit C++ language usage to just coroutines forever. Someone finds
> > > another C++ feature they absolutely need and over time the codebase
> > > becomes C++ - with both its advantages and disadvantages.
> > > 
> > > [...] although you can write C in C++, it's not idiomatic modern C++.
> > > The language lends itself to a different style of programming that
> > > some will embrace while others will not.
> > 
> > Yes, this is an important aspect to discuss.  I think coroutines provide a
> > good blueprint for how QEMU might use C++.
> > 
> > I totally agree that, if we go this way, the genie is out of the bottle and
> > other uses of C++ will pop up with 100% probability.  But the important
> > thing to note is that our dialect of C is already not standard C, and that
> > some of our or GLib's "innovations" are actually based on experience with
> > C++.  We can keep on writing "QEMU's C" if we think of C++ as a supercharged
> > way of writing these quality-of-life improvements that we already write.  In
> > some sense coroutines are an extreme example of this idea.
> > 
> > In fact, a C API would have to remain unless all source files are changed to
> > C++, so QEMU would remain mostly a C project with C idioms, but that doesn't
> > prevent _abstracting_ the use of C++ features (written in modern, idiomatic
> > C++) behind an API that C programmers have no problems learning.  Again,
> > coroutines are an example of this of keeping the familiar create/enter/yield
> > API and hiding the "magic" of C++ coroutines (and when they don't, that had
> > better be an improvement).
> > 
> > In the end, C++ is a tool that you can use if it leads to better code. For
> > example, I don't see much use of C++ for devices for example, and the
> > storage devices in particular do not even need coroutines because they use
> > the callback-based interface.  But perhaps someone will try to use templates
> > to replace repeated inclusion (which is common in hw/display) and others
> > will follow suit.  Or perhaps not.
> > 
> > One example that was brought up on IRC is type-safe operations on things
> > such as hwaddr (i.e. hwaddr+int is allowed but hwaddr-hwaddr gives back an
> > int64_t and might even check for overflow).  These would be opt in (you get
> > them just by changing a file from .c to .cc), but the actual C++ code would
> > still look very much like C code that uses hwaddr with no type checking.
> > All the operator overloading gunk would be in include/.
> > 
> > A different topic is what would happen if all of QEMU could be compiled as
> > C++, and could inform our selection of C++ idioms even long before we get
> > there.  For example, I'm fine with GLib and our type-safe intrusive lists,
> > so I don't have much interest in STL containers and I would prefer _not_ to
> > use STL containers even in .cc files[1].  However, perhaps QEMU's home-grown
> > lock guard might be replaced by something that uses C++ destructors instead
> > of g_autoptr, so perhaps we should consider using std::lock_guard<>, or
> > something like that, instead of QEMU_LOCK_GUARD.  It may be interesting to
> > pass down lock_guards as arguments to enforce "this lock is taken"
> > invariants.
> > 
> > But really, coroutines would be enough work so my dish would be full for
> > some time and I wouldn't really have time to look at any of this. :)
> 
> I think it will be necessary to compile QEMU with a C++ compiler quite
> soon. It is possible to provide C APIs like in the case of coroutines,
> but sometimes C++ features need to be exposed to the caller (like the
> lock guards you mentioned).

I'm not sure what the C++ lock guards offer that our current lock guards
don't? Passing down lock guards makes sense to me, but why can't you do
that with QemuLockable? (Hm, or can the C++ version somehow check at
compile time that it's the _right_ lock that is held rather than just
any lock? It didn't look like it at the first sight.)

But I do see the benefit of a compiler checked CoroutineFn<> return type
compared to the coroutine_fn markers we have today. On the other hand...

> Also, once C++ is available people will start submitting C++ patches
> simply because they are more comfortable with C++ (especially
> one-time/infrequent contributors).

...using C++ in coroutine code means that all of the block layer would
suddenly become C++ and would be most affected by this effect. I'm not
sure if that's something I would like to see, at least until there is a
clear tree-wide policy (that preferably limits it to a subset that I
understand).

Kevin


signature.asc
Description: PGP signature


Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-15 Thread Peter Maydell
On Tue, 15 Mar 2022 at 14:09, Stefan Hajnoczi  wrote:
> Also, once C++ is available people will
> start submitting C++ patches simply because they are more comfortable
> with C++ (especially one-time/infrequent contributors).

This to my mind is the major argument against using C++
for coroutines...

-- PMM



Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-15 Thread Stefan Hajnoczi
On Mon, Mar 14, 2022 at 05:21:22PM +0100, Paolo Bonzini wrote:
> On 3/14/22 15:07, Stefan Hajnoczi wrote:
> > If we can reach a consensus about C++ language usage in QEMU then I'm in
> > favor of using C++ coroutines. It's probably not realistic to think we
> > can limit C++ language usage to just coroutines forever. Someone finds
> > another C++ feature they absolutely need and over time the codebase
> > becomes C++ - with both its advantages and disadvantages.
> > 
> > [...] although you can write C in C++, it's not idiomatic modern C++.
> > The language lends itself to a different style of programming that
> > some will embrace while others will not.
> 
> Yes, this is an important aspect to discuss.  I think coroutines provide a
> good blueprint for how QEMU might use C++.
> 
> I totally agree that, if we go this way, the genie is out of the bottle and
> other uses of C++ will pop up with 100% probability.  But the important
> thing to note is that our dialect of C is already not standard C, and that
> some of our or GLib's "innovations" are actually based on experience with
> C++.  We can keep on writing "QEMU's C" if we think of C++ as a supercharged
> way of writing these quality-of-life improvements that we already write.  In
> some sense coroutines are an extreme example of this idea.
> 
> In fact, a C API would have to remain unless all source files are changed to
> C++, so QEMU would remain mostly a C project with C idioms, but that doesn't
> prevent _abstracting_ the use of C++ features (written in modern, idiomatic
> C++) behind an API that C programmers have no problems learning.  Again,
> coroutines are an example of this of keeping the familiar create/enter/yield
> API and hiding the "magic" of C++ coroutines (and when they don't, that had
> better be an improvement).
> 
> In the end, C++ is a tool that you can use if it leads to better code. For
> example, I don't see much use of C++ for devices for example, and the
> storage devices in particular do not even need coroutines because they use
> the callback-based interface.  But perhaps someone will try to use templates
> to replace repeated inclusion (which is common in hw/display) and others
> will follow suit.  Or perhaps not.
> 
> One example that was brought up on IRC is type-safe operations on things
> such as hwaddr (i.e. hwaddr+int is allowed but hwaddr-hwaddr gives back an
> int64_t and might even check for overflow).  These would be opt in (you get
> them just by changing a file from .c to .cc), but the actual C++ code would
> still look very much like C code that uses hwaddr with no type checking.
> All the operator overloading gunk would be in include/.
> 
> A different topic is what would happen if all of QEMU could be compiled as
> C++, and could inform our selection of C++ idioms even long before we get
> there.  For example, I'm fine with GLib and our type-safe intrusive lists,
> so I don't have much interest in STL containers and I would prefer _not_ to
> use STL containers even in .cc files[1].  However, perhaps QEMU's home-grown
> lock guard might be replaced by something that uses C++ destructors instead
> of g_autoptr, so perhaps we should consider using std::lock_guard<>, or
> something like that, instead of QEMU_LOCK_GUARD.  It may be interesting to
> pass down lock_guards as arguments to enforce "this lock is taken"
> invariants.
> 
> But really, coroutines would be enough work so my dish would be full for
> some time and I wouldn't really have time to look at any of this. :)

I think it will be necessary to compile QEMU with a C++ compiler quite
soon. It is possible to provide C APIs like in the case of coroutines,
but sometimes C++ features need to be exposed to the caller (like the
lock guards you mentioned). Also, once C++ is available people will
start submitting C++ patches simply because they are more comfortable
with C++ (especially one-time/infrequent contributors).

We need to agree on a policy so that people know how and when they can
use C++.

The policy needs to be simple so it doesn't create hurdles for new
contributors.

Does anyone have experience with C projects that introduced C++ and what
worked/didn't work?

Stefan


signature.asc
Description: PGP signature


Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-15 Thread Daniel P . Berrangé
On Tue, Mar 15, 2022 at 10:05:32AM +0100, Paolo Bonzini wrote:
> On 3/14/22 17:52, Daniel P. Berrangé wrote:
> >  RHEL-8: 10.0.1
> >  openSUSE Leap 15.3: 9.0.1
> >Ubuntu LTS 18.04: 6.0.0
> >  FreeBSD 12: 8.0.1
> > 
> > Ubuntu 18.04 drops off our list after 7.0 comes out
> > 
> > OpenSUSE Leap 15.2 was EOL'd by SUSE themselves in Jan 2022,
> > We use it as a proxy for SLES, but I think we can required
> > SLES 15 sp3.
> 
> (FTR, OpenSUSE Leap 15.3 has GCC 10.3.0).
> 
> > FreeBSD 12 is something we still support until April 2023,
> > but arguably we only care about CLang there.
> > 
> > NetBSD 9 wasn't listed, but it was reported to required
> > GCC 7.4  (commit 3830df5f83b9b52d9496763ce1a50afb9231c998)
> > and that is still the latest release of NetBSD.
> > 
> > So NetBSD is our biggest constraint on requiring GCC 10
> 
> Do we care about the BSDs since they have newer compilers (including gcc10)
> available in pkgsrc?  If you go by the base system, then RHEL8 has 8.5.0 and
> newer version are only available with packages such as gcc-toolset-10 and
> gcc-toolset-11.

I mention NetBSD because we had an explicit request to support
7.4 GCC from there, as it was the current system compiler.

That's a mistake in my original commit logs then wrt RHEL8, as I
only ever intended to consider the standard base repos, not random
addon repos.

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 :|




Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-15 Thread Paolo Bonzini

On 3/14/22 17:52, Daniel P. Berrangé wrote:

 RHEL-8: 10.0.1
 openSUSE Leap 15.3: 9.0.1
   Ubuntu LTS 18.04: 6.0.0
 FreeBSD 12: 8.0.1

Ubuntu 18.04 drops off our list after 7.0 comes out

OpenSUSE Leap 15.2 was EOL'd by SUSE themselves in Jan 2022,
We use it as a proxy for SLES, but I think we can required
SLES 15 sp3.


(FTR, OpenSUSE Leap 15.3 has GCC 10.3.0).


FreeBSD 12 is something we still support until April 2023,
but arguably we only care about CLang there.

NetBSD 9 wasn't listed, but it was reported to required
GCC 7.4  (commit 3830df5f83b9b52d9496763ce1a50afb9231c998)
and that is still the latest release of NetBSD.

So NetBSD is our biggest constraint on requiring GCC 10


Do we care about the BSDs since they have newer compilers (including 
gcc10) available in pkgsrc?  If you go by the base system, then RHEL8 
has 8.5.0 and newer version are only available with packages such as 
gcc-toolset-10 and gcc-toolset-11.


Paolo



Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-14 Thread Richard Henderson

On 3/14/22 09:21, Paolo Bonzini wrote:
But perhaps someone will try to use templates to replace repeated inclusion (which is 
common in hw/display) and others will follow suit.


The code in fpu/ desperately calls out for overloading and templates.  At present it is a 
tangle of _Generic and multiple inclusion.



r~



Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-14 Thread Daniel P . Berrangé
On Mon, Mar 14, 2022 at 10:31:47AM +0100, Paolo Bonzini wrote:
> This was compiled with GCC 11 only.  Coroutine support was added in
> GCC 10, released in 2020, which IIRC is much newer than the most recent
> release we support.

Currrently we target 7.4:

  commit 2a85a08c998e418a46a308095893f223642f6fc9
  Author: Daniel P. Berrangé 
  Date:   Fri May 14 13:04:15 2021 +0100

configure: bump min required CLang to 6.0 / XCode 10.0

Several distros have been dropped since the last time we bumped the
minimum required CLang version.

Per repology, currently shipping versions are:

 RHEL-8: 10.0.1
  Debian Buster: 7.0.1
 openSUSE Leap 15.2: 9.0.1
   Ubuntu LTS 18.04: 6.0.0
   Ubuntu LTS 20.04: 10.0.0
 FreeBSD 12: 8.0.1
  Fedora 33: 11.0.0
  Fedora 34: 11.1.0



Ubuntu 18.04 drops off our list after 7.0 comes out

Buster is already  off our list as that hit the 2 year
mark in AUg 2021.

OpenSUSE Leap 15.2 was EOL'd by SUSE themselves in Jan 2022,
We use it as a proxy for SLES, but I think we can required
SLES 15 sp3.

FreeBSD 12 is something we still support until April 2023,
but arguably we only care about CLang there.

NetBSD 9 wasn't listed, but it was reported to required
GCC 7.4  (commit 3830df5f83b9b52d9496763ce1a50afb9231c998)
and that is still the latest release of NetBSD.

So NetBSD is our biggest constraint on requiring GCC 10

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 :|




Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-14 Thread Paolo Bonzini

On 3/14/22 15:07, Stefan Hajnoczi wrote:

If we can reach a consensus about C++ language usage in QEMU then I'm in
favor of using C++ coroutines. It's probably not realistic to think we
can limit C++ language usage to just coroutines forever. Someone finds
another C++ feature they absolutely need and over time the codebase
becomes C++ - with both its advantages and disadvantages.

[...] although you can write C in C++, it's not idiomatic modern C++.
The language lends itself to a different style of programming that
some will embrace while others will not.


Yes, this is an important aspect to discuss.  I think coroutines provide 
a good blueprint for how QEMU might use C++.


I totally agree that, if we go this way, the genie is out of the bottle 
and other uses of C++ will pop up with 100% probability.  But the 
important thing to note is that our dialect of C is already not standard 
C, and that some of our or GLib's "innovations" are actually based on 
experience with C++.  We can keep on writing "QEMU's C" if we think of 
C++ as a supercharged way of writing these quality-of-life improvements 
that we already write.  In some sense coroutines are an extreme example 
of this idea.


In fact, a C API would have to remain unless all source files are 
changed to C++, so QEMU would remain mostly a C project with C idioms, 
but that doesn't prevent _abstracting_ the use of C++ features (written 
in modern, idiomatic C++) behind an API that C programmers have no 
problems learning.  Again, coroutines are an example of this of keeping 
the familiar create/enter/yield API and hiding the "magic" of C++ 
coroutines (and when they don't, that had better be an improvement).


In the end, C++ is a tool that you can use if it leads to better code. 
For example, I don't see much use of C++ for devices for example, and 
the storage devices in particular do not even need coroutines because 
they use the callback-based interface.  But perhaps someone will try to 
use templates to replace repeated inclusion (which is common in 
hw/display) and others will follow suit.  Or perhaps not.


One example that was brought up on IRC is type-safe operations on things 
such as hwaddr (i.e. hwaddr+int is allowed but hwaddr-hwaddr gives back 
an int64_t and might even check for overflow).  These would be opt in 
(you get them just by changing a file from .c to .cc), but the actual 
C++ code would still look very much like C code that uses hwaddr with no 
type checking.  All the operator overloading gunk would be in include/.


A different topic is what would happen if all of QEMU could be compiled 
as C++, and could inform our selection of C++ idioms even long before we 
get there.  For example, I'm fine with GLib and our type-safe intrusive 
lists, so I don't have much interest in STL containers and I would 
prefer _not_ to use STL containers even in .cc files[1].  However, 
perhaps QEMU's home-grown lock guard might be replaced by something that 
uses C++ destructors instead of g_autoptr, so perhaps we should consider 
using std::lock_guard<>, or something like that, instead of 
QEMU_LOCK_GUARD.  It may be interesting to pass down lock_guards as 
arguments to enforce "this lock is taken" invariants.


But really, coroutines would be enough work so my dish would be full for 
some time and I wouldn't really have time to look at any of this. :)


Thanks,

Paolo

[1] One big advantage of STL containers for example is that 
std::vector<> automatically constructs objects instead of just filling 
memory with zero (or leaving it uninitialized).  But that doesn't really 
matter if we don't use classes with constructors.




Re: [PATCH experiment 00/16] C++20 coroutine backend

2022-03-14 Thread Stefan Hajnoczi
On Mon, Mar 14, 2022 at 10:31:47AM +0100, Paolo Bonzini wrote:
> However, there  are no ramifications to actual coroutine code, except
> for the template syntax "CoroutineFn" for the function and
> the mandatory co_await/co_return keywords... both of which are an
> improvement, really: the fact that a single function cannot run either
> inside or outside coroutines is checked by the compiler now, because
> qemu_coroutine_create accepts a function that returns CoroutineFn.

Yeah, these are nice.

> One important difference is that C++ coroutines allocate frames on the
> heap, and that explains why performance is better in /perf/nesting,
> which has to do many large memory allocations for the stack in the other
> two backends (and also a makecontext/swapcontext in the ucontext case).
> C++ coroutines hardly benefit from the coroutine pool; OTOH that also
> means the coroutine pool could be removed if we went this way.

Removing the pool would be nice.

> Overall this was ~twice the amount of work of the C experiment, but
> that's because the two are very different ways to achieve the same goal:
> 
> - the design work was substantially smaller in the C experiment, where
> all the backend does is allocate stack frames and do a loop that invokes
> a function pointer.  Here the backend has to map between the C++ concepts
> and the QEMU API.  In the C case, most of the work was really in the
> manual conversion which I had to do one function at a time.
> 
> - the remaining work is also completely different: a source-to-source
> translator (and only build system work in QEMU) for the C experiment;
> making ~100 files compile in C++ for this one (and relatively little
> work as far as coroutines are concerned).
> 
> This was compiled with GCC 11 only.  Coroutine support was added in
> GCC 10, released in 2020, which IIRC is much newer than the most recent
> release we support.

Using C++ coroutines is likely to be lower risk than maintaining our own
C coroutine source-to-source translator. On the other hand, it exposes
QEMU developers to C++ whether they like it or not so it may not be
popular.

If we can reach a consensus about C++ language usage in QEMU then I'm in
favor of using C++ coroutines. It's probably not realistic to think we
can limit C++ language usage to just coroutines forever. Someone finds
another C++ feature they absolutely need and over time the codebase
becomes C++ - with both its advantages and disadvantages. I'm not sure
what the best solution is but this sounds like a recipe for an identity
crisis with the potential to cause friction for years. From that
perspective I feel it's better to allow C++ and get over it although
what I'd really like is just C++ coroutines and nothing else :P.

To add some more detail, although you can write C in C++, it's not
idiomatic modern C++. The language lends itself to a different style of
programming that some will embrace while others will not. It will be a
bigger impedance mismatch than anything currently in the codebase (e.g.
glib vs non-glib code).

On the other hand, a number of projects have already gone through a
transition like this (gcc, gdb, ...). Maybe we can learn from their
mistakes?

Stefan


signature.asc
Description: PGP signature


[PATCH experiment 00/16] C++20 coroutine backend

2022-03-14 Thread Paolo Bonzini
It turns out that going from a prototype C++ implementation of the QEMU
API, to something that could build tests/unit/test-coroutine, was just a
few hours work; and once it compiled, only one line had to be changed
for every test to pass.

Most of the differences between C and C++ already show up here:

- keywords such as "new" (or "class", which I didn't encounter yet)

- _Generic must be replaced by templates and/or overloading (QemuCoLockable
is implemented completely different from QemuLockable, in fact I spent
most of the time on that)

- PRI* functions must be separated with a space from string constants that
precede it

- void* casts must be explicit (g_new takes care of that most of the time,
but not for opaque pointers passed to coroutine).

There are 300 lines of hard-core C++ in the backend and in
coroutine.h.  I tried to comment it as much as possible (this
time I didn't include a big commit message on stackless coroutines
in general) but it still requires some knowledge of the basic C++
coroutine concepts of resumable types, promise types and awaiter types.
https://www.youtube.com/watch?v=ZTqHjjm86Bw is an excellent introduction
and it's where I learnt most of what was needed.

However, there  are no ramifications to actual coroutine code, except
for the template syntax "CoroutineFn" for the function and
the mandatory co_await/co_return keywords... both of which are an
improvement, really: the fact that a single function cannot run either
inside or outside coroutines is checked by the compiler now, because
qemu_coroutine_create accepts a function that returns CoroutineFn.
Therefore I had to disable some more code in util/ and qapi/ that used
qemu_in_coroutine() or coroutine_fn.

Here is the performance comparison of the three backends:

   ucontext   stackless C   stackless C++
/perf/lifecycle0.068 s0.025 s   0.065 s
/perf/nesting  55 s   4.7 s 1.7 s
/perf/yield6.0 s  1.3 s 1.3 s
/perf/cost 8 Mops/s (125ns)   35 ns 1 Mops/s (99 ns)

One important difference is that C++ coroutines allocate frames on the
heap, and that explains why performance is better in /perf/nesting,
which has to do many large memory allocations for the stack in the other
two backends (and also a makecontext/swapcontext in the ucontext case).
C++ coroutines hardly benefit from the coroutine pool; OTOH that also
means the coroutine pool could be removed if we went this way.

I haven't checked why /perf/lifecycle (and therefore /perf/cost; they
are roughly the same test) is so much slower than the handwritten C code.
It's still comparable with the ucontext backend though.

Overall this was ~twice the amount of work of the C experiment, but
that's because the two are very different ways to achieve the same goal:

- the design work was substantially smaller in the C experiment, where
all the backend does is allocate stack frames and do a loop that invokes
a function pointer.  Here the backend has to map between the C++ concepts
and the QEMU API.  In the C case, most of the work was really in the
manual conversion which I had to do one function at a time.

- the remaining work is also completely different: a source-to-source
translator (and only build system work in QEMU) for the C experiment;
making ~100 files compile in C++ for this one (and relatively little
work as far as coroutines are concerned).

This was compiled with GCC 11 only.  Coroutine support was added in
GCC 10, released in 2020, which IIRC is much newer than the most recent
release we support.

Paolo

Paolo Bonzini (17):
  coroutine: add missing coroutine_fn annotations for CoRwlock functions
  coroutine: qemu_coroutine_get_aio_context is not a coroutine_fn
  coroutine: small code cleanup in qemu_co_rwlock_wrlock
  coroutine: introduce QemuCoLockable
  port atomic.h to C++
  use g_new0 instead of g_malloc0
  start porting compiler.h to C++
  tracetool: add extern "C" around generated headers
  start adding extern "C" markers
  add space between liter and string macro
  bump to C++20
  remove "new" keyword from trace-events
  disable some code
  util: introduce C++ stackless coroutine backend
  port QemuCoLockable to C++ coroutines
  port test-coroutine to C++ coroutines

 configure |  48 +-
 include/block/aio.h   |   5 +
 include/fpu/softfloat-types.h |   4 +
 include/qemu/atomic.h |   5 +
 include/qemu/bitops.h |   3 +
 include/qemu/bswap.h  |  10 +-
 include/qemu/co-lockable.h|  93 
 include/qemu/compiler.h   |   4 +
 include/qemu/coroutine.h  | 466 +-
 include/qemu/coroutine_int.h  |   8 +
 include/qemu/host-utils.h |   4 +
 include/qemu/lockable.h