summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Dreslinski <rdreslin@umich.edu>2006-11-13 22:37:22 -0500
committerRon Dreslinski <rdreslin@umich.edu>2006-11-13 22:37:22 -0500
commit903a61871438fc872a4762e4d782264cbbd02154 (patch)
tree68583be309085a163edb5d22d16f9f68bac8f513
parentdb0895084d11158f5d121e23949cc5d3ef7df748 (diff)
downloadgem5-903a61871438fc872a4762e4d782264cbbd02154.tar.xz
Fix a bug to handle the fact that a CPU can send Functional accesses while a sendTiming has not returned in the call stack.
src/mem/cache/base_cache.cc: Sometimes a functional access comes while waiting on a outstanding packet being sent. This could be because Timing CPU does some post processing on the recvTiming which send functional access. Either the CPU should leave the pkt/req around (so They can be referenced in the mem system). Or the mem system should remove them from outstanding lists and reinsert them if they fail in the sendTiming. I did the later, eventually we should consider doing the former if that is the correct behavior. --HG-- extra : convert_revision : be41e0d2632369dca9d7c15e96e5576d7583fe6a
-rw-r--r--src/mem/cache/base_cache.cc14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc
index c16cb6945..3af61375d 100644
--- a/src/mem/cache/base_cache.cc
+++ b/src/mem/cache/base_cache.cc
@@ -160,11 +160,14 @@ BaseCache::CachePort::recvRetry()
PacketPtr pkt;
assert(waitingOnRetry);
if (!drainList.empty()) {
- DPRINTF(CachePort, "%s attempting to send a retry for response\n", name());
+ DPRINTF(CachePort, "%s attempting to send a retry for response (%i waiting)\n"
+ , name(), drainList.size());
//We have some responses to drain first
- if (sendTiming(drainList.front())) {
- DPRINTF(CachePort, "%s sucessful in sending a retry for response\n", name());
- drainList.pop_front();
+ pkt = drainList.front();
+ drainList.pop_front();
+ if (sendTiming(pkt)) {
+ DPRINTF(CachePort, "%s sucessful in sending a retry for"
+ "response (%i still waiting)\n", name(), drainList.size());
if (!drainList.empty() ||
!isCpuSide && cache->doMasterRequest() ||
isCpuSide && cache->doSlaveRequest()) {
@@ -175,6 +178,9 @@ BaseCache::CachePort::recvRetry()
}
waitingOnRetry = false;
}
+ else {
+ drainList.push_front(pkt);
+ }
// Check if we're done draining once this list is empty
if (drainList.empty())
cache->checkDrain();