qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [RFC] QEMU Object Model status/merge plan


From: Anthony Liguori
Subject: Re: [Qemu-devel] [RFC] QEMU Object Model status/merge plan
Date: Tue, 13 Dec 2011 10:02:28 -0600
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.21) Gecko/20110831 Lightning/1.0b2 Thunderbird/3.1.13

On 12/13/2011 09:05 AM, Kevin Wolf wrote:
Am 13.12.2011 14:43, schrieb Anthony Liguori:
On 12/13/2011 05:35 AM, Stefan Hajnoczi wrote:
On Mon, Dec 12, 2011 at 7:36 PM, Anthony Liguori<address@hidden>   wrote:
I choose the serial device to showcase what we'll eventually be able to do.
   The three relevant files are:

https://github.com/aliguori/qemu/blob/qom-next/hw/isa-serial.c

https://github.com/aliguori/qemu/blob/qom-next/hw/mm-serial.c

https://github.com/aliguori/qemu/blob/qom-next/hw/serial.c

I'm not sure I understand how init functions are called for derived
classes.

There are three types of init functions:

class_init
==========

This lives in (TypeInit) and is called when a class is first created for a type.
   It is only ever called once.  Within this function, you should override any
methods in your base classes and set default implementations for any methods you
implement.

I guess in most cases this could be replaced by a static table and the
function could be made optional? (That is, there could be a default
implementation for the NULL case)

As it turns out, you can pass an opaque to class_init so you could have something like:

typedef struct PCIDeviceOps {
   void (*foo)(PCIDevice *dev, ...);
   ...
};

And then you could write a generic:

void pci_generic_class_init(ObjectClass *klass, void *data)
{
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
    PCIDeviceOps *ops = data;

    if (ops->foo) {
        k->foo = ops->foo;
    }
}

Which would then let you do:

static PCIDeviceOps e1000_device_ops = {
    .foo = e1000_foo,
    ...
};

static TypeInfo e1000_device_info = {
    .name = TYPE_E1000,
    .parent = TYPE_PCI_DEVICE,
    .instance_size = sizeof(E1000State),
    .class_init = pci_generic_class_init,
    .class_data = &e1000_device_ops,
};

I didn't really plan on this, but it looks like it would work pretty well. It might be reasonable to do for really common devices. I don't think it's all that nice to do for everything though because the *_generic_class_init() functions get really ugly and makes allowing subclassing pretty hard.


instance_init
=============

This is the constructor for a type.  It is called when an object is created and
chained such that the base class constructors are called first to initialize the
object.

Same for this one, in your serial code it looks like this doesn't do
anything interesting in the common case and could be made optional (it
adds an UART child device, but this is static property and should be
moved anyway)

It could potentially, yes. instance_init functions will often times not be needed. It's really meant to do things like initialize lists and stuff like that that property accessors may need to work with.

I think even in the future the really interesting work will be done in
realize.

Yes.  The various TypeInfo methods can all be omitted if they don't do any work.

Regards,

Anthony Liguori


Kevin





reply via email to

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