From b2b6c39a7915e82cade4ab8689344c91c5e45653 Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Mon, 12 Dec 2011 14:29:40 -0600 Subject: [PATCH] qom: optimize qdev_get_canonical_path using a parent link The full tree search was a bit unreasonable. Signed-off-by: Anthony Liguori --- hw/qdev.c | 56 ++++++++++++++++++++++++-------------------------------- hw/qdev.h | 4 ++++ 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index 4d491f109e..4004860239 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -1229,6 +1229,8 @@ void qdev_property_add_child(DeviceState *dev, const char *name, NULL, NULL, child, errp); qdev_ref(child); + g_assert(child->parent == NULL); + child->parent = dev; g_free(type); } @@ -1307,48 +1309,38 @@ void qdev_property_add_link(DeviceState *dev, const char *name, g_free(full_type); } -static gchar *qdev_get_path_in(DeviceState *parent, DeviceState *dev) +gchar *qdev_get_canonical_path(DeviceState *dev) { - DeviceProperty *prop; + DeviceState *root = qdev_get_root(); + char *newpath = NULL, *path = NULL; - if (parent == dev) { - return g_strdup(""); - } + while (dev != root) { + DeviceProperty *prop = NULL; - QTAILQ_FOREACH(prop, &parent->properties, node) { - gchar *subpath; + g_assert(dev->parent != NULL); - if (!strstart(prop->type, "child<", NULL)) { - continue; - } + QTAILQ_FOREACH(prop, &dev->parent->properties, node) { + if (!strstart(prop->type, "child<", NULL)) { + continue; + } - /* Check to see if the device is one of parent's children */ - if (prop->opaque == dev) { - return g_strdup(prop->name); + if (prop->opaque == dev) { + if (path) { + newpath = g_strdup_printf("%s/%s", prop->name, path); + g_free(path); + path = newpath; + } else { + path = g_strdup(prop->name); + } + break; + } } - /* Check to see if the device is a child of our child */ - subpath = qdev_get_path_in(prop->opaque, dev); - if (subpath) { - gchar *path; + g_assert(prop != NULL); - path = g_strdup_printf("%s/%s", prop->name, subpath); - g_free(subpath); - - return path; - } + dev = dev->parent; } - return NULL; -} - -gchar *qdev_get_canonical_path(DeviceState *dev) -{ - gchar *path, *newpath; - - path = qdev_get_path_in(qdev_get_root(), dev); - g_assert(path != NULL); - newpath = g_strdup_printf("/%s", path); g_free(path); diff --git a/hw/qdev.h b/hw/qdev.h index 4351e2e5af..fdab84835e 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -92,6 +92,10 @@ struct DeviceState { uint32_t ref; QTAILQ_HEAD(, DeviceProperty) properties; + + /* Do not, under any circumstance, use this parent link below anywhere + * outside of qdev.c. You have been warned. */ + DeviceState *parent; }; typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent); -- 2.11.0