* [Qemu-devel] [RfC PATCH 0/2] qdev/prop: macros for creating typechecked properties. @ 2009-07-31 13:04 Gerd Hoffmann 2009-07-31 13:04 ` [Qemu-devel] [RfC PATCH 1/2] " Gerd Hoffmann 2009-07-31 13:04 ` [Qemu-devel] [RfC PATCH 2/2] qdev/prop: convert pci.c to helper macros Gerd Hoffmann 0 siblings, 2 replies; 6+ messages in thread From: Gerd Hoffmann @ 2009-07-31 13:04 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Hi folks, Continuing the property macro debate with some code. Two patches, one adding macros, one converting pci.c as an example. I volunteer to send patches switching all properties over to macros. But given the discussions we had on the topic so far I'd like to have a agreement on the route to take before, so my work wouldn't end up in the trash. cheers, Gerd ^ permalink raw reply [flat|nested] 6+ messages in thread
* [Qemu-devel] [RfC PATCH 1/2] qdev/prop: macros for creating typechecked properties. 2009-07-31 13:04 [Qemu-devel] [RfC PATCH 0/2] qdev/prop: macros for creating typechecked properties Gerd Hoffmann @ 2009-07-31 13:04 ` Gerd Hoffmann 2009-07-31 13:04 ` [Qemu-devel] [RfC PATCH 2/2] qdev/prop: convert pci.c to helper macros Gerd Hoffmann 1 sibling, 0 replies; 6+ messages in thread From: Gerd Hoffmann @ 2009-07-31 13:04 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann There are DEFINE_PROP_$TYPE("name", struct, field, default) macros for each property type. These macros link the qdev_prop_$name struct to the type used by that property. typeof(struct->field) is verifyed to be the correct one for the given property. This uses gcc extentions, but as it is a check only it could easily be turned off for non-gcc compilers if needed. The error message given by the compiler isn't that great, I didn't manage to make the compiler print something more helpful than "error: initializer element is not constant". Ideally I'd like to somehow generate a message containing the variable referenced by the macro reference in the failure case, so we could use the variable name to transport the message ... Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/qdev-addr.h | 3 +++ hw/qdev.h | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 0 deletions(-) diff --git a/hw/qdev-addr.h b/hw/qdev-addr.h index f02bd7a..9568c27 100644 --- a/hw/qdev-addr.h +++ b/hw/qdev-addr.h @@ -1,2 +1,5 @@ +#define DEFINE_PROP_TADDR(_n, _s, _f) \ + DEFINE_PROP(_n, _s, _f, qdev_prop_taddr, target_phys_addr_t) + extern PropertyInfo qdev_prop_taddr; void qdev_prop_set_taddr(DeviceState *dev, const char *name, target_phys_addr_t value); diff --git a/hw/qdev.h b/hw/qdev.h index b342afb..4fe534e 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -156,6 +156,46 @@ extern PropertyInfo qdev_prop_ptr; extern PropertyInfo qdev_prop_macaddr; extern PropertyInfo qdev_prop_pci_devfn; +extern int qdev_property_type_check_failed; /* undefined */ +#define typeof_field(type, field) typeof(((type *)0)->field) +#define type_check(t1,t2) __builtin_choose_expr( \ + __builtin_types_compatible_p(t1,t2),0,qdev_property_type_check_failed) + +#define DEFINE_PROP(_name, _state, _field, _prop, _type) { \ + .name = (_name), \ + .info = &(_prop), \ + .offset = offsetof(_state, _field) \ + + type_check(_type,typeof_field(_state, _field)), \ + } +#define DEFINE_PROP_DEFAULT(_name, _state, _field, _defval, _prop, _type) { \ + .name = (_name), \ + .info = &(_prop), \ + .offset = offsetof(_state, _field) \ + + type_check(_type,typeof_field(_state, _field)), \ + .defval = (_type[]) { _defval }, \ + } + +#define DEFINE_PROP_UINT16(_n, _s, _f, _d) \ + DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t) +#define DEFINE_PROP_UINT32(_n, _s, _f, _d) \ + DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t) +#define DEFINE_PROP_UINT64(_n, _s, _f, _d) \ + DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t) +#define DEFINE_PROP_HEX32(_n, _s, _f, _d) \ + DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex32, uint32_t) +#define DEFINE_PROP_HEX64(_n, _s, _f, _d) \ + DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex64, uint64_t) +#define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \ + DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_pci_devfn, uint32_t) + +#define DEFINE_PROP_PTR(_n, _s, _f) \ + DEFINE_PROP(_n, _s, _f, qdev_prop_ptr, void*) +#define DEFINE_PROP_MACADDR(_n, _s, _f) \ + DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, uint8_t[6]) + +#define DEFINE_PROP_END_OF_LIST() \ + {} + /* Set properties between creation and init. */ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop); int qdev_prop_parse(DeviceState *dev, const char *name, const char *value); -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [RfC PATCH 2/2] qdev/prop: convert pci.c to helper macros. 2009-07-31 13:04 [Qemu-devel] [RfC PATCH 0/2] qdev/prop: macros for creating typechecked properties Gerd Hoffmann 2009-07-31 13:04 ` [Qemu-devel] [RfC PATCH 1/2] " Gerd Hoffmann @ 2009-07-31 13:04 ` Gerd Hoffmann 2009-07-31 14:32 ` Michael S. Tsirkin 1 sibling, 1 reply; 6+ messages in thread From: Gerd Hoffmann @ 2009-07-31 13:04 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/pci.c | 9 ++------- hw/pci.h | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index 4d0cdc7..27eac04 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -60,13 +60,8 @@ static struct BusInfo pci_bus_info = { .size = sizeof(PCIBus), .print_dev = pcibus_dev_print, .props = (Property[]) { - { - .name = "addr", - .info = &qdev_prop_pci_devfn, - .offset = offsetof(PCIDevice, devfn), - .defval = (uint32_t[]) { -1 }, - }, - {/* end of list */} + DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1), + DEFINE_PROP_END_OF_LIST() } }; diff --git a/hw/pci.h b/hw/pci.h index cbfea6a..a2ec16a 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -177,7 +177,7 @@ struct PCIDevice { /* the following fields are read only */ PCIBus *bus; - int devfn; + uint32_t devfn; char name[64]; PCIIORegion io_regions[PCI_NUM_REGIONS]; -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [RfC PATCH 2/2] qdev/prop: convert pci.c to helper macros. 2009-07-31 13:04 ` [Qemu-devel] [RfC PATCH 2/2] qdev/prop: convert pci.c to helper macros Gerd Hoffmann @ 2009-07-31 14:32 ` Michael S. Tsirkin 2009-07-31 15:01 ` Gerd Hoffmann 2009-07-31 15:42 ` Gerd Hoffmann 0 siblings, 2 replies; 6+ messages in thread From: Michael S. Tsirkin @ 2009-07-31 14:32 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: qemu-devel On Fri, Jul 31, 2009 at 03:04:59PM +0200, Gerd Hoffmann wrote: > > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> > --- > hw/pci.c | 9 ++------- > hw/pci.h | 2 +- > 2 files changed, 3 insertions(+), 8 deletions(-) > > diff --git a/hw/pci.c b/hw/pci.c > index 4d0cdc7..27eac04 100644 > --- a/hw/pci.c > +++ b/hw/pci.c > @@ -60,13 +60,8 @@ static struct BusInfo pci_bus_info = { > .size = sizeof(PCIBus), > .print_dev = pcibus_dev_print, > .props = (Property[]) { > - { > - .name = "addr", > - .info = &qdev_prop_pci_devfn, > - .offset = offsetof(PCIDevice, devfn), > - .defval = (uint32_t[]) { -1 }, > - }, > - {/* end of list */} > + DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1), > + DEFINE_PROP_END_OF_LIST() > } I think the type safety is an important addition. Unfortunately there's still duplication - in the macro definition: DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t) which leaves room for mistakes. And there will have to be lots of these macros, for each type. Here's an idea: if each property exposed a "type" field, documenting what type it supports, we could use that for a type-safe macro. Along the lines of: - .info = &qdev_prop_pci_devfn, - .offset = offsetof(PCIDevice, devfn), + QDEV_INFO(&qdev_prop_pci_devfn, PCIDevice, devfn), Where QDEV_INFO would be defined as something like: #define QDEV_INFO(_prop, _struct, _field) \ .info = (_prop), \ .offset = (offsetof(_struct, _field) + ( 0 && \ (long)(&(_prop)->type - &((_struct *)0)->_field)) \ ) Defval could be checked in a similar fashion. This seems to be free of gcc extensions and gives more or less sane errors like: foo.c:26: error: invalid operands to binary - (have ‘long long int *’ and ‘int *’) This way we need only 1 or 2 macros that everyone can use. > }; > > diff --git a/hw/pci.h b/hw/pci.h > index cbfea6a..a2ec16a 100644 > --- a/hw/pci.h > +++ b/hw/pci.h > @@ -177,7 +177,7 @@ struct PCIDevice { > > /* the following fields are read only */ > PCIBus *bus; > - int devfn; > + uint32_t devfn; Good catch - with int the value could get sign-extended if we try to decode just the high bits by >>, and shows importance of type-checking. > char name[64]; > PCIIORegion io_regions[PCI_NUM_REGIONS]; > > -- > 1.6.2.5 > Full self-contained toy example below, in case you want to play with my idea some more: #include <stdio.h> #include <stddef.h> struct prop { long long type; }; struct desc { struct prop *info; int offset; }; struct foo { int bar1; long long bar2; }; #define QDEV_INFO(_prop, _struct, _field) \ .info = (_prop), \ .offset = (offsetof(_struct, _field) + ( 0 && \ (long)(&(_prop)->type - &((_struct *)0)->_field) \ )) struct prop prop1; struct desc desc1 = { QDEV_INFO(&prop1, struct foo, bar2) }; int main() { printf("offset: %d\n", desc1.offset); return 0; } ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [RfC PATCH 2/2] qdev/prop: convert pci.c to helper macros. 2009-07-31 14:32 ` Michael S. Tsirkin @ 2009-07-31 15:01 ` Gerd Hoffmann 2009-07-31 15:42 ` Gerd Hoffmann 1 sibling, 0 replies; 6+ messages in thread From: Gerd Hoffmann @ 2009-07-31 15:01 UTC (permalink / raw) To: Michael S. Tsirkin; +Cc: qemu-devel On 07/31/09 16:32, Michael S. Tsirkin wrote: > Unfortunately there's still duplication - in the macro definition: > DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t) It has to be somewhere ... > Full self-contained toy example below, in case you want to play with > my idea some more: Can you create a working patch against qemu next time please? > #include<stdio.h> > #include<stddef.h> > > struct prop { > long long type; > }; This is the PropertyInfo aequivalent, right? Note we are using the very same PropertyInfo struct for all property types we have, thus your idea simply doesn't work. We could use a different struct for each type. That wouldn't solve the fundamental issue though, it would just shift it to another place. cheers, Gerd ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [RfC PATCH 2/2] qdev/prop: convert pci.c to helper macros. 2009-07-31 14:32 ` Michael S. Tsirkin 2009-07-31 15:01 ` Gerd Hoffmann @ 2009-07-31 15:42 ` Gerd Hoffmann 1 sibling, 0 replies; 6+ messages in thread From: Gerd Hoffmann @ 2009-07-31 15:42 UTC (permalink / raw) To: Michael S. Tsirkin; +Cc: qemu-devel [-- Attachment #1: Type: text/plain, Size: 363 bytes --] Hi, > (long)(&(_prop)->type -&((_struct *)0)->_field)) \ > This seems to be free of gcc extensions and gives more or less sane errors like: > > foo.c:26: error: invalid operands to binary - (have ‘long long int *’ and ‘int *’) The "better error message" bit works. Nice idea. Incremental patch attached. cheers, Gerd [-- Attachment #2: 0001-better-type-check.patch --] [-- Type: text/plain, Size: 945 bytes --] From cf4d63c456250c7e97705338c3c052fe10a5a4b6 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann <kraxel@redhat.com> Date: Fri, 31 Jul 2009 17:36:01 +0200 Subject: [PATCH] better type check --- hw/qdev.h | 4 +--- 1 files changed, 1 insertions(+), 3 deletions(-) diff --git a/hw/qdev.h b/hw/qdev.h index 4fe534e..e2703f4 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -156,10 +156,8 @@ extern PropertyInfo qdev_prop_ptr; extern PropertyInfo qdev_prop_macaddr; extern PropertyInfo qdev_prop_pci_devfn; -extern int qdev_property_type_check_failed; /* undefined */ #define typeof_field(type, field) typeof(((type *)0)->field) -#define type_check(t1,t2) __builtin_choose_expr( \ - __builtin_types_compatible_p(t1,t2),0,qdev_property_type_check_failed) +#define type_check(t1,t2) ((t1*)0 - (t2*)0) #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \ .name = (_name), \ -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2009-07-31 15:42 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-07-31 13:04 [Qemu-devel] [RfC PATCH 0/2] qdev/prop: macros for creating typechecked properties Gerd Hoffmann 2009-07-31 13:04 ` [Qemu-devel] [RfC PATCH 1/2] " Gerd Hoffmann 2009-07-31 13:04 ` [Qemu-devel] [RfC PATCH 2/2] qdev/prop: convert pci.c to helper macros Gerd Hoffmann 2009-07-31 14:32 ` Michael S. Tsirkin 2009-07-31 15:01 ` Gerd Hoffmann 2009-07-31 15:42 ` Gerd Hoffmann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).