[PATCH phosphor-objmgr] Performance improvements
OpenBMC Patches
openbmc-patches at stwcx.xyz
Mon Jun 6 14:10:46 AEST 2016
From: Brad Bishop <bradleyb at fuzziesquirrel.com>
Prior to this patch, an excessive ( more than zero ) number of dbus
calls were made to determine if a signal was something we care about.
This patch adds a well-known to unique connection name translation cache
eliminating all outgoing dbus calls.
Also removed the abstraction layer that obscured this as it isn't used.
Signed-off-by: Brad Bishop <bradleyb at fuzziesquirrel.com>
---
phosphor-mapper | 102 ++++++++++++++++++++++++++------------------------------
1 file changed, 47 insertions(+), 55 deletions(-)
diff --git a/phosphor-mapper b/phosphor-mapper
index 944f6d4..ea30f1b 100644
--- a/phosphor-mapper
+++ b/phosphor-mapper
@@ -152,14 +152,14 @@ class Association(dbus.service.Object):
class Manager(obmc.dbuslib.bindings.DbusObjectManager):
def __init__(self, bus, path):
obmc.dbuslib.bindings.DbusObjectManager.__init__(self)
- dbus.service.Object.__init__(self, bus.dbus, path)
+ dbus.service.Object.__init__(self, bus, path)
class ObjectMapper(dbus.service.Object):
def __init__(self, bus, path,
name_match=obmc.utils.misc.org_dot_openbmc_match,
intf_match=obmc.utils.misc.org_dot_openbmc_match):
- super(ObjectMapper, self).__init__(bus.dbus, path)
+ super(ObjectMapper, self).__init__(bus, path)
self.cache = obmc.utils.pathtree.PathTree()
self.bus = bus
self.name_match = name_match
@@ -168,28 +168,29 @@ class ObjectMapper(dbus.service.Object):
self.service = None
self.index = {}
self.manager = Manager(bus, obmc.dbuslib.bindings.OBJ_PREFIX)
- self.unique = bus.dbus.get_unique_name()
+ self.unique = bus.get_unique_name()
+ self.bus_map = {}
gobject.idle_add(self.discover)
- self.bus.dbus.add_signal_receiver(
+ self.bus.add_signal_receiver(
self.bus_handler,
dbus_interface=
dbus.BUS_DAEMON_IFACE,
signal_name='NameOwnerChanged')
- self.bus.dbus.add_signal_receiver(
+ self.bus.add_signal_receiver(
self.interfaces_added_handler,
dbus_interface=
dbus.BUS_DAEMON_IFACE + '.ObjectManager',
signal_name='InterfacesAdded',
sender_keyword='sender',
path_keyword='sender_path')
- self.bus.dbus.add_signal_receiver(
+ self.bus.add_signal_receiver(
self.interfaces_removed_handler,
dbus_interface=dbus.BUS_DAEMON_IFACE + '.ObjectManager',
signal_name='InterfacesRemoved',
sender_keyword='sender',
path_keyword='sender_path')
- self.bus.dbus.add_signal_receiver(
+ self.bus.add_signal_receiver(
self.properties_changed_handler,
dbus_interface=dbus.PROPERTIES_IFACE,
signal_name='PropertiesChanged',
@@ -226,10 +227,10 @@ class ObjectMapper(dbus.service.Object):
interfaces = self.get_signal_interfaces(owner, iprops.iterkeys())
if interfaces:
self.add_new_objmgr(str(kw['sender_path']), owner)
- cache_entry = self.cache_get(path)
- old = self.interfaces_get(cache_entry, owner)
- new = list(set(interfaces).union(old))
- self.update_interfaces(path, owner, old, new)
+ cache_entry = self.cache_get(path)
+ old = self.interfaces_get(cache_entry, owner)
+ new = list(set(interfaces).union(old))
+ self.update_interfaces(path, owner, old, new)
def interfaces_removed_handler(self, path, interfaces, **kw):
path = str(path)
@@ -237,10 +238,10 @@ class ObjectMapper(dbus.service.Object):
interfaces = self.get_signal_interfaces(owner, interfaces)
if interfaces:
self.add_new_objmgr(str(kw['sender_path']), owner)
- cache_entry = self.cache_get(path)
- old = self.interfaces_get(cache_entry, owner)
- new = list(set(old).difference(interfaces))
- self.update_interfaces(path, owner, old, new)
+ cache_entry = self.cache_get(path)
+ old = self.interfaces_get(cache_entry, owner)
+ new = list(set(old).difference(interfaces))
+ self.update_interfaces(path, owner, old, new)
def properties_changed_handler(self, interface, new, old, **kw):
owner = str(kw['sender'])
@@ -259,31 +260,34 @@ class ObjectMapper(dbus.service.Object):
self.index_get_associations(path, [owner]),
associations)
- def process_new_owner(self, owner):
+ def process_new_owner(self, owned_name, owner):
# unique name
try:
- return self.discover([owner])
+ return self.discover([(owned_name, owner)])
except dbus.exceptions.DBusException, e:
if obmc.dbuslib.enums.DBUS_UNKNOWN_SERVICE \
not in e.get_dbus_name():
raise
- def process_old_owner(self, owner):
+ def process_old_owner(self, owned_name, owner):
+ if owner in self.bus_map:
+ del self.bus_map[owner]
+
for path, item in self.cache.dataitems():
old = self.interfaces_get(item, owner)
# remove all interfaces for this service
self.update_interfaces(
path, owner, old=old, new=[])
- def bus_handler(self, owner, old, new):
+ def bus_handler(self, owned_name, old, new):
valid = False
- if not obmc.dbuslib.bindings.is_unique(owner):
- valid = self.valid_signal(owner)
+ if not obmc.dbuslib.bindings.is_unique(owned_name):
+ valid = self.valid_signal(owned_name)
if valid and new:
- self.process_new_owner(new)
+ self.process_new_owner(owned_name, new)
if valid and old:
- self.process_old_owner(old)
+ self.process_old_owner(owned_name, old)
def update_interfaces(self, path, owner, old, new):
cache_entry = self.cache.setdefault(path, {})
@@ -315,14 +319,19 @@ class ObjectMapper(dbus.service.Object):
return iface == dbus.BUS_DAEMON_IFACE + '.ObjectManager' or \
self.intf_match(iface)
if not owners:
- owners = self.bus.get_owner_names(self.bus_match)
- for o in owners:
+ owned_names = [x for x in self.bus.list_names()
+ if self.bus_match(x)]
+ owners = [self.bus.get_name_owner(x) for x in owned_names]
+ owners = zip(owned_names, owners)
+ for owned_name, o in owners:
self.add_items(
o,
- find_dbus_interfaces(self.bus.dbus, o, '/', self.intf_match))
+ find_dbus_interfaces(self.bus, o, '/', self.intf_match))
+ self.bus_map[o] = owned_name
if self.discovery_pending():
# add my object mananger instance
+ self.bus_map[self.unique] = obmc.mapper.MAPPER_NAME
self.add_items(
self.unique,
{obmc.dbuslib.bindings.OBJ_PREFIX:
@@ -331,14 +340,17 @@ class ObjectMapper(dbus.service.Object):
print "ObjectMapper discovery complete..."
self.service = dbus.service.BusName(
- obmc.mapper.MAPPER_NAME, self.bus.dbus)
+ obmc.mapper.MAPPER_NAME, self.bus)
+
+ def valid_signal(self, name):
+ if self.discovery_pending():
+ return False
- def valid_signal(self, owner):
- if obmc.dbuslib.bindings.is_unique(owner):
- owner = self.bus.get_owned_name(self.bus_match, owner)
+ if obmc.dbuslib.bindings.is_unique(name):
+ name = self.bus_map.get(name)
- return owner is not None and not self.discovery_pending() and \
- self.bus_match(owner)
+ return name is not None and \
+ self.bus_match(name)
def get_signal_interfaces(self, owner, interfaces):
filtered = []
@@ -435,7 +447,7 @@ class ObjectMapper(dbus.service.Object):
del index[path]
def dbus_get_associations(self, path, owner):
- obj = self.bus.dbus.get_object(owner, path, introspect=False)
+ obj = self.bus.get_object(owner, path, introspect=False)
iface = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
return [(str(f), str(r), str(e)) for f, r, e in iface.Get(
obmc.dbuslib.enums.OBMC_ASSOCIATIONS_IFACE,
@@ -472,7 +484,7 @@ class ObjectMapper(dbus.service.Object):
if added and create:
self.manager.add(
- path, Association(self.bus.dbus, path, added))
+ path, Association(self.bus, path, added))
elif added:
self.manager.get(path).append(added)
@@ -561,30 +573,10 @@ class ObjectMapper(dbus.service.Object):
return objs
-class BusWrapper:
- def __init__(self, bus):
- self.dbus = bus
-
- def get_owned_name(self, match, bus):
- for x in self.get_service_names(match):
- if self.dbus.get_name_owner(x) == bus:
- return x
-
- def get_service_names(self, match):
- # these are well known names
- return [x for x in self.dbus.list_names()
- if match(x)]
-
- def get_owner_names(self, match):
- # these are unique connection names
- return list(set(
- [self.dbus.get_name_owner(x)
- for x in self.get_service_names(match)]))
-
if __name__ == '__main__':
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
- o = ObjectMapper(BusWrapper(bus), obmc.mapper.MAPPER_PATH)
+ o = ObjectMapper(bus, obmc.mapper.MAPPER_PATH)
loop = gobject.MainLoop()
loop.run()
--
2.8.3
More information about the openbmc
mailing list