From: Richard Henderson <richard.henderson@linaro.org>
To: qemu-devel@nongnu.org
Cc: pbonzini@redhat.com, berrange@redhat.com, eduardo@habkost.net,
armbru@redhat.com, ajones@ventanamicro.com,
alex.bennee@linaro.org
Subject: [RFC PATCH 02/40] qom: Introduce class_late_init
Date: Tue, 3 Jan 2023 10:16:08 -0800 [thread overview]
Message-ID: <20230103181646.55711-3-richard.henderson@linaro.org> (raw)
In-Reply-To: <20230103181646.55711-1-richard.henderson@linaro.org>
Create a new class initialization hook, to be called immediately
before creation of the first instance. Most class initialization
happens quite early, which makes interaction between classes
difficult. E.g. cpu objects often depend on the accellerator,
or the global properties coming from the command-line.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/qom/object.h | 4 ++++
qom/object.c | 55 +++++++++++++++++++++++++++++++++++++-------
2 files changed, 51 insertions(+), 8 deletions(-)
diff --git a/include/qom/object.h b/include/qom/object.h
index ef7258a5e1..86958abe15 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -402,6 +402,9 @@ struct Object
* parent class initialization has occurred, but before the class itself
* is initialized. This is the function to use to undo the effects of
* memcpy from the parent class to the descendants.
+ * @class_late_init: This function is called for all base classes just
+ * before the first object is created. This is the function to use to
+ * apply properties (which are interpreted quite late).
* @class_data: Data to pass to the @class_init,
* @class_base_init. This can be useful when building dynamic
* classes.
@@ -425,6 +428,7 @@ struct TypeInfo
void (*class_init)(ObjectClass *klass, void *data);
void (*class_base_init)(ObjectClass *klass, void *data);
+ bool (*class_late_init)(ObjectClass *klass, Error **errp);
void *class_data;
InterfaceInfo *interfaces;
diff --git a/qom/object.c b/qom/object.c
index e25f1e96db..82a5c7d36e 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -56,6 +56,7 @@ struct TypeImpl
void (*class_init)(ObjectClass *klass, void *data);
void (*class_base_init)(ObjectClass *klass, void *data);
+ bool (*class_late_init)(ObjectClass *klass, Error **errp);
void *class_data;
@@ -64,6 +65,7 @@ struct TypeImpl
void (*instance_finalize)(Object *obj);
bool abstract;
+ bool object_created;
const char *parent;
TypeImpl *parent_type;
@@ -121,6 +123,7 @@ static TypeImpl *type_new(const TypeInfo *info)
ti->class_init = info->class_init;
ti->class_base_init = info->class_base_init;
+ ti->class_late_init = info->class_late_init;
ti->class_data = info->class_data;
ti->instance_init = info->instance_init;
@@ -367,6 +370,26 @@ static void type_initialize(TypeImpl *ti)
}
}
+static bool type_late_initialize(TypeImpl *ti, ObjectClass *cls, Error **errp)
+{
+ TypeImpl *pi = type_get_parent(ti);
+ if (pi && !type_late_initialize(pi, cls, errp)) {
+ return false;
+ }
+
+ for (GSList *e = ti->class->interfaces; e ; e = e->next) {
+ InterfaceClass *ic = e->data;
+ if (!type_late_initialize(ic->interface_type, cls, errp)) {
+ return false;
+ }
+ }
+
+ if (ti->class_late_init) {
+ return ti->class_late_init(cls, errp);
+ }
+ return true;
+}
+
static void object_init_with_type(Object *obj, TypeImpl *ti)
{
if (type_has_parent(ti)) {
@@ -502,7 +525,8 @@ static void object_class_property_init_all(Object *obj)
}
}
-static void object_initialize_with_type(Object *obj, size_t size, TypeImpl *type)
+static bool object_initialize_with_type(Object *obj, size_t size,
+ TypeImpl *type, Error **errp)
{
type_initialize(type);
@@ -510,6 +534,13 @@ static void object_initialize_with_type(Object *obj, size_t size, TypeImpl *type
g_assert(type->abstract == false);
g_assert(size >= type->instance_size);
+ if (!type->object_created) {
+ type->object_created = true;
+ if (!type_late_initialize(type, type->class, errp)) {
+ return false;
+ }
+ }
+
memset(obj, 0, type->instance_size);
obj->class = type->class;
object_ref(obj);
@@ -518,6 +549,7 @@ static void object_initialize_with_type(Object *obj, size_t size, TypeImpl *type
NULL, object_property_free);
object_init_with_type(obj, type);
object_post_init_with_type(obj, type);
+ return true;
}
void object_initialize(void *data, size_t size, const char *typename)
@@ -540,7 +572,7 @@ void object_initialize(void *data, size_t size, const char *typename)
abort();
}
- object_initialize_with_type(data, size, type);
+ object_initialize_with_type(data, size, type, &error_fatal);
}
bool object_initialize_child_with_props(Object *parentobj,
@@ -712,7 +744,7 @@ typedef union {
} qemu_max_align_t;
#endif
-static Object *object_new_with_type(Type type)
+static Object *object_new_with_type(Type type, Error **errp)
{
Object *obj;
size_t size, align;
@@ -736,22 +768,25 @@ static Object *object_new_with_type(Type type)
obj_free = qemu_vfree;
}
- object_initialize_with_type(obj, size, type);
- obj->free = obj_free;
+ if (!object_initialize_with_type(obj, size, type, errp)) {
+ obj_free(obj);
+ return NULL;
+ }
+ obj->free = obj_free;
return obj;
}
Object *object_new_with_class(ObjectClass *klass)
{
- return object_new_with_type(klass->type);
+ return object_new_with_type(klass->type, &error_fatal);
}
Object *object_new(const char *typename)
{
TypeImpl *ti = type_get_by_name(typename);
- return object_new_with_type(ti);
+ return object_new_with_type(ti, &error_fatal);
}
@@ -792,7 +827,11 @@ Object *object_new_with_propv(const char *typename,
error_setg(errp, "object type '%s' is abstract", typename);
return NULL;
}
- obj = object_new_with_type(klass->type);
+
+ obj = object_new_with_type(klass->type, errp);
+ if (!obj) {
+ return NULL;
+ }
if (!object_set_propv(obj, errp, vargs)) {
goto error;
--
2.34.1
next prev parent reply other threads:[~2023-01-03 18:19 UTC|newest]
Thread overview: 77+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-03 18:16 [RFC PATCH 00/40] Toward class init of cpu features Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 01/40] qdev: Don't always force the global property array non-null Richard Henderson
2023-01-05 21:56 ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` Richard Henderson [this message]
2023-01-03 18:16 ` [RFC PATCH 03/40] qom: Create class properties Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 04/40] target/arm: Remove aarch64_cpu_finalizefn Richard Henderson
2023-01-05 21:51 ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 05/40] target/arm: Create arm_cpu_register_parent Richard Henderson
2023-01-05 21:57 ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 06/40] target/arm: Remove AArch64CPUClass Richard Henderson
2023-01-05 21:50 ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 07/40] target/arm: Create TYPE_ARM_V7M_CPU Richard Henderson
2023-01-05 21:58 ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 08/40] target/arm: Pass ARMCPUClass to ARMCPUInfo.class_init Richard Henderson
2023-01-05 22:00 ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 09/40] target/arm: Utilize arm-cpu instance_post_init hook Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 10/40] target/arm: Copy dtb_compatible from ARMCPUClass Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 11/40] target/arm: Copy features " Richard Henderson
2023-01-05 22:04 ` Philippe Mathieu-Daudé
2023-01-06 2:19 ` Richard Henderson
2023-01-06 7:14 ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 12/40] target/arm: Copy isar and friends " Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 13/40] hw/arm/bcm2836: Set mp-affinity property in realize Richard Henderson
2023-01-05 21:48 ` Philippe Mathieu-Daudé
2023-01-06 7:51 ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 14/40] target/arm: Rename arm_cpu_mp_affinity Richard Henderson
2023-01-05 21:55 ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 15/40] target/arm: Create arm_cpu_mp_affinity Richard Henderson
2023-01-05 21:53 ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 16/40] target/arm: Represent the entire MPIDR_EL1 Richard Henderson
2023-01-06 19:16 ` Peter Maydell
2023-01-06 19:33 ` Richard Henderson
2023-01-06 22:14 ` Peter Maydell
2023-01-06 22:36 ` Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 17/40] target/arm: Copy cp_regs from ARMCPUClass Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 18/40] target/arm: Create cpreg definition functions with GHashTable arg Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 19/40] target/arm: Move most cpu initialization to the class Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 20/40] target/arm: Merge kvm64.c with kvm.c Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 21/40] target/arm: Remove aarch64 check from aarch64_host_object_init Richard Henderson
2023-01-05 22:08 ` Philippe Mathieu-Daudé
2023-01-06 2:21 ` Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 22/40] target/arm: Hoist feature and dtb_compatible from KVM, HVF Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 23/40] target/arm: Probe KVM host into ARMCPUClass Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 24/40] target/arm/hvf: Probe " Richard Henderson
2023-01-05 22:10 ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 25/40] target/arm/hvf: Use offsetof in hvf_arm_get_host_cpu_features Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 26/40] target/arm: Rename 'cpu' to 'acc' in class init functions Richard Henderson
2023-01-03 19:24 ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 27/40] target/arm: Split out strongarm_class_init Richard Henderson
2023-01-05 22:12 ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 28/40] target/arm: Split out xscale*_class_init Richard Henderson
2023-01-05 22:13 ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 29/40] target/arm: Remove m-profile has_vfp and has_dsp properties Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 30/40] target/arm: Move feature bit propagation to class init Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 31/40] target/arm: Get and set class properties in the monitor Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 32/40] target/arm: Move "midr" to class property Richard Henderson
2023-01-05 22:18 ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 33/40] target/arm: Move "cntfrq" " Richard Henderson
2023-01-05 22:21 ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 34/40] target/arm: Move "reset-hivecs" " Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 35/40] target/arm: Move "has_el2" " Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 36/40] target/arm: Move "has_el3" " Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 37/40] target/arm: Move "cfgend" " Richard Henderson
2023-01-05 22:23 ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 38/40] target/arm: Move "vfp" and "neon" to class properties Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 39/40] target/arm: Move "has-mpu" and "pmsav7-dregion" " Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 40/40] target/arm: Move "pmu" to class property Richard Henderson
2023-01-04 0:01 ` [RFC PATCH 00/40] Toward class init of cpu features Richard Henderson
2023-01-06 19:12 ` Peter Maydell
2023-01-06 19:29 ` Richard Henderson
2023-01-06 21:59 ` Peter Maydell
2023-01-06 22:28 ` Richard Henderson
2023-01-07 13:14 ` Peter Maydell
2023-01-06 23:43 ` Alex Bennée
2023-01-06 23:57 ` Richard Henderson
2023-01-07 10:19 ` Alex Bennée
2023-01-07 17:53 ` Richard Henderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230103181646.55711-3-richard.henderson@linaro.org \
--to=richard.henderson@linaro.org \
--cc=ajones@ventanamicro.com \
--cc=alex.bennee@linaro.org \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=eduardo@habkost.net \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).