diff options
author | Ron Dreslinski <rdreslin@umich.edu> | 2006-11-13 22:37:22 -0500 |
---|---|---|
committer | Ron Dreslinski <rdreslin@umich.edu> | 2006-11-13 22:37:22 -0500 |
commit | 903a61871438fc872a4762e4d782264cbbd02154 (patch) | |
tree | 68583be309085a163edb5d22d16f9f68bac8f513 | |
parent | db0895084d11158f5d121e23949cc5d3ef7df748 (diff) | |
download | gem5-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.cc | 14 |
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(); |