QOM Super class access
v2 cover QOM Super class access
From: Peter Crosthwaite <[email protected]>
This series enables QOM super class access and demostrates some usages. Replaces the save->override->call via FooClass technique, to reduce some of the boiler plate in recently fully QOMified devices.
Applied the change to ARM CPU, MB CPU and some of Andreas's recently QOMified i386 devices, all which have the save->override->call issue. ARMCPU I've done a brief test on and seems to work.
ARM CPU was particularly difficult, as it has 3 layers of heirachy, where a non-concrete class (TYPE_ARM_CPU) need to super class itself (to TYPE_CPU). This sees the need for super-classers to specify their expected base class level. See patches for illustration.
The main future work to the series is to apply the change pattern to the reset of the tree
changed since V1:
Simplified to use object_class_get_parent_by_type (suggest by Hu Tao)
Peter Crosthwaite (5):
target-arm/cpu.c: delete un-needed instance/class sizes qom/object: Add object_class_get_parent_by_name
target-arm: Use parent classes for reset + realize
target-microblaze: Use parent class for reset + realize
i8254: Use parent class for realize
hw/i386/kvm/i8254.c | 18 +++--------------- hw/timer/i8254.c | 17 +++-------------- include/qom/object.h | 9 +++++++++ qom/object.c | 5 +++++ target-arm/cpu-qom.h | 20 -------------------- target-arm/cpu.c | 18 +++++++----------- target-microblaze/cpu-qom.h | 20 -------------------- target-microblaze/cpu.c | 16 ++++++---------- 8 files changed, 33 insertions(+), 90 deletions(-)
Signature · 1 line
1.8.3.rc1.44.gb387c77.dirty
PATCH v2 1/5 target-arm/cpu.c: delete un-needed instance/class sizes
From: Peter Crosthwaite <[email protected]>
QOM automatically inherits class and instance size from the parent class. No need to redefine as the same value as the parent.
---
target-arm/cpu.c | 2 -- 1 file changed, 2 deletions(-)
target-arm/cpu.c +0 -2
@@ -823,9 +823,7 @@ static void cpu_register(const ARMCPUInfo *info) {TypeInfo type_info = { .parent =TYPE_ARM_CPU , - .instance_size =sizeof (ARMCPU ), .instance_init = info->initfn, - .class_size =sizeof (ARMCPUClass), .class_init = info->class_init, };
Signature · 1 line
1.8.3.rc1.44.gb387c77.dirty
Re: [Qemu-devel] [PATCH qom-next v2 1/5] target-arm/cpu.c: delete un-needed instance/class sizes
Am 11.07.2013 03:45, schrieb [email protected]:
Quoted 4 lines
From: Peter Crosthwaite <[email protected]>
QOM automatically inherits class and instance size from the parent class. No need to redefine as the same value as the parent.
Quoting my original comment:
"It would be fair to mention since which commit because that was originally not the case."
http://git.qemu.org/?p=qemu.git;a=commit;h=aca59af612840772f18598363b65a25bf02bb569
E.g., "By now, QOM automatically..." or "Since commit ..."
Quoted 2 lines
We have an active ARM maintainer, so no reason to involve qemu-trivial here by our definition. Possibly that would've required Cc: anyway? Not actually CC'ed.
Quoted 2 lines
Signed-off-by Peter Crosthwaite <[email protected]>
Still:
PMM, do you want to pick this one up for target-arm.next? The rest depends on central infrastructure under discussion. Suggest renaming to "target-arm: Delete un-needed instance/class sizes for ARMCPU subclasses" for simplicity and so that it aligns nicely with others.
Regards,
Andreas
Quoted 19 lines
---
target-arm/cpu.c | 2 -- 1 file changed, 2 deletions(-)target-arm/cpu.c +0
-2@@ -823,9 +823,7 @@ static void cpu_register(const ARMCPUInfo *info) {TypeInfo type_info = { .parent =TYPE_ARM_CPU , - .instance_size =sizeof (ARMCPU ), .instance_init = info->initfn, - .class_size =sizeof (ARMCPUClass), .class_init = info->class_init, };
Signature · 2 lines
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH qom-next v2 1/5] target-arm/cpu.c: delete un-needed instance/class sizes
Quoted 4 lines · Andreas Färber
PMM, do you want to pick this one up for target-arm.next? The rest depends on central infrastructure under discussion. Suggest renaming to "target-arm: Delete un-needed instance/class sizes for ARMCPU subclasses" for simplicity and so that it aligns nicely with others.
I really prefer not to pick up single patches from a series, it is awkward. A patch series should be a coherent set which is picked up by whichever subtree it is overall most fitted to. (Similarly, cc'ing qemu-trivial on one or two patches out of a set doesn't make much sense.)
thanks
-- PMM
PATCH v2 2/5 qom/object: Add object_class_get_parent_by_name
In reply to [email protected]From: Peter Crosthwaite <[email protected]>
Function for looking up a class by name then getting its parent.
---
include/qom/object.h | 9 +++++++++ qom/object.c | 5 +++++ 2 files changed, 14 insertions(+)
include/qom/object.h +9 -0
@@ -706,6 +706,15 @@ ObjectClass *object_class_dynamic_cast(ObjectClass *klass,ObjectClass *object_class_get_parent (ObjectClass *klass);/** +* object_class_get_parent_by_name: +* Lookup a class by name and get its parent. +* @typename: The class to lookup and obtain the parent for. +* +* Returns: The parent for @typename's class or %NULL if none. +*/ +ObjectClass *object_class_get_parent_by_name (const char *typename); + +/** * object_class_get_name: * @klass: The class to obtain the QOM typename for. *
qom/object.c +5 -0
@@ -608,6 +608,11 @@ ObjectClass *object_class_get_parent(ObjectClass *class)return type->class; } +ObjectClass *object_class_get_parent_by_name (const char *typename) +{ +return object_class_get_parent (object_class_by_name (typename)); +} + typedef struct OCFData { void (*fn)(ObjectClass *klass, void *opaque);
Signature · 1 line
1.8.3.rc1.44.gb387c77.dirty
PATCH v2 3/5 target-arm: Use parent classes for reset + realize
In reply to [email protected]From: Peter Crosthwaite <[email protected]>
ARMCPUClass is only needed for parent-class abstract function access. Just use parent classes for reset and realize access and remove ARMCPUClass completely.
---
target-arm/cpu-qom.h | 20 -------------------- target-arm/cpu.c | 16 +++++++--------- 2 files changed, 7 insertions(+), 29 deletions(-)
target-arm/cpu-qom.h +0 -20
@@ -24,28 +24,8 @@#define TYPE_ARM_CPU "arm-cpu" -#define ARM_CPU_CLASS (klass) \ - OBJECT_CLASS_CHECK(ARMCPUClass, (klass), TYPE_ARM_CPU)#define ARM_CPU (obj) \ OBJECT_CHECK(ARMCPU, (obj), TYPE_ARM_CPU) -#define ARM_CPU_GET_CLASS (obj) \ - OBJECT_GET_CLASS(ARMCPUClass, (obj), TYPE_ARM_CPU) - -/** -* ARMCPUClass: -* @parent_realize: The parent class' realize handler. -* @parent_reset: The parent class' reset handler. -* -* An ARM CPU model. -*/ -typedef struct ARMCPUClass { -/*< private >*/ -CPUClass parent_class; -/*< public >*/ - -DeviceRealize parent_realize; -void (*parent_reset)(CPUState *cpu); -}ARMCPUClass ;/** * ARMCPU:
target-arm/cpu.c +7 -9
@@ -60,7 +60,8 @@ static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)static void arm_cpu_reset (CPUState *s) {ARMCPU *cpu =ARM_CPU (s); -ARMCPUClass *acc =ARM_CPU_GET_CLASS (cpu); +CPUClass *cc_parent = +CPU_CLASS (object_class_get_parent_by_name (TYPE_ARM_CPU ));CPUARMState *env = &cpu->env;if (qemu_loglevel_mask (CPU_LOG_RESET )) {
@@ -68,7 +69,7 @@ static void arm_cpu_reset(CPUState *s)log_cpu_state (env,0 ); } - acc->parent_reset (s); + cc_parent->reset (s);memset (env,0 , offsetof(CPUARMState , breakpoints));g_hash_table_foreach (cpu->cp_regs, cp_reg_reset, cpu);
@@ -158,7 +159,8 @@ static void arm_cpu_finalizefn(Object *obj)static void arm_cpu_realizefn (DeviceState *dev,Error **errp) {ARMCPU *cpu =ARM_CPU (dev); -ARMCPUClass *acc =ARM_CPU_GET_CLASS (dev); +DeviceClass *dc_parent = +DEVICE_CLASS (object_class_get_parent_by_name (TYPE_ARM_CPU ));CPUARMState *env = &cpu->env;/* Some features automatically imply others: */
@@ -209,7 +211,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)cpu_reset (CPU (cpu)); - acc->parent_realize (dev, errp); + dc_parent->realize (dev, errp); }/* CPU models */
@@ -803,14 +805,11 @@ static const ARMCPUInfo arm_cpus[] = {static void arm_cpu_class_init (ObjectClass *oc,void *data) { -ARMCPUClass *acc =ARM_CPU_CLASS (oc); -CPUClass *cc =CPU_CLASS (acc); +CPUClass *cc =CPU_CLASS (oc);DeviceClass *dc =DEVICE_CLASS (oc); - acc->parent_realize = dc->realize; dc->realize = arm_cpu_realizefn; - acc->parent_reset = cc->reset; cc->reset = arm_cpu_reset; cc->class_by_name = arm_cpu_class_by_name;
@@ -839,7 +838,6 @@ static const TypeInfo arm_cpu_type_info = { .instance_init = arm_cpu_initfn, .instance_finalize = arm_cpu_finalizefn, .abstract = true, - .class_size = sizeof(ARMCPUClass), .class_init = arm_cpu_class_init, };
Signature · 1 line
1.8.3.rc1.44.gb387c77.dirty
Re: [Qemu-devel] [PATCH qom-next v2 3/5] target-arm: Use parent classes for reset + realize
Quoted 51 lines · On Thu, 11 Jul 2013 11:47:16 +1000 [email protected] wrote:
From: Peter Crosthwaite <[email protected]>
ARMCPUClass is only needed for parent-class abstract function access. Just use parent classes for reset and realize access and remove ARMCPUClass completely.
Signed-off-by Peter Crosthwaite <[email protected]>---
target-arm/cpu-qom.h | 20 -------------------- target-arm/cpu.c | 16 +++++++--------- 2 files changed, 7 insertions(+), 29 deletions(-)target-arm/cpu-qom.h +0
-20@@ -24,28 +24,8 @@#define TYPE_ARM_CPU "arm-cpu" -#define ARM_CPU_CLASS (klass) \ - OBJECT_CLASS_CHECK(ARMCPUClass, (klass), TYPE_ARM_CPU)#define ARM_CPU (obj) \ OBJECT_CHECK(ARMCPU, (obj), TYPE_ARM_CPU) -#define ARM_CPU_GET_CLASS (obj) \ - OBJECT_GET_CLASS(ARMCPUClass, (obj), TYPE_ARM_CPU) - -/** -* ARMCPUClass: -* @parent_realize: The parent class' realize handler. -* @parent_reset: The parent class' reset handler. -* -* An ARM CPU model. -*/ -typedef struct ARMCPUClass { -/*< private >*/ -CPUClass parent_class; -/*< public >*/ - -DeviceRealize parent_realize; -void (*parent_reset)(CPUState *cpu); -}ARMCPUClass ;/** * ARMCPU: target-arm/cpu.c +0
-0
target-arm/cpu.c static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque) · line 64
Quoted 6 lines
target-arm/cpu.c +2
-1@@ -60,7 +60,8 @@ static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)static void arm_cpu_reset (CPUState *s) {ARMCPU *cpu =ARM_CPU (s); -ARMCPUClass *acc =ARM_CPU_GET_CLASS (cpu); +CPUClass *cc_parent = +CPU_CLASS (object_class_get_parent_by_name (TYPE_ARM_CPU ));
Maybe object_class_get_parent_of_type() would be less confusing?
This usage assumes that parent of TYPE_ARM_CPU is TYPE_CPU and if another TYPE_X added between them, it might break if TYPE_X doesn't re-implement this logic in its reset.
Could reset be modeled like DEVICE.instance_init() instead? Then no explicit access to parent from child would be needed and it still leaves possibility to override resets if parent->child propagation order is not desirable for a particular device.
Quoted 55 lines
target-arm/cpu.c +5
-8CPUARMState *env = &cpu->env;if (qemu_loglevel_mask (CPU_LOG_RESET )) {@@ -68,7 +69,7 @@ static void arm_cpu_reset(CPUState *s)log_cpu_state (env,0 ); } - acc->parent_reset (s); + cc_parent->reset (s);memset (env,0 , offsetof(CPUARMState , breakpoints));g_hash_table_foreach (cpu->cp_regs, cp_reg_reset, cpu);@@ -158,7 +159,8 @@ static void arm_cpu_finalizefn(Object *obj)static void arm_cpu_realizefn (DeviceState *dev,Error **errp) {ARMCPU *cpu =ARM_CPU (dev); -ARMCPUClass *acc =ARM_CPU_GET_CLASS (dev); +DeviceClass *dc_parent = +DEVICE_CLASS (object_class_get_parent_by_name (TYPE_ARM_CPU ));CPUARMState *env = &cpu->env;/* Some features automatically imply others: */ @@ -209,7 +211,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)cpu_reset (CPU (cpu)); - acc->parent_realize (dev, errp); + dc_parent->realize (dev, errp); }/* CPU models */ @@ -803,14 +805,11 @@ static const ARMCPUInfo arm_cpus[] = {static void arm_cpu_class_init (ObjectClass *oc,void *data) { -ARMCPUClass *acc =ARM_CPU_CLASS (oc); -CPUClass *cc =CPU_CLASS (acc); +CPUClass *cc =CPU_CLASS (oc);DeviceClass *dc =DEVICE_CLASS (oc); - acc->parent_realize = dc->realize; dc->realize = arm_cpu_realizefn; - acc->parent_reset = cc->reset; cc->reset = arm_cpu_reset; cc->class_by_name = arm_cpu_class_by_name;@@ -839,7 +838,6 @@ static const TypeInfo arm_cpu_type_info = { .instance_init = arm_cpu_initfn, .instance_finalize = arm_cpu_finalizefn, .abstract = true, - .class_size = sizeof(ARMCPUClass), .class_init = arm_cpu_class_init, };
Re: [Qemu-devel] [PATCH qom-next v2 3/5] target-arm: Use parent classes for reset + realize
Quoted 62 lines · Igor Mammedov
Quoted 51 lines · On Thu, 11 Jul 2013 11:47:16 +1000 [email protected] wrote:
From: Peter Crosthwaite <[email protected]>
ARMCPUClass is only needed for parent-class abstract function access. Just use parent classes for reset and realize access and remove ARMCPUClass completely.
Signed-off-by Peter Crosthwaite <[email protected]>---
target-arm/cpu-qom.h | 20 -------------------- target-arm/cpu.c | 16 +++++++--------- 2 files changed, 7 insertions(+), 29 deletions(-)target-arm/cpu-qom.h +0
-20@@ -24,28 +24,8 @@#define TYPE_ARM_CPU "arm-cpu" -#define ARM_CPU_CLASS (klass) \ - OBJECT_CLASS_CHECK(ARMCPUClass, (klass), TYPE_ARM_CPU)#define ARM_CPU (obj) \ OBJECT_CHECK(ARMCPU, (obj), TYPE_ARM_CPU) -#define ARM_CPU_GET_CLASS (obj) \ - OBJECT_GET_CLASS(ARMCPUClass, (obj), TYPE_ARM_CPU) - -/** -* ARMCPUClass: -* @parent_realize: The parent class' realize handler. -* @parent_reset: The parent class' reset handler. -* -* An ARM CPU model. -*/ -typedef struct ARMCPUClass { -/*< private >*/ -CPUClass parent_class; -/*< public >*/ - -DeviceRealize parent_realize; -void (*parent_reset)(CPUState *cpu); -}ARMCPUClass ;/** * ARMCPU: target-arm/cpu.c +0
-0target-arm/cpu.c static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque) · line 64
Quoted 6 lines
target-arm/cpu.c +2
-1@@ -60,7 +60,8 @@ static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)static void arm_cpu_reset (CPUState *s) {ARMCPU *cpu =ARM_CPU (s); -ARMCPUClass *acc =ARM_CPU_GET_CLASS (cpu); +CPUClass *cc_parent = +CPU_CLASS (object_class_get_parent_by_name (TYPE_ARM_CPU ));Maybe
object_class_get_parent_of_type()would be less confusing?
Quoted 3 lines
This usage assumes that parent of
TYPE_ARM_CPUisTYPE_CPUand if anotherTYPE_Xadded between them, it might break ifTYPE_Xdoesn't re-implement this logic in its reset.
If what's needed is TYPE_CPU, you can just look up the class by name.
Quoted 60 lines
Could reset be modeled like
DEVICE.instance_init()instead? Then no explicit access to parent from child would be needed and it still leaves possibility to override resets ifparent->childpropagation order is not desirable for a particular device.Quoted 55 lines
target-arm/cpu.c +5
-8CPUARMState *env = &cpu->env;if (qemu_loglevel_mask (CPU_LOG_RESET )) {@@ -68,7 +69,7 @@ static void arm_cpu_reset(CPUState *s)log_cpu_state (env,0 ); } - acc->parent_reset (s); + cc_parent->reset (s);memset (env,0 , offsetof(CPUARMState , breakpoints));g_hash_table_foreach (cpu->cp_regs, cp_reg_reset, cpu);@@ -158,7 +159,8 @@ static void arm_cpu_finalizefn(Object *obj)static void arm_cpu_realizefn (DeviceState *dev,Error **errp) {ARMCPU *cpu =ARM_CPU (dev); -ARMCPUClass *acc =ARM_CPU_GET_CLASS (dev); +DeviceClass *dc_parent = +DEVICE_CLASS (object_class_get_parent_by_name (TYPE_ARM_CPU ));CPUARMState *env = &cpu->env;/* Some features automatically imply others: */ @@ -209,7 +211,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)cpu_reset (CPU (cpu)); - acc->parent_realize (dev, errp); + dc_parent->realize (dev, errp); }/* CPU models */ @@ -803,14 +805,11 @@ static const ARMCPUInfo arm_cpus[] = {static void arm_cpu_class_init (ObjectClass *oc,void *data) { -ARMCPUClass *acc =ARM_CPU_CLASS (oc); -CPUClass *cc =CPU_CLASS (acc); +CPUClass *cc =CPU_CLASS (oc);DeviceClass *dc =DEVICE_CLASS (oc); - acc->parent_realize = dc->realize; dc->realize = arm_cpu_realizefn; - acc->parent_reset = cc->reset; cc->reset = arm_cpu_reset; cc->class_by_name = arm_cpu_class_by_name;@@ -839,7 +838,6 @@ static const TypeInfo arm_cpu_type_info = { .instance_init = arm_cpu_initfn, .instance_finalize = arm_cpu_finalizefn, .abstract = true, - .class_size = sizeof(ARMCPUClass), .class_init = arm_cpu_class_init, };
Re: [Qemu-devel] [PATCH qom-next v2 3/5] target-arm: Use parent classes for reset + realize
Am 11.07.2013 12:31, schrieb Michael S. Tsirkin:
Quoted 63 lines · Igor Mammedov
Quoted 62 lines
Quoted 51 lines · On Thu, 11 Jul 2013 11:47:16 +1000 [email protected] wrote:
From: Peter Crosthwaite <[email protected]>
ARMCPUClass is only needed for parent-class abstract function access. Just use parent classes for reset and realize access and remove ARMCPUClass completely.
Signed-off-by Peter Crosthwaite <[email protected]>---
target-arm/cpu-qom.h | 20 -------------------- target-arm/cpu.c | 16 +++++++--------- 2 files changed, 7 insertions(+), 29 deletions(-)target-arm/cpu-qom.h +0
-20@@ -24,28 +24,8 @@#define TYPE_ARM_CPU "arm-cpu" -#define ARM_CPU_CLASS (klass) \ - OBJECT_CLASS_CHECK(ARMCPUClass, (klass), TYPE_ARM_CPU)#define ARM_CPU (obj) \ OBJECT_CHECK(ARMCPU, (obj), TYPE_ARM_CPU) -#define ARM_CPU_GET_CLASS (obj) \ - OBJECT_GET_CLASS(ARMCPUClass, (obj), TYPE_ARM_CPU) - -/** -* ARMCPUClass: -* @parent_realize: The parent class' realize handler. -* @parent_reset: The parent class' reset handler. -* -* An ARM CPU model. -*/ -typedef struct ARMCPUClass { -/*< private >*/ -CPUClass parent_class; -/*< public >*/ - -DeviceRealize parent_realize; -void (*parent_reset)(CPUState *cpu); -}ARMCPUClass ;/** * ARMCPU: target-arm/cpu.c +0
-0target-arm/cpu.c static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque) · line 64
Quoted 6 lines
target-arm/cpu.c +2
-1@@ -60,7 +60,8 @@ static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)static void arm_cpu_reset (CPUState *s) {ARMCPU *cpu =ARM_CPU (s); -ARMCPUClass *acc =ARM_CPU_GET_CLASS (cpu); +CPUClass *cc_parent = +CPU_CLASS (object_class_get_parent_by_name (TYPE_ARM_CPU ));Maybe
object_class_get_parent_of_type()would be less confusing?
Quoted 5 lines
Quoted 3 lines
This usage assumes that parent of
TYPE_ARM_CPUisTYPE_CPUand if anotherTYPE_Xadded between them, it might break ifTYPE_Xdoesn't re-implement this logic in its reset.If what's needed is
TYPE_CPU, you can just look up the class by name.
My suggestion was to hide the implementation details behind an ARM_CPU_GET_PARENT_CLASS(obj) macro.
That would at the same time allow to later switch to an iterative approach as seen in v1 without a whole lot of refactoring.
Andreas
Quoted 61 lines
Quoted 61 lines
Could reset be modeled like
DEVICE.instance_init()instead? Then no explicit access to parent from child would be needed and it still leaves possibility to override resets ifparent->childpropagation order is not desirable for a particular device.Quoted 55 lines
target-arm/cpu.c +5
-8CPUARMState *env = &cpu->env;if (qemu_loglevel_mask (CPU_LOG_RESET )) {@@ -68,7 +69,7 @@ static void arm_cpu_reset(CPUState *s)log_cpu_state (env,0 ); } - acc->parent_reset (s); + cc_parent->reset (s);memset (env,0 , offsetof(CPUARMState , breakpoints));g_hash_table_foreach (cpu->cp_regs, cp_reg_reset, cpu);@@ -158,7 +159,8 @@ static void arm_cpu_finalizefn(Object *obj)static void arm_cpu_realizefn (DeviceState *dev,Error **errp) {ARMCPU *cpu =ARM_CPU (dev); -ARMCPUClass *acc =ARM_CPU_GET_CLASS (dev); +DeviceClass *dc_parent = +DEVICE_CLASS (object_class_get_parent_by_name (TYPE_ARM_CPU ));CPUARMState *env = &cpu->env;/* Some features automatically imply others: */ @@ -209,7 +211,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)cpu_reset (CPU (cpu)); - acc->parent_realize (dev, errp); + dc_parent->realize (dev, errp); }/* CPU models */ @@ -803,14 +805,11 @@ static const ARMCPUInfo arm_cpus[] = {static void arm_cpu_class_init (ObjectClass *oc,void *data) { -ARMCPUClass *acc =ARM_CPU_CLASS (oc); -CPUClass *cc =CPU_CLASS (acc); +CPUClass *cc =CPU_CLASS (oc);DeviceClass *dc =DEVICE_CLASS (oc); - acc->parent_realize = dc->realize; dc->realize = arm_cpu_realizefn; - acc->parent_reset = cc->reset; cc->reset = arm_cpu_reset; cc->class_by_name = arm_cpu_class_by_name;@@ -839,7 +838,6 @@ static const TypeInfo arm_cpu_type_info = { .instance_init = arm_cpu_initfn, .instance_finalize = arm_cpu_finalizefn, .abstract = true, - .class_size = sizeof(ARMCPUClass), .class_init = arm_cpu_class_init, };
Signature · 2 lines
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH qom-next v2 3/5] target-arm: Use parent classes for reset + realize
Quoted 70 lines · Andreas Färber
Am 11.07.2013 12:31, schrieb Michael S. Tsirkin:
Quoted 68 lines · Igor Mammedov
Quoted 62 lines
Quoted 51 lines · On Thu, 11 Jul 2013 11:47:16 +1000 [email protected] wrote:
From: Peter Crosthwaite <[email protected]>
ARMCPUClass is only needed for parent-class abstract function access. Just use parent classes for reset and realize access and remove ARMCPUClass completely.
Signed-off-by Peter Crosthwaite <[email protected]>---
target-arm/cpu-qom.h | 20 -------------------- target-arm/cpu.c | 16 +++++++--------- 2 files changed, 7 insertions(+), 29 deletions(-)target-arm/cpu-qom.h +0
-20@@ -24,28 +24,8 @@#define TYPE_ARM_CPU "arm-cpu" -#define ARM_CPU_CLASS (klass) \ - OBJECT_CLASS_CHECK(ARMCPUClass, (klass), TYPE_ARM_CPU)#define ARM_CPU (obj) \ OBJECT_CHECK(ARMCPU, (obj), TYPE_ARM_CPU) -#define ARM_CPU_GET_CLASS (obj) \ - OBJECT_GET_CLASS(ARMCPUClass, (obj), TYPE_ARM_CPU) - -/** -* ARMCPUClass: -* @parent_realize: The parent class' realize handler. -* @parent_reset: The parent class' reset handler. -* -* An ARM CPU model. -*/ -typedef struct ARMCPUClass { -/*< private >*/ -CPUClass parent_class; -/*< public >*/ - -DeviceRealize parent_realize; -void (*parent_reset)(CPUState *cpu); -}ARMCPUClass ;/** * ARMCPU: target-arm/cpu.c +0
-0target-arm/cpu.c static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque) · line 64
Quoted 6 lines
target-arm/cpu.c +2
-1@@ -60,7 +60,8 @@ static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)static void arm_cpu_reset (CPUState *s) {ARMCPU *cpu =ARM_CPU (s); -ARMCPUClass *acc =ARM_CPU_GET_CLASS (cpu); +CPUClass *cc_parent = +CPU_CLASS (object_class_get_parent_by_name (TYPE_ARM_CPU ));Maybe
object_class_get_parent_of_type()would be less confusing?Quoted 3 lines
This usage assumes that parent of
TYPE_ARM_CPUisTYPE_CPUand if anotherTYPE_Xadded between them, it might break ifTYPE_Xdoesn't re-implement this logic in its reset.If what's needed is
TYPE_CPU, you can just look up the class by name.
That means the function has knowedge of who the direct parent is which I am trying to avoid. The goal is the Device::realize function knows it has to call the parent version. As for who that direct parent is, that ideally remain abstracted away from here. If you directly reference a parent class by name you also make it hard to change an objects parent (which is currently only defined in one place.
Quoted 3 lines
My suggestion was to hide the implementation details behind an
ARM_CPU_GET_PARENT_CLASS(obj)macro.
Respinning. as such. I think this is a good idea. Looks more consistent with neighbouring code as well.
Regards,
Peter
Re: [Qemu-devel] [PATCH qom-next v2 3/5] target-arm: Use parent classes for reset + realize
In reply to Michael S. TsirkinQuoted 63 lines · On Thu, 11 Jul 2013 13:31:15 +0300 "Michael S. Tsirkin" <[email protected]> wrote:
Quoted 62 lines · Igor Mammedov
Quoted 51 lines · On Thu, 11 Jul 2013 11:47:16 +1000 [email protected] wrote:
From: Peter Crosthwaite <[email protected]>
ARMCPUClass is only needed for parent-class abstract function access. Just use parent classes for reset and realize access and remove ARMCPUClass completely.
Signed-off-by Peter Crosthwaite <[email protected]>---
target-arm/cpu-qom.h | 20 -------------------- target-arm/cpu.c | 16 +++++++--------- 2 files changed, 7 insertions(+), 29 deletions(-)target-arm/cpu-qom.h +0
-20@@ -24,28 +24,8 @@#define TYPE_ARM_CPU "arm-cpu" -#define ARM_CPU_CLASS (klass) \ - OBJECT_CLASS_CHECK(ARMCPUClass, (klass), TYPE_ARM_CPU)#define ARM_CPU (obj) \ OBJECT_CHECK(ARMCPU, (obj), TYPE_ARM_CPU) -#define ARM_CPU_GET_CLASS (obj) \ - OBJECT_GET_CLASS(ARMCPUClass, (obj), TYPE_ARM_CPU) - -/** -* ARMCPUClass: -* @parent_realize: The parent class' realize handler. -* @parent_reset: The parent class' reset handler. -* -* An ARM CPU model. -*/ -typedef struct ARMCPUClass { -/*< private >*/ -CPUClass parent_class; -/*< public >*/ - -DeviceRealize parent_realize; -void (*parent_reset)(CPUState *cpu); -}ARMCPUClass ;/** * ARMCPU: target-arm/cpu.c +0
-0target-arm/cpu.c static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque) · line 64
Quoted 6 lines
target-arm/cpu.c +2
-1@@ -60,7 +60,8 @@ static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)static void arm_cpu_reset (CPUState *s) {ARMCPU *cpu =ARM_CPU (s); -ARMCPUClass *acc =ARM_CPU_GET_CLASS (cpu); +CPUClass *cc_parent = +CPU_CLASS (object_class_get_parent_by_name (TYPE_ARM_CPU ));Maybe
object_class_get_parent_of_type()would be less confusing?
Quoted 5 lines
Quoted 3 lines
This usage assumes that parent of
TYPE_ARM_CPUisTYPE_CPUand if anotherTYPE_Xadded between them, it might break ifTYPE_Xdoesn't re-implement this logic in its reset.If what's needed is
TYPE_CPU, you can just look up the class by name.
As a quick way to reduce amount of current code /save+override+call/ it will work too, but adding intermediate TYPE bears the same risk, i.e. children must be amended to call its reset if it has one.
Quoted 62 lines
Quoted 61 lines
Could reset be modeled like
DEVICE.instance_init()instead? Then no explicit access to parent from child would be needed and it still leaves possibility to override resets ifparent->childpropagation order is not desirable for a particular device.Quoted 55 lines
target-arm/cpu.c +5
-8CPUARMState *env = &cpu->env;if (qemu_loglevel_mask (CPU_LOG_RESET )) {@@ -68,7 +69,7 @@ static void arm_cpu_reset(CPUState *s)log_cpu_state (env,0 ); } - acc->parent_reset (s); + cc_parent->reset (s);memset (env,0 , offsetof(CPUARMState , breakpoints));g_hash_table_foreach (cpu->cp_regs, cp_reg_reset, cpu);@@ -158,7 +159,8 @@ static void arm_cpu_finalizefn(Object *obj)static void arm_cpu_realizefn (DeviceState *dev,Error **errp) {ARMCPU *cpu =ARM_CPU (dev); -ARMCPUClass *acc =ARM_CPU_GET_CLASS (dev); +DeviceClass *dc_parent = +DEVICE_CLASS (object_class_get_parent_by_name (TYPE_ARM_CPU ));CPUARMState *env = &cpu->env;/* Some features automatically imply others: */ @@ -209,7 +211,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)cpu_reset (CPU (cpu)); - acc->parent_realize (dev, errp); + dc_parent->realize (dev, errp); }/* CPU models */ @@ -803,14 +805,11 @@ static const ARMCPUInfo arm_cpus[] = {static void arm_cpu_class_init (ObjectClass *oc,void *data) { -ARMCPUClass *acc =ARM_CPU_CLASS (oc); -CPUClass *cc =CPU_CLASS (acc); +CPUClass *cc =CPU_CLASS (oc);DeviceClass *dc =DEVICE_CLASS (oc); - acc->parent_realize = dc->realize; dc->realize = arm_cpu_realizefn; - acc->parent_reset = cc->reset; cc->reset = arm_cpu_reset; cc->class_by_name = arm_cpu_class_by_name;@@ -839,7 +838,6 @@ static const TypeInfo arm_cpu_type_info = { .instance_init = arm_cpu_initfn, .instance_finalize = arm_cpu_finalizefn, .abstract = true, - .class_size = sizeof(ARMCPUClass), .class_init = arm_cpu_class_init, };
Re: [Qemu-devel] [PATCH qom-next v2 3/5] target-arm: Use parent classes for reset + realize
In reply to Igor MammedovHi Igor,
Quoted 62 lines · Igor Mammedov
Quoted 51 lines · On Thu, 11 Jul 2013 11:47:16 +1000 [email protected] wrote:
From: Peter Crosthwaite <[email protected]>
ARMCPUClass is only needed for parent-class abstract function access. Just use parent classes for reset and realize access and remove ARMCPUClass completely.
Signed-off-by Peter Crosthwaite <[email protected]>---
target-arm/cpu-qom.h | 20 -------------------- target-arm/cpu.c | 16 +++++++--------- 2 files changed, 7 insertions(+), 29 deletions(-)target-arm/cpu-qom.h +0
-20@@ -24,28 +24,8 @@#define TYPE_ARM_CPU "arm-cpu" -#define ARM_CPU_CLASS (klass) \ - OBJECT_CLASS_CHECK(ARMCPUClass, (klass), TYPE_ARM_CPU)#define ARM_CPU (obj) \ OBJECT_CHECK(ARMCPU, (obj), TYPE_ARM_CPU) -#define ARM_CPU_GET_CLASS (obj) \ - OBJECT_GET_CLASS(ARMCPUClass, (obj), TYPE_ARM_CPU) - -/** -* ARMCPUClass: -* @parent_realize: The parent class' realize handler. -* @parent_reset: The parent class' reset handler. -* -* An ARM CPU model. -*/ -typedef struct ARMCPUClass { -/*< private >*/ -CPUClass parent_class; -/*< public >*/ - -DeviceRealize parent_realize; -void (*parent_reset)(CPUState *cpu); -}ARMCPUClass ;/** * ARMCPU: target-arm/cpu.c +0
-0target-arm/cpu.c static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque) · line 64
Quoted 6 lines
target-arm/cpu.c +2
-1@@ -60,7 +60,8 @@ static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)static void arm_cpu_reset (CPUState *s) {ARMCPU *cpu =ARM_CPU (s); -ARMCPUClass *acc =ARM_CPU_GET_CLASS (cpu); +CPUClass *cc_parent = +CPU_CLASS (object_class_get_parent_by_name (TYPE_ARM_CPU ));Maybe
object_class_get_parent_of_type()would be less confusing?
Quoted 1 line
This usage assumes that parent of
TYPE_ARM_CPUisTYPE_CPU
It assumes that a parent (could be a grandparent on any level) is TYPE_CPU not necessarily the direct parent.
Quoted 3 lines
and if
anotherTYPE_Xadded between them, it might break ifTYPE_Xdoesn't re-implement this logic in its reset.
That's not really an issue. Assuming your example inheritance heirachy:
TYPE_ARM_CPU -> TYPE_X -> TYPE_CPU
If TYPE_X does not override reset, then TYPE_X inherits TYPE_CPU::reset as its reset. When TYPE_ARM_CPU does object_class_get_parent_by_name(TYPE_ARM_CPU), TYPE_X will be returned, but it will call TYPE_CPU::reset through inheritance anyway. If TYPE_X does implement a reset, then its TYPE_X's job to call parent reset as well but that is no different to the status quo anyway.
Quoted 6 lines
Could reset be modeled like
DEVICE.instance_init()instead? Then no explicit access to parent from child would be needed and it still leaves possibility to override resets ifparent->childpropagation order is not desirable for a particular device.
I don't think thats a good idea. Then reset is inconsistent with other deviceClass::foo APIs. Leave calling of the parent open coded for the child to determine. Also the parent should not be allowed to force the child to call its reset. The child should be able override an API throwing the original away entirely. The child should also be able to call the parent version when it wants, rather than us having to worry about the need for multiple "post or pre" versions.
Regards,
Peter
Quoted 57 lines
Quoted 55 lines
target-arm/cpu.c +5
-8CPUARMState *env = &cpu->env;if (qemu_loglevel_mask (CPU_LOG_RESET )) {@@ -68,7 +69,7 @@ static void arm_cpu_reset(CPUState *s)log_cpu_state (env,0 ); } - acc->parent_reset (s); + cc_parent->reset (s);memset (env,0 , offsetof(CPUARMState , breakpoints));g_hash_table_foreach (cpu->cp_regs, cp_reg_reset, cpu);@@ -158,7 +159,8 @@ static void arm_cpu_finalizefn(Object *obj)static void arm_cpu_realizefn (DeviceState *dev,Error **errp) {ARMCPU *cpu =ARM_CPU (dev); -ARMCPUClass *acc =ARM_CPU_GET_CLASS (dev); +DeviceClass *dc_parent = +DEVICE_CLASS (object_class_get_parent_by_name (TYPE_ARM_CPU ));CPUARMState *env = &cpu->env;/* Some features automatically imply others: */ @@ -209,7 +211,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)cpu_reset (CPU (cpu)); - acc->parent_realize (dev, errp); + dc_parent->realize (dev, errp); }/* CPU models */ @@ -803,14 +805,11 @@ static const ARMCPUInfo arm_cpus[] = {static void arm_cpu_class_init (ObjectClass *oc,void *data) { -ARMCPUClass *acc =ARM_CPU_CLASS (oc); -CPUClass *cc =CPU_CLASS (acc); +CPUClass *cc =CPU_CLASS (oc);DeviceClass *dc =DEVICE_CLASS (oc); - acc->parent_realize = dc->realize; dc->realize = arm_cpu_realizefn; - acc->parent_reset = cc->reset; cc->reset = arm_cpu_reset; cc->class_by_name = arm_cpu_class_by_name;@@ -839,7 +838,6 @@ static const TypeInfo arm_cpu_type_info = { .instance_init = arm_cpu_initfn, .instance_finalize = arm_cpu_finalizefn, .abstract = true, - .class_size = sizeof(ARMCPUClass), .class_init = arm_cpu_class_init, };
PATCH v2 4/5 target-microblaze: Use parent class for reset + realize
In reply to [email protected]From: Peter Crosthwaite <[email protected]>
MicroblazeCPUClass is only needed for parent-class abstract function access. Just use parent classes for reset and realize access and remove MicroblazeCPUClass completely.
---
target-microblaze/cpu-qom.h | 20 -------------------- target-microblaze/cpu.c | 16 ++++++---------- 2 files changed, 6 insertions(+), 30 deletions(-)
target-microblaze/cpu-qom.h +0 -20
@@ -24,28 +24,8 @@#define TYPE_MICROBLAZE_CPU "microblaze-cpu" -#define MICROBLAZE_CPU_CLASS (klass) \ - OBJECT_CLASS_CHECK(MicroBlazeCPUClass, (klass), TYPE_MICROBLAZE_CPU)#define MICROBLAZE_CPU (obj) \ OBJECT_CHECK(MicroBlazeCPU, (obj), TYPE_MICROBLAZE_CPU) -#define MICROBLAZE_CPU_GET_CLASS (obj) \ - OBJECT_GET_CLASS(MicroBlazeCPUClass, (obj), TYPE_MICROBLAZE_CPU) - -/** -* MicroBlazeCPUClass: -* @parent_realize: The parent class' realize handler. -* @parent_reset: The parent class' reset handler. -* -* A MicroBlaze CPU model. -*/ -typedef struct MicroBlazeCPUClass { -/*< private >*/ -CPUClass parent_class; -/*< public >*/ - -DeviceRealize parent_realize; -void (*parent_reset)(CPUState *cpu); -}MicroBlazeCPUClass ;/** * MicroBlazeCPU:
target-microblaze/cpu.c +6 -10
@@ -25,12 +25,12 @@#include "hw/qdev-properties.h" #include "migration/vmstate.h" -/* CPUClass::reset() */ static void mb_cpu_reset (CPUState *s) {MicroBlazeCPU *cpu =MICROBLAZE_CPU (s); -MicroBlazeCPUClass *mcc =MICROBLAZE_CPU_GET_CLASS (cpu); +CPUClass *cc_parent = +CPU_CLASS (object_class_get_parent_by_name (TYPE_MICROBLAZE_CPU ));CPUMBState *env = &cpu->env;if (qemu_loglevel_mask (CPU_LOG_RESET )) {
@@ -38,7 +38,7 @@ static void mb_cpu_reset(CPUState *s)log_cpu_state (env,0 ); } - mcc->parent_reset (s); + cc_parent->reset (s);memset (env,0 , offsetof(CPUMBState , breakpoints)); env->res_addr =RES_ADDR_NONE ;
@@ -89,11 +89,11 @@ static void mb_cpu_reset(CPUState *s)static void mb_cpu_realizefn (DeviceState *dev,Error **errp) {MicroBlazeCPU *cpu =MICROBLAZE_CPU (dev); -MicroBlazeCPUClass *mcc =MICROBLAZE_CPU_GET_CLASS (dev); - +DeviceClass *dc_parent = +DEVICE_CLASS (object_class_get_parent_by_name (TYPE_MICROBLAZE_CPU ));cpu_reset (CPU (cpu)); - mcc->parent_realize (dev, errp); + dc_parent->realize (dev, errp); }static void mb_cpu_initfn (Object *obj)
@@ -128,12 +128,9 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data) {DeviceClass *dc =DEVICE_CLASS (oc);CPUClass *cc =CPU_CLASS (oc); -MicroBlazeCPUClass *mcc =MICROBLAZE_CPU_CLASS (oc); - mcc->parent_realize = dc->realize; dc->realize = mb_cpu_realizefn; - mcc->parent_reset = cc->reset; cc->reset = mb_cpu_reset; cc->do_interrupt = mb_cpu_do_interrupt;
@@ -148,7 +145,6 @@ static const TypeInfo mb_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(MicroBlazeCPU), .instance_init = mb_cpu_initfn, - .class_size = sizeof(MicroBlazeCPUClass), .class_init = mb_cpu_class_init, };
Signature · 1 line
1.8.3.rc1.44.gb387c77.dirty
PATCH v2 5/5 i8254: Use parent class for realize
In reply to [email protected]From: Peter Crosthwaite <[email protected]>
[KVM]PITClass is only needed for parent-class realize function access. Just use parent classes for realize access and remove [KVM]PITClass completely.
---
hw/i386/kvm/i8254.c | 18 +++--------------- hw/timer/i8254.c | 17 +++-------------- 2 files changed, 6 insertions(+), 29 deletions(-)
hw/i386/kvm/i8254.c +3 -15
@@ -33,10 +33,6 @@#define CALIBRATION_ROUNDS 3#define KVM_PIT (obj) OBJECT_CHECK(KVMPITState, (obj), TYPE_KVM_I8254) -#define KVM_PIT_CLASS (class) \ - OBJECT_CLASS_CHECK(KVMPITClass, (class), TYPE_KVM_I8254) -#define KVM_PIT_GET_CLASS (obj) \ - OBJECT_GET_CLASS(KVMPITClass, (obj), TYPE_KVM_I8254) typedef struct KVMPITState { PITCommonState parent_obj;
@@ -46,12 +42,6 @@ typedef struct KVMPITState {int64_t kernel_clock_offset; } KVMPITState; -typedef struct KVMPITClass { -PITCommonClass parent_class; - -DeviceRealize parent_realize; -}KVMPITClass ; -static int64_t abs64 (int64_t v) {return v <0 ? -v : v;
@@ -250,7 +240,8 @@ static void kvm_pit_vm_state_change(void *opaque, int running,static void kvm_pit_realizefn (DeviceState *dev,Error **errp) {PITCommonState *pit =PIT_COMMON (dev); -KVMPITClass *kpc =KVM_PIT_GET_CLASS (dev); +DeviceClass *dc_parent = +DEVICE_CLASS (object_class_get_parent_by_name (TYPE_KVM_I8254 ));KVMPITState *s =KVM_PIT (pit);struct kvm_pit_config config = { .flags =0 ,
@@ -294,7 +285,7 @@ static void kvm_pit_realizefn(DeviceState *dev, Error **errp)qemu_add_vm_change_state_handler (kvm_pit_vm_state_change, s); - kpc->parent_realize (dev, errp); + dc_parent->realize (dev, errp); }static Property kvm_pit_properties[] = {
@@ -306,11 +297,9 @@ static Property kvm_pit_properties[] = {static void kvm_pit_class_init (ObjectClass *klass,void *data) { -KVMPITClass *kpc =KVM_PIT_CLASS (klass);PITCommonClass *k =PIT_COMMON_CLASS (klass);DeviceClass *dc =DEVICE_CLASS (klass); - kpc->parent_realize = dc->realize; dc->realize = kvm_pit_realizefn; k->set_channel_gate = kvm_pit_set_gate; k->get_channel_info = kvm_pit_get_channel_info;
@@ -325,7 +314,6 @@ static const TypeInfo kvm_pit_info = { .parent = TYPE_PIT_COMMON, .instance_size = sizeof(KVMPITState), .class_init = kvm_pit_class_init, - .class_size = sizeof(KVMPITClass), };static void kvm_pit_register (void )
hw/timer/i8254.c +3 -14
@@ -35,15 +35,6 @@#define RW_STATE_WORD0 3#define RW_STATE_WORD1 4 -#define PIT_CLASS (class) OBJECT_CLASS_CHECK(PITClass, (class), TYPE_I8254) -#define PIT_GET_CLASS (obj) OBJECT_GET_CLASS(PITClass, (obj), TYPE_I8254) - -typedef struct PITClass { -PITCommonClass parent_class; - -DeviceRealize parent_realize; -}PITClass ; -static void pit_irq_timer_update (PITChannelState *s,int64_t current_time);static int pit_get_count (PITChannelState *s)
@@ -325,7 +316,8 @@ static void pit_post_load(PITCommonState *s)static void pit_realizefn (DeviceState *dev,Error **err) {PITCommonState *pit =PIT_COMMON (dev); -PITClass *pc =PIT_GET_CLASS (dev); +DeviceClass *dc_parent = +DEVICE_CLASS (object_class_get_parent_by_name (TYPE_I8254 ));PITChannelState *s; s = &pit->channels[0 ];
@@ -338,7 +330,7 @@ static void pit_realizefn(DeviceState *dev, Error **err)qdev_init_gpio_in (dev, pit_irq_control,1 ); - pc->parent_realize (dev, err); + dc_parent->realize (dev, err); }static Property pit_properties[] = {
@@ -348,11 +340,9 @@ static Property pit_properties[] = {static void pit_class_initfn (ObjectClass *klass,void *data) { -PITClass *pc =PIT_CLASS (klass);PITCommonClass *k =PIT_COMMON_CLASS (klass);DeviceClass *dc =DEVICE_CLASS (klass); - pc->parent_realize = dc->realize; dc->realize = pit_realizefn; k->set_channel_gate = pit_set_channel_gate; k->get_channel_info = pit_get_channel_info_common;
@@ -366,7 +356,6 @@ static const TypeInfo pit_info = { .parent = TYPE_PIT_COMMON, .instance_size = sizeof(PITCommonState), .class_init = pit_class_initfn, - .class_size = sizeof(PITClass), };static void pit_register_types (void )
Signature · 1 line
1.8.3.rc1.44.gb387c77.dirty