The MemoryObject tha owns a port should delete it if it so chooses when deletePortRef...
authorAli Saidi <saidi@eecs.umich.edu>
Wed, 4 Apr 2007 17:56:38 +0000 (13:56 -0400)
committerAli Saidi <saidi@eecs.umich.edu>
Wed, 4 Apr 2007 17:56:38 +0000 (13:56 -0400)
In this way a MemoryObject can keep a functional port around and give it to anyone who wants to do functional accesses rather
than creating a new one each time.

src/mem/bus.cc:
src/mem/bus.hh:
src/mem/cache/cache_impl.hh:
    only keep around one func port we give to anyone who wants it. Otherwise we can run out of port ids reasonably quickly if
    a lot of functional accesses are happening (e.g. remote debugging, dprintk, etc)

--HG--
extra : convert_revision : 6a9e3e96f51cedaab6de1b36cf317203899a3716

src/mem/bus.cc
src/mem/bus.hh
src/mem/cache/cache_impl.hh
src/mem/port.cc

index 6e6ba2380558f87c2faba2a27670f6de247a3126..b0636ecc2c3f105165a72e7d810178c08a60840e 100644 (file)
@@ -52,9 +52,19 @@ Bus::getPort(const std::string &if_name, int idx)
         } else
             fatal("Default port already set\n");
     }
+    int id;
+    if (if_name == "functional") {
+        if (!funcPort) {
+            id = maxId++;
+            funcPort = new BusPort(csprintf("%s-p%d-func", name(), id), this, id);
+            funcPortId = id;
+            interfaces[id] = funcPort;
+        }
+        return funcPort;
+    }
 
     // if_name ignored?  forced to be empty?
-    int id = maxId++;
+    id = maxId++;
     assert(maxId < std::numeric_limits<typeof(maxId)>::max());
     BusPort *bp = new BusPort(csprintf("%s-p%d", name(), id), this, id);
     interfaces[id] = bp;
@@ -64,10 +74,15 @@ Bus::getPort(const std::string &if_name, int idx)
 void
 Bus::deletePortRefs(Port *p)
 {
+
     BusPort *bp =  dynamic_cast<BusPort*>(p);
     if (bp == NULL)
         panic("Couldn't convert Port* to BusPort*\n");
+    // If this is our one functional port
+    if (funcPort == bp)
+        return;
     interfaces.erase(bp->getId());
+    delete bp;
 }
 
 /** Get the ranges of anyone other buses that we are connected to. */
@@ -520,7 +535,7 @@ Bus::recvStatusChange(Port::Status status, int id)
     m5::hash_map<short,BusPort*>::iterator intIter;
 
     for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
-        if (intIter->first != id)
+        if (intIter->first != id && intIter->first != funcPortId)
             intIter->second->sendStatusChange(Port::RangeChange);
 
     if (id != defaultId && defaultPort)
index 6706b6c7752a1b981ce058262b9a6df241dc0157..0dd7547c523291924aca6a7fc24afb74abfa0bde 100644 (file)
@@ -63,6 +63,7 @@ class Bus : public MemObject
 
     Event * drainEvent;
 
+
     static const int defaultId = -3; //Make it unique from Broadcast
 
     struct DevMap {
@@ -249,6 +250,9 @@ class Bus : public MemObject
     /** Port that handles requests that don't match any of the interfaces.*/
     BusPort *defaultPort;
 
+    BusPort *funcPort;
+    int funcPortId;
+
     /** Has the user specified their own default responder? */
     bool responderSet;
 
@@ -266,7 +270,8 @@ class Bus : public MemObject
         bool responder_set)
         : MemObject(n), busId(bus_id), clock(_clock), width(_width),
           tickNextIdle(0), drainEvent(NULL), busIdle(this), inRetry(false),
-          maxId(0), defaultPort(NULL), responderSet(responder_set)
+          maxId(0), defaultPort(NULL), funcPort(NULL), funcPortId(-4),
+          responderSet(responder_set)
     {
         //Both the width and clock period must be positive
         if (width <= 0)
index ec0ef1be45b8b03c637b1fc820f2547f9e3f7a67..0a528aa5d8aee39619ea267664506e036e8cb120 100644 (file)
@@ -1183,7 +1183,8 @@ Cache<TagStore,Coherence>::deletePortRefs(Port *p)
 {
     if (cpuSidePort == p || memSidePort == p)
         panic("Can only delete functional ports\n");
-    // nothing else to do
+
+    delete p;
 }
 
 
index e75e50e4d43ec4e1460c0c1c8ccec88645ab2529..e6ea773f24abf73e8b34d61af18424a808482c21 100644 (file)
@@ -51,7 +51,6 @@ Port::removeConn()
 {
     if (peer->getOwner())
         peer->getOwner()->deletePortRefs(peer);
-    delete peer;
     peer = NULL;
 }