From 3b6ca4022d150ad273d4cd9556c2f4873389f965 Mon Sep 17 00:00:00 2001 From: Ildar Isaev Date: Wed, 4 Mar 2015 17:09:46 +0300 Subject: qdev: Change Property::offset field to ptrdiff_t type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Property::offset field is calculated as a diff between two pointers: arrayprop->prop.offset = eltptr - (void *)dev; If offset is declared as int, this subtraction can cause type overflow, thus leading to failure of the subsequent assertion: assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr); So ptrdiff_t should be used instead. Signed-off-by: Ildar Isaev Reviewed-by: Peter Maydell Signed-off-by: Andreas Färber --- include/hw/qdev-core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index e6dbde4..c537969 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -237,7 +237,7 @@ struct BusState { struct Property { const char *name; PropertyInfo *info; - int offset; + ptrdiff_t offset; uint8_t bitnr; qtype_code qtype; int64_t defval; -- cgit v1.1 From a00c94824126901168bca5b89147f9e334a49e87 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Tue, 13 Oct 2015 13:37:40 +0100 Subject: qom: Introduce ObjectPropertyIterator struct for iteration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some users of QOM need to be able to iterate over properties defined against an object instance. Currently they are just directly using the QTAIL macros against the object properties data structure. This is bad because it exposes them to changes in the data structure used to store properties, as well as changes in functionality such as ability to register properties against the class. This provides an ObjectPropertyIterator struct which will insulate the callers from the particular data structure used to store properties. It can be used thus ObjectProperty *prop; ObjectPropertyIterator *iter; iter = object_property_iter_init(obj); while ((prop = object_property_iter_next(iter))) { ... do something with prop ... } object_property_iter_free(iter); Signed-off-by: Daniel P. Berrange Tested-by: Pavel Fedin [AF: Fixed examples, style cleanups] Signed-off-by: Andreas Färber --- include/qom/object.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'include') diff --git a/include/qom/object.h b/include/qom/object.h index 0bb89d4..9f70314 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -960,6 +960,55 @@ void object_property_del(Object *obj, const char *name, Error **errp); ObjectProperty *object_property_find(Object *obj, const char *name, Error **errp); +typedef struct ObjectPropertyIterator ObjectPropertyIterator; + +/** + * object_property_iter_init: + * @obj: the object + * + * Initializes an iterator for traversing all properties + * registered against an object instance. + * + * It is forbidden to modify the property list while iterating, + * whether removing or adding properties. + * + * Typical usage pattern would be + * + * + * Using object property iterators + * + * ObjectProperty *prop; + * ObjectPropertyIterator *iter; + * + * iter = object_property_iter_init(obj); + * while ((prop = object_property_iter_next(iter))) { + * ... do something with prop ... + * } + * object_property_iter_free(iter); + * + * + * + * Returns: the new iterator + */ +ObjectPropertyIterator *object_property_iter_init(Object *obj); + +/** + * object_property_iter_free: + * @iter: the iterator instance + * + * Releases any resources associated with the iterator. + */ +void object_property_iter_free(ObjectPropertyIterator *iter); + +/** + * object_property_iter_next: + * @iter: the iterator instance + * + * Returns: the next property, or %NULL when all properties + * have been traversed. + */ +ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter); + void object_unparent(Object *obj); /** -- cgit v1.1 From b604a854e843505007c59d68112c654556102a20 Mon Sep 17 00:00:00 2001 From: Pavel Fedin Date: Tue, 13 Oct 2015 13:37:45 +0100 Subject: qom: Replace object property list with GHashTable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ARM GICv3 systems with large number of CPUs create lots of IRQ pins. Since every pin is represented as a property, number of these properties becomes very large. Every property add first makes sure there's no duplicates. Traversing the list becomes very slow, therefore QEMU initialization takes significant time (several seconds for e. g. 16 CPUs). This patch replaces list with GHashTable, making lookup very fast. The only drawback is that object_child_foreach() and object_child_foreach_recursive() cannot add or remove properties during traversal, since GHashTableIter does not have modify-safe version. However, the code seems not to modify objects via these functions. Signed-off-by: Pavel Fedin Signed-off-by: Daniel P. Berrange Tested-by: Pavel Fedin [AF: Fixed object_property_del_{all,child}() issues; g_hash_table_contains() -> g_hash_table_lookup(), suggested by Daniel] Reviewed-by: Daniel P. Berrange Signed-off-by: Andreas Färber --- include/qom/object.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/qom/object.h b/include/qom/object.h index 9f70314..f172fea 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -344,8 +344,6 @@ typedef struct ObjectProperty ObjectPropertyResolve *resolve; ObjectPropertyRelease *release; void *opaque; - - QTAILQ_ENTRY(ObjectProperty) node; } ObjectProperty; /** @@ -405,7 +403,7 @@ struct Object /*< private >*/ ObjectClass *class; ObjectFree *free; - QTAILQ_HEAD(, ObjectProperty) properties; + GHashTable *properties; uint32_t ref; Object *parent; }; @@ -1537,6 +1535,9 @@ void object_property_set_description(Object *obj, const char *name, * Call @fn passing each child of @obj and @opaque to it, until @fn returns * non-zero. * + * It is forbidden to add or remove children from @obj from the @fn + * callback. + * * Returns: The last value returned by @fn, or 0 if there is no child. */ int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque), @@ -1552,6 +1553,9 @@ int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque), * non-zero. Calls recursively, all child nodes of @obj will also be passed * all the way down to the leaf nodes of the tree. Depth first ordering. * + * It is forbidden to add or remove children from @obj (or its + * child nodes) from the @fn callback. + * * Returns: The last value returned by @fn, or 0 if there is no child. */ int object_child_foreach_recursive(Object *obj, -- cgit v1.1