From: Anthony Liguori <anthony@codemonkey.ws>
To: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Alexander Graf <agraf@suse.de>, Avi Kivity <avi@redhat.com>,
Marcelo Tosatti <mtosatti@redhat.com>,
kvm@vger.kernel.org
Subject: Re: [PATCH kvm-unit-tests 2/4] Introduce a C++ wrapper for the kvm APIs
Date: Sun, 28 Nov 2010 16:04:34 -0600 [thread overview]
Message-ID: <4CF2D1F2.8030309@codemonkey.ws> (raw)
In-Reply-To: <20101128122737.GC11685@redhat.com>
On 11/28/2010 06:27 AM, Michael S. Tsirkin wrote:
> On Wed, Nov 24, 2010 at 08:41:26AM -0600, Anthony Liguori wrote:
>
>> On 11/24/2010 06:59 AM, Alexander Graf wrote:
>>
>>> On 24.11.2010, at 11:52, Avi Kivity wrote:
>>>
>>>
>>>> Introduce exception-safe objects for calling system, vm, and vcpu ioctls.
>>>>
>>>> Signed-off-by: Avi Kivity<avi@redhat.com>
>>>>
>>> FWIW, I still disagree with C++ and believe this code to be hardly readable.
>>>
>> There's a general prettiness that well written C++ code will have
>> over C when there's heavy object modelling. This can be subjective
>> but for me, it's fairly significant.
>>
> My guess is this comes from the fact that you are rewriting large pieces
> of code from scratch so it suits your personal style perfectly :)
>
That's probably a good observations.
> If history teaches us anything, as with most projects in qemu, what we will
> end up with is a half done conversion of maybe 30% of the codebase.
> The result might be anything: safer, more correct - but it won't be prettier.
>
This is where things need to be different. I'm not at all interested in
"introducing" C++ to QEMU because of exactly what you describe above.
I think the only viable approach is one where we have a segregated code
base that is correct with an incremental movement of code from the "old"
code base to the new way of doing things.
I've always thought that the device model should be a library and I
think that's the way to structure it. Have a libqemuhw and only move
devices into it as they are converted properly.
>> The fact that objects are easily created on the stack and on the
>> heap is also pretty significant.
>>
> Significant how?
>
> To create an object on the stack, you must have the class definition in
> a public header and a public constructor/destructor.
> This is exactly the same in C.
>
It's really more of a design statement than a statement about C++ vs. C.
In qdev today, we mix object initialization with a user-exposed
factory. This means that you cannot do something simple like:
struct i440fx {
struct piix3 piix;
};
void i440fx_init(struct i440fx_init *obj) {
piix3_init(&obj->piix);
}
But rather need to use ugly factory functions with all sorts of
DO_UPCAST. This is really unfriendly especially for writing test cases.
But this isn't C vs. C++, this is just about device model design. I
think C++ makes it quite a bit more obvious though how to design
correctly though.
>> In real hardware, the i8042 (keyboard controller) is actually
>> implemented in the PIIX3 which is a chip that is part of the i440fx.
>> The i440fx acts as both the memory controller and as the PCI Host
>> controller. So you get something that looks like:
>>
>> class PIIX3 : public PCIDevice
>> {
>> private:
>> I8042 i8042;
>> RTC rtc;
>> // ...
>> };
>>
>> class I440FX : public PCIHostController
>> {
>> I440FX(void) {
>> this->slots[1].plug(&this->piix3); // piix3 is always in slot 1
>> }
>>
>> private:
>> Plug<PCIDevice *> slots[32]; // slot 0 is the PMC
>> PIIX3 piix3;
>> };
>>
>
> We can have the same thing today. In fact, getting rid of the UP_CAST
> and opaque pointers should be a priority.
>
I find that you end up writing a lot more boiler plate code trying to do
this properly in C. I think gobject is probably the best example of
this. If you've ever written a GTK widget from scratch in C and then
written one in gtkmm, the difference is night and day.
>> So whereas we have this very complicate machine create function that
>> attempts to create and composite all of these devices after the
>> fact, when written in C++, partially due to good design, but
>> partially due to the fact that the languages forces you to think a
>> certain way, you get a tremendous simplification.
>>
>> A proper C++ device model turns a vast majority of our device
>> creation complexity into a single new I440FX. Then it's just a
>> matter of instantiating and plugging the appropriate set of PCI
>> devices.
>>
>> Of course, this can be wrapped in a factory to make it drivable via
>> an API or config file.
>>
>> Another area that C++ shines is safety. C++ enables you to inject
>> safe versions of things that you really can't do in C. For
>> instance, the PIT has three channels but the mask to select a
>> channel is two bits. There was a kernel exploit that found a way to
>> trick selection of a forth channel because of a missing check.
>>
>> In C++, you can convert:
>>
>> PITChannel channnels[3];
>>
>> Into:
>>
>> Array<PITChannel, 3> channels;
>>
>> It behaves in every other way just like a normal array. The memory
>> is stack allocated, the type has a fixed size. The only difference
>> is that you can overload the [] operators and implement bounds
>> checking for array accesses. This means that as long as you use
>> Array<>, array overflows disappear from the code base. That's a big
>> deal.
>>
> Except that you get used to the fact that [] is safe,
> and then forget to check the value in a dynamically
> sized array access. Boom.
>
I don't think the fact that you get deterministic vs. non-deterministic
behavior changes the approach people take to using arrays. If it simply
threw away invalid accesses, I might buy your argument. But anyone that
catches an out of bound exception as a normal error handling mechanism
deserves to get beaten with a three day old trout.
>> Another area C++ shines is generating metacode. Consider the
>> ugliness around VMState. The crux of the problem is that it's not
>> possible to write type-neutral code in C. This all gets simplified
>> with C++. Instead of having a bunch of macros like:
>>
>> VMSTATE_INT8(val0, ...)
>> VMSTATE_INT16(val1, ...)
>>
>> You can just have:
>>
>> vmstate(val0)
>> vmstate(val1)
>>
>> And use type overloading to implement different behaviors. Combined
>> with template specialization and an Array wrapper, the same thing
>> works for arrays too.
>>
>> Regards,
>>
>> Anthony Liguori
>>
>> Regards,
>>
>> Anthony Liguori
>>
> At least with VMSTATE_INT16 I can grep and find the definition.
>
grep 'vmstate(.*, int16_t' *.hpp
Works perfectly fine.
Regards,
Anthony Liguori
>
>>> Alex
>>>
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe kvm" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe kvm" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
next prev parent reply other threads:[~2010-11-28 22:04 UTC|newest]
Thread overview: 130+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-11-24 10:52 [PATCH kvm-unit-tests 0/4] API test framework Avi Kivity
2010-11-24 10:52 ` [PATCH kvm-unit-tests 1/4] Makefile: add support for C++ Avi Kivity
2010-11-24 10:52 ` [PATCH kvm-unit-tests 2/4] Introduce a C++ wrapper for the kvm APIs Avi Kivity
2010-11-24 12:59 ` Alexander Graf
2010-11-24 13:33 ` Gleb Natapov
2010-11-24 14:18 ` Anthony Liguori
2010-11-24 14:24 ` Anthony Liguori
2010-11-24 14:32 ` Avi Kivity
2010-11-24 14:31 ` Avi Kivity
2010-11-24 14:41 ` Anthony Liguori
2010-11-24 15:40 ` Gleb Natapov
2010-11-24 15:50 ` Anthony Liguori
2010-11-24 16:10 ` Avi Kivity
2010-12-02 13:52 ` Mike Day
2010-11-24 16:12 ` [PATCH kvm-unit-tests 2/4] " Gleb Natapov
2010-11-24 16:14 ` Avi Kivity
2010-11-24 16:21 ` Gleb Natapov
2010-11-24 16:25 ` Avi Kivity
2010-11-24 16:29 ` Gleb Natapov
2010-11-24 16:33 ` Avi Kivity
2010-11-24 16:52 ` Gleb Natapov
2010-11-24 16:56 ` Avi Kivity
2010-11-24 17:02 ` Gleb Natapov
2010-11-24 17:07 ` Avi Kivity
2010-11-24 17:10 ` Jes Sorensen
2010-11-24 17:12 ` Avi Kivity
2010-11-24 17:14 ` Anthony Liguori
2010-11-24 16:43 ` Anthony Liguori
2010-11-24 16:48 ` Gleb Natapov
2010-11-24 16:56 ` Anthony Liguori
2010-11-24 17:04 ` Gleb Natapov
2010-11-24 16:40 ` Anthony Liguori
2010-11-24 17:33 ` Gleb Natapov
2010-11-24 17:39 ` Avi Kivity
2010-11-24 17:41 ` Gleb Natapov
2010-11-24 17:50 ` Avi Kivity
2010-11-24 18:23 ` Gleb Natapov
2010-11-24 18:50 ` Avi Kivity
2010-11-24 18:17 ` Anthony Liguori
2010-11-24 18:34 ` Gleb Natapov
2010-11-24 18:53 ` Anthony Liguori
2010-11-25 8:35 ` Gleb Natapov
2010-11-24 16:40 ` Jes Sorensen
2010-11-24 16:47 ` Avi Kivity
2010-11-24 16:51 ` Jes Sorensen
2010-11-24 16:57 ` Anthony Liguori
2010-11-24 17:29 ` Avi Kivity
2010-11-24 16:59 ` Avi Kivity
2010-11-24 17:06 ` Jes Sorensen
2010-11-24 17:11 ` Avi Kivity
2010-11-24 17:17 ` Jes Sorensen
2010-11-24 17:25 ` Avi Kivity
2010-11-24 17:28 ` Jes Sorensen
2010-11-24 17:31 ` Avi Kivity
2010-11-24 17:36 ` Gleb Natapov
2010-11-24 17:41 ` Avi Kivity
2010-11-24 17:27 ` Anthony Liguori
2010-11-24 17:35 ` Avi Kivity
2010-11-24 17:36 ` Jes Sorensen
2010-11-24 17:41 ` Avi Kivity
2010-11-24 17:43 ` Gleb Natapov
2010-11-24 17:50 ` Avi Kivity
2010-11-24 18:10 ` Gleb Natapov
2010-11-24 18:55 ` Avi Kivity
2010-11-24 19:29 ` Jes Sorensen
2010-11-24 19:33 ` Avi Kivity
2010-11-24 17:43 ` Jes Sorensen
2010-11-24 17:51 ` Avi Kivity
2010-11-24 17:43 ` Anthony Liguori
2010-11-24 17:45 ` Jes Sorensen
2010-11-24 17:51 ` Avi Kivity
2010-11-24 18:01 ` Anthony Liguori
2010-11-24 18:56 ` Avi Kivity
2010-11-24 16:55 ` Gleb Natapov
2010-11-24 17:01 ` Avi Kivity
2010-11-24 17:16 ` Gleb Natapov
2010-11-24 17:26 ` Avi Kivity
2010-11-24 16:53 ` Anthony Liguori
2010-11-24 17:03 ` Jes Sorensen
2010-11-28 12:27 ` Michael S. Tsirkin
2010-11-28 22:04 ` Anthony Liguori [this message]
2010-11-28 22:28 ` Michael S. Tsirkin
2010-11-28 23:13 ` Anthony Liguori
2010-11-29 8:04 ` Michael S. Tsirkin
2010-11-29 13:44 ` Anthony Liguori
2010-11-29 13:48 ` Avi Kivity
2010-11-24 16:29 ` Jes Sorensen
2010-11-24 16:34 ` Avi Kivity
2010-11-24 16:44 ` Jes Sorensen
2010-11-24 16:49 ` Avi Kivity
2010-11-28 11:59 ` Michael S. Tsirkin
2010-11-28 13:02 ` Avi Kivity
2010-11-28 13:57 ` Michael S. Tsirkin
2010-11-28 14:34 ` Avi Kivity
2010-11-28 16:57 ` Michael S. Tsirkin
2010-11-29 9:22 ` Avi Kivity
2010-11-29 10:47 ` Michael S. Tsirkin
2010-11-29 10:52 ` Avi Kivity
2010-11-29 11:26 ` Michael S. Tsirkin
2010-11-29 13:38 ` Anthony Liguori
2010-11-24 14:10 ` Anthony Liguori
2010-11-24 14:29 ` Avi Kivity
2010-11-24 14:45 ` Anthony Liguori
2010-11-24 14:53 ` Avi Kivity
2010-11-24 14:55 ` Anthony Liguori
2010-11-25 16:32 ` Avi Kivity
2010-11-26 10:16 ` Michael S. Tsirkin
[not found] ` <4CF0CB9A.5060403@redhat.com>
2010-11-28 8:58 ` Michael S. Tsirkin
2010-11-28 9:31 ` Avi Kivity
2010-11-28 9:50 ` Michael S. Tsirkin
2010-11-28 9:54 ` Avi Kivity
2010-11-28 11:44 ` Michael S. Tsirkin
2010-11-28 13:14 ` Avi Kivity
2010-11-28 14:40 ` Michael S. Tsirkin
2010-11-28 22:12 ` Anthony Liguori
2010-11-29 9:30 ` Avi Kivity
2010-11-28 11:49 ` Michael S. Tsirkin
2010-11-28 13:15 ` Avi Kivity
2010-11-28 14:49 ` Michael S. Tsirkin
2010-11-29 9:30 ` Avi Kivity
2010-11-24 10:52 ` [PATCH kvm-unit-tests 3/4] Add support for calling a function in guest mode Avi Kivity
2010-11-26 14:17 ` Michael S. Tsirkin
[not found] ` <4CF0CC26.8030407@redhat.com>
2010-11-28 8:59 ` Michael S. Tsirkin
2010-11-28 9:22 ` Avi Kivity
2010-11-24 10:52 ` [PATCH kvm-unit-tests 4/4] Add sample test using the api test harness Avi Kivity
2010-11-26 14:17 ` Michael S. Tsirkin
[not found] ` <4CF0CC4A.8070100@redhat.com>
2010-11-28 9:04 ` Michael S. Tsirkin
2010-11-28 9:21 ` Avi Kivity
2010-11-29 16:09 ` [PATCH kvm-unit-tests 0/4] API test framework Marcelo Tosatti
2010-12-01 10:38 ` Avi Kivity
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=4CF2D1F2.8030309@codemonkey.ws \
--to=anthony@codemonkey.ws \
--cc=agraf@suse.de \
--cc=avi@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=mst@redhat.com \
--cc=mtosatti@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox