[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 13/24] hw/core: Introduce device_class_set_props_n
From: |
Richard Henderson |
Subject: |
[PATCH v2 13/24] hw/core: Introduce device_class_set_props_n |
Date: |
Wed, 18 Dec 2024 07:42:40 -0600 |
Record the size of the array in DeviceClass.props_count_.
Iterate with known count in qdev_prop_walk.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/hw/qdev-core.h | 18 ++++++++++++++++++
hw/core/qdev-properties.c | 39 +++++++++++++++++++++++++++++----------
hw/core/qdev.c | 1 +
system/qdev-monitor.c | 15 +++++++--------
4 files changed, 55 insertions(+), 18 deletions(-)
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index cbce3cf0b4..e9b4891f55 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -138,6 +138,12 @@ struct DeviceClass {
*/
const Property *props_;
+ /**
+ * @props_count_: number of elements in @props_; should only be
+ * assigned by using device_class_set_props().
+ */
+ uint16_t props_count_;
+
/**
* @user_creatable: Can user instantiate with -device / device_add?
*
@@ -960,6 +966,18 @@ void device_class_set_props(DeviceClass *dc, const
Property *props);
(device_class_set_props)((dc), (props)); \
} while (0)
+/**
+ * device_class_set_props_n(): add a set of properties to an device
+ * @dc: the parent DeviceClass all devices inherit
+ * @props: an array of properties, not terminated by DEFINE_PROP_END_OF_LIST.
+ * @n: ARRAY_SIZE(@props)
+ *
+ * This will add a set of properties to the object. It will fault if
+ * you attempt to add an existing property defined by a parent class.
+ * To modify an inherited property you need to use????
+ */
+void device_class_set_props_n(DeviceClass *dc, const Property *props, size_t
n);
+
/**
* device_class_set_parent_realize() - set up for chaining realize fns
* @dc: The device class
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index de618a964a..31e3072b55 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -749,16 +749,13 @@ const PropertyInfo qdev_prop_array = {
/* --- public helpers --- */
-static const Property *qdev_prop_walk(const Property *props, const char *name)
+static const Property *qdev_prop_walk(DeviceClass *cls, const char *name)
{
- if (!props) {
- return NULL;
- }
- while (props->name) {
- if (strcmp(props->name, name) == 0) {
- return props;
+ for (int i = 0, n = cls->props_count_; i < n; ++i) {
+ const Property *prop = &cls->props_[i];
+ if (strcmp(prop->name, name) == 0) {
+ return prop;
}
- props++;
}
return NULL;
}
@@ -771,7 +768,7 @@ static const Property *qdev_prop_find(DeviceState *dev,
const char *name)
/* device properties */
class = object_get_class(OBJECT(dev));
do {
- prop = qdev_prop_walk(DEVICE_CLASS(class)->props_, name);
+ prop = qdev_prop_walk(DEVICE_CLASS(class), name);
if (prop) {
return prop;
}
@@ -1064,9 +1061,31 @@ static void qdev_class_add_legacy_property(DeviceClass
*dc, const Property *prop
void (device_class_set_props)(DeviceClass *dc, const Property *props)
{
const Property *prop;
+ size_t n;
dc->props_ = props;
- for (prop = props; prop && prop->name; prop++) {
+ for (prop = props, n = 0; prop && prop->name; prop++, n++) {
+ qdev_class_add_legacy_property(dc, prop);
+ qdev_class_add_property(dc, prop->name, prop);
+ }
+
+ /* We used a hole in DeviceClass because that's still a lot. */
+ assert(n <= UINT16_MAX);
+ dc->props_count_ = n;
+}
+
+void device_class_set_props_n(DeviceClass *dc, const Property *props, size_t n)
+{
+ /* We used a hole in DeviceClass because that's still a lot. */
+ assert(n <= UINT16_MAX);
+ assert(n != 0);
+
+ dc->props_ = props;
+ dc->props_count_ = n;
+
+ for (size_t i = 0; i < n; ++i) {
+ const Property *prop = &props[i];
+ assert(prop->name);
qdev_class_add_legacy_property(dc, prop);
qdev_class_add_property(dc, prop->name, prop);
}
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 5f13111b77..57c1d9df3a 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -703,6 +703,7 @@ static void device_class_base_init(ObjectClass *class, void
*data)
* so do not propagate them to the subclasses.
*/
klass->props_ = NULL;
+ klass->props_count_ = 0;
}
static void device_unparent(Object *obj)
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index 03ae610649..6831fffd9d 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -752,19 +752,18 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ##
__VA_ARGS__)
-static void qdev_print_props(Monitor *mon, DeviceState *dev, const Property
*props,
+static void qdev_print_props(Monitor *mon, DeviceState *dev, DeviceClass *dc,
int indent)
{
- if (!props)
- return;
- for (; props->name; props++) {
+ for (int i = 0, n = dc->props_count_; i < n; ++i) {
+ const Property *prop = &dc->props_[i];
char *value;
- char *legacy_name = g_strdup_printf("legacy-%s", props->name);
+ char *legacy_name = g_strdup_printf("legacy-%s", prop->name);
if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
value = object_property_get_str(OBJECT(dev), legacy_name, NULL);
} else {
- value = object_property_print(OBJECT(dev), props->name, true,
+ value = object_property_print(OBJECT(dev), prop->name, true,
NULL);
}
g_free(legacy_name);
@@ -772,7 +771,7 @@ static void qdev_print_props(Monitor *mon, DeviceState
*dev, const Property *pro
if (!value) {
continue;
}
- qdev_printf("%s = %s\n", props->name,
+ qdev_printf("%s = %s\n", prop->name,
*value ? value : "<null>");
g_free(value);
}
@@ -812,7 +811,7 @@ static void qdev_print(Monitor *mon, DeviceState *dev, int
indent)
}
class = object_get_class(OBJECT(dev));
do {
- qdev_print_props(mon, dev, DEVICE_CLASS(class)->props_, indent);
+ qdev_print_props(mon, dev, DEVICE_CLASS(class), indent);
class = object_class_get_parent(class);
} while (class != object_class_by_name(TYPE_DEVICE));
bus_print_dev(dev->parent_bus, mon, dev, indent);
--
2.43.0
- Re: [PATCH v2 08/24] hw/s390x: Remove empty Property lists, (continued)
- [PATCH v2 14/24] migration: Use device_class_set_props_n, Richard Henderson, 2024/12/18
- [PATCH v2 17/24] rust/qemu-api: Use device_class_set_props_n, Richard Henderson, 2024/12/18
- [PATCH v2 19/24] target/riscv: Do not abuse DEFINE_PROP_END_OF_LIST, Richard Henderson, 2024/12/18
- [PATCH v2 22/24] hw/core/qdev-properties: Constify Property argument to object_field_prop_ptr, Richard Henderson, 2024/12/18
- [PATCH v2 09/24] hw/xen: Remove empty Property lists, Richard Henderson, 2024/12/18
- [PATCH v2 12/24] include/hw/qdev-core: Detect most empty Property lists at compile time, Richard Henderson, 2024/12/18
- [PATCH v2 13/24] hw/core: Introduce device_class_set_props_n,
Richard Henderson <=
- [PATCH v2 15/24] hw/scsi/megasas: Use device_class_set_props_n, Richard Henderson, 2024/12/18
- [PATCH v2 16/24] hw/arm/armsse: Use device_class_set_props_n, Richard Henderson, 2024/12/18
- [PATCH v2 18/24] hw/core: Remove device_class_set_props function, Richard Henderson, 2024/12/18
- [PATCH v2 24/24] Constify all opaque Property pointers, Richard Henderson, 2024/12/18
- [PATCH v2 21/24] include/hw/qdev-properties: Shrink struct Property, Richard Henderson, 2024/12/18
- [PATCH v2 23/24] hw/core/qdev-properties: Constify Property argument to PropertyInfo.print, Richard Henderson, 2024/12/18
- [PATCH v2 20/24] include/hw/qdev-properties: Remove DEFINE_PROP_END_OF_LIST, Richard Henderson, 2024/12/18
- Re: [PATCH v2 00/24] More Property cleanups, Lei Yang, 2024/12/18