Hello Jason Lowe-Power,

I'd like you to do a code review. Please visit

    https://gem5-review.googlesource.com/4400

to review the following change.


Change subject: python: Add a function to delete references to a SimObject
......................................................................

python: Add a function to delete references to a SimObject

There are times (e.g., in the new TLB switching logic) where you may
want to delete a SimObject. This patch adds a deleteRefs(simobj)
function that ensures that 'simobj' is not referenced by its parent or
by any ports. Additionally, all of the children of simobj will have
their ports cleared as well.

Change-Id: I0e7e3fb9ad2fa9daddb5c63ccca22e43d2e33ad4
Signed-off-by: Jason Lowe-Power <[email protected]>
---
M src/python/m5/SimObject.py
M src/python/m5/params.py
2 files changed, 52 insertions(+), 0 deletions(-)



diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py
index baeef73..f2dca97 100644
--- a/src/python/m5/SimObject.py
+++ b/src/python/m5/SimObject.py
@@ -1228,6 +1228,20 @@
         child.set_parent(self, name)
         self._children[name] = child

+    def removePorts(self):
+ """Iterate through children and make sure there are no ports that are + going to be connected to this object later. This is used as a step
+           in deleting a SimObject that may have been partially setup.
+        """
+        for obj in self.descendants():
+            if obj != self:
+                obj.removePorts()
+
+        for port_name in sorted(self._ports.keys()):
+            port = self._port_refs.get(port_name, None)
+            if port != None:
+                port.disconnect()
+
     # Take SimObject-valued parameters that haven't been explicitly
     # assigned as children and make them children of the object that
     # they were assigned to as a parameter value.  This guarantees
@@ -1540,6 +1554,17 @@
         raise TypeError, "SimObject or SimObjectVector expected"
     return value

+def deleteRefs(obj):
+    """Delete references to obj.
+       This function deletes obj from its parent's children and makes sure
+       to remove any dangling port connections.
+    """
+    if obj == NULL:
+        return
+    if obj._parent:
+        obj._parent.clear_child(obj.get_name())
+    obj.removePorts()
+
 baseClasses = allClasses.copy()
 baseInstances = instanceDict.copy()

@@ -1558,4 +1583,5 @@
     'cxxMethod',
     'PyBindMethod',
     'PyBindProperty',
+    'deleteRefs',
 ]
diff --git a/src/python/m5/params.py b/src/python/m5/params.py
index 776fbe2..3932a12 100644
--- a/src/python/m5/params.py
+++ b/src/python/m5/params.py
@@ -1748,6 +1748,7 @@
         self.name = name
         self.role = role
         self.peer = None   # not associated with another port yet
+        self.peerVector = None # Save the vector ref in case it's needed
         self.ccConnected = False # C++ port connection done?
         self.index = -1  # always -1 for non-vector ports

@@ -1781,6 +1782,7 @@
     def connect(self, other):
         if isinstance(other, VectorPortRef):
             # reference to plain VectorPort is implicit append
+            self.peerVector = other
             other = other._get_next()
         if self.peer and not proxy.isproxy(self.peer):
fatal("Port %s is already connected to %s, cannot connect %s\n",
@@ -1826,6 +1828,23 @@
         else:
fatal("Port %s not connected, cannot splice in new peers\n", self)

+    def disconnect(self):
+        """The opposite of connect. Called from removePorts in SimObject.
+ This will only work if the ports have not been connected via C++ and
+           nothing happens if this port is not connected.
+        """
+        if self.ccConnected:
+ fatal("Cannot disconnect %s. Already connected in C++!" % (self))
+        if self.peer and not proxy.isproxy(self.peer):
+            if isinstance(self.peer, VectorPortElementRef):
+                assert(self.peerVector != None)
+                # Remove the peer port from the vector its in
+                del self.peerVector[self.peer.index]
+            # Clear ourselves from the peer vector
+            self.peer.peer = None
+            # Clear our peer
+            self.peer = None
+
     def clone(self, simobj, memo):
         if memo.has_key(self):
             return memo[self]
@@ -1910,6 +1929,13 @@
         # length of the elements.
         return len(self.elements)

+    def __delitem__(self, idx):
+        """Delete a port from this port vector."""
+        del self.elements[idx]
+        # Fix up the indicies
+        for i,el in enumerate(self.elements):
+            el.index = i
+
     # for config.ini, print peer's name (not ours)
     def ini_str(self):
         return ' '.join([el.ini_str() for el in self.elements])

--
To view, visit https://gem5-review.googlesource.com/4400
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0e7e3fb9ad2fa9daddb5c63ccca22e43d2e33ad4
Gerrit-Change-Number: 4400
Gerrit-PatchSet: 1
Gerrit-Owner: Sean Wilson <[email protected]>
Gerrit-Reviewer: Jason Lowe-Power <[email protected]>
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to