summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2014-09-03 07:42:53 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2014-09-03 07:42:53 -0400
commit1ff4c45bbbaa22d5bd91e9bdd34d4435290ab8be (patch)
tree8249a3f3b73194cf9ccc6ce921ff6cf97052ed4d
parent8f95144e161ef7bdb264eb572108a98f215785c0 (diff)
downloadgem5-1ff4c45bbbaa22d5bd91e9bdd34d4435290ab8be.tar.xz
mem: Avoid unecessary retries when bus peer is not ready
This patch removes unecessary retries that happened when the bus layer itself was no longer busy, but the the peer was not yet ready. Instead of sending a retry that will inevitably not succeed, the bus now silenty waits until the peer sends a retry.
-rw-r--r--src/mem/bus.cc15
-rw-r--r--src/mem/bus.hh8
2 files changed, 6 insertions, 17 deletions
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index 5ab7e5b04..730c612ca 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -136,8 +136,7 @@ template <typename SrcType, typename DstType>
BaseBus::Layer<SrcType,DstType>::Layer(DstType& _port, BaseBus& _bus,
const std::string& _name) :
port(_port), bus(_bus), _name(_name), state(IDLE), drainManager(NULL),
- retryingPort(NULL), waitingForPeer(NULL),
- releaseEvent(this)
+ waitingForPeer(NULL), releaseEvent(this)
{
}
@@ -190,9 +189,6 @@ BaseBus::Layer<SrcType,DstType>::tryTiming(SrcType* src_port)
// update the state to busy
state = BUSY;
- // reset the retrying port
- retryingPort = NULL;
-
return true;
}
@@ -243,7 +239,10 @@ BaseBus::Layer<SrcType,DstType>::releaseLayer()
// bus layer is now idle, so if someone is waiting we can retry
if (!waitingForLayer.empty()) {
- retryWaiting();
+ // there is no point in sending a retry if someone is still
+ // waiting for the peer
+ if (waitingForPeer == NULL)
+ retryWaiting();
} else if (waitingForPeer == NULL && drainManager) {
DPRINTF(Drain, "Bus done draining, signaling drain manager\n");
//If we weren't able to drain before, do it now.
@@ -268,8 +267,7 @@ BaseBus::Layer<SrcType,DstType>::retryWaiting()
// set the retrying port to the front of the retry list and pop it
// off the list
- assert(retryingPort == NULL);
- retryingPort = waitingForLayer.front();
+ SrcType* retryingPort = waitingForLayer.front();
waitingForLayer.pop_front();
// tell the port to retry, which in some cases ends up calling the
@@ -282,7 +280,6 @@ BaseBus::Layer<SrcType,DstType>::retryWaiting()
// update the state to busy and reset the retrying port, we
// have done our bit and sent the retry
state = BUSY;
- retryingPort = NULL;
// occupy the bus layer until the next cycle ends
occupyLayer(bus.clockEdge(Cycles(1)));
diff --git a/src/mem/bus.hh b/src/mem/bus.hh
index bdcf319f4..f01a3ae7f 100644
--- a/src/mem/bus.hh
+++ b/src/mem/bus.hh
@@ -221,14 +221,6 @@ class BaseBus : public MemObject
std::deque<SrcType*> waitingForLayer;
/**
- * Port that we are currently in the process of telling to
- * retry a previously failed attempt to perform a timing
- * transaction. This is a valid port when in the retry state,
- * and NULL when in busy or idle.
- */
- SrcType* retryingPort;
-
- /**
* Track who is waiting for the retry when receiving it from a
* peer. If no port is waiting NULL is stored.
*/