Skip to contentSkip to conversation

QOM Super class access

PATCH Superseded [email protected] 5 participants 14 messages Jul 11, 2013 – Jul 15, 2013

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

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
index 1bc227e..ed53df8 100644
@@ -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
Reviewed-by on v2 1/5
#2 lore raw

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

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
index 1bc227e..ed53df8 100644
@@ -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
#3 lore raw

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

#4 lore raw

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
index 23fc048..f5ce2e8 100644
@@ -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
index cbd7e86..4a3197d 100644
@@ -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
#5 lore raw

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
index ef6261f..bdad93a 100644
@@ -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
index ed53df8..ad5ec7b 100644
@@ -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
#6 lore raw

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.

---

 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
index ef6261f..bdad93a 100644
@@ -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
index ed53df8..ad5ec7b 100644

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 -8
     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,
 };
 
#7 lore raw

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.

---

 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
index ef6261f..bdad93a 100644
@@ -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
index ed53df8..ad5ec7b 100644

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?

Quoted 3 lines

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.

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 if parent->child propagation order is not desirable for a particular device.

Quoted 55 lines
target-arm/cpu.c +5 -8
     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,
 };
 
#8 lore raw

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.

---

 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
index ef6261f..bdad93a 100644
@@ -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
index ed53df8..ad5ec7b 100644

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?

Quoted 5 lines
Quoted 3 lines

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.

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 if parent->child propagation order is not desirable for a particular device.

Quoted 55 lines
target-arm/cpu.c +5 -8
     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 · 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
#9 lore raw

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.

---

 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
index ef6261f..bdad93a 100644
@@ -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
index ed53df8..ad5ec7b 100644

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?

Quoted 3 lines

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.

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

#10 lore raw

Re: [Qemu-devel] [PATCH qom-next v2 3/5] target-arm: Use parent classes for reset + realize

In reply to Michael S. Tsirkin
Quoted 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.

---

 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
index ef6261f..bdad93a 100644
@@ -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
index ed53df8..ad5ec7b 100644

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?

Quoted 5 lines
Quoted 3 lines

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.

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 if parent->child propagation order is not desirable for a particular device.

Quoted 55 lines
target-arm/cpu.c +5 -8
     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,
 };
 
#11 lore raw

Re: [Qemu-devel] [PATCH qom-next v2 3/5] target-arm: Use parent classes for reset + realize

In reply to Igor Mammedov

Hi 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.

---

 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
index ef6261f..bdad93a 100644
@@ -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
index ed53df8..ad5ec7b 100644

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?

Quoted 1 line

This usage assumes that parent of TYPE_ARM_CPU is TYPE_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
another TYPE_X added between them, it might break if TYPE_X doesn'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 if parent->child propagation 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 -8
     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,
 };
 
#12 lore raw

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
index 3e9c206..f47259b 100644
@@ -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
index a0fcdf4..e8d76b9 100644
@@ -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
#13 lore raw

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
index c1f4094..36d2e21 100644
@@ -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
index cd52140..8db8b34 100644
@@ -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