summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Saidi <saidi@eecs.umich.edu>2007-04-04 13:56:38 -0400
committerAli Saidi <saidi@eecs.umich.edu>2007-04-04 13:56:38 -0400
commitd0ea8ff08849f45196fa6c8d69d5a408d9cbbafd (patch)
tree5fba9c44fb5e1072524963b82aabf0ef1cd51632
parentc46e946c94cf730bd2c22de27d3af43955b63ba9 (diff)
downloadgem5-d0ea8ff08849f45196fa6c8d69d5a408d9cbbafd.tar.xz
The MemoryObject tha owns a port should delete it if it so chooses when deletePortRefs() is called on it with that port as a parameter.
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
-rw-r--r--src/mem/bus.cc19
-rw-r--r--src/mem/bus.hh7
-rw-r--r--src/mem/cache/cache_impl.hh3
-rw-r--r--src/mem/port.cc1
4 files changed, 25 insertions, 5 deletions
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index 6e6ba2380..b0636ecc2 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -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)
diff --git a/src/mem/bus.hh b/src/mem/bus.hh
index 6706b6c77..0dd7547c5 100644
--- a/src/mem/bus.hh
+++ b/src/mem/bus.hh
@@ -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)
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index ec0ef1be4..0a528aa5d 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -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;
}
diff --git a/src/mem/port.cc b/src/mem/port.cc
index e75e50e4d..e6ea773f2 100644
--- a/src/mem/port.cc
+++ b/src/mem/port.cc
@@ -51,7 +51,6 @@ Port::removeConn()
{
if (peer->getOwner())
peer->getOwner()->deletePortRefs(peer);
- delete peer;
peer = NULL;
}