diff options
author | Steve Reinhardt <stever@gmail.com> | 2008-03-25 10:01:21 -0400 |
---|---|---|
committer | Steve Reinhardt <stever@gmail.com> | 2008-03-25 10:01:21 -0400 |
commit | 29be31ce3139c36f596e6edafbd3d253ee2200b3 (patch) | |
tree | 1a5f4364401b96594da0c4ae18f9d03a5b1ed19e | |
parent | 623dd7ed3a66e71e241dc8365c079cb5b42fa918 (diff) | |
download | gem5-29be31ce3139c36f596e6edafbd3d253ee2200b3.tar.xz |
Fix handling of writeback-induced writebacks in atomic mode.
--HG--
extra : convert_revision : 4fa64f8a929f1aa36a9d5a71b8d1816b497aca4c
-rw-r--r-- | src/mem/cache/cache.hh | 3 | ||||
-rw-r--r-- | src/mem/cache/cache_impl.hh | 50 |
2 files changed, 24 insertions, 29 deletions
diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh index f5f65d4dd..88c9deb7b 100644 --- a/src/mem/cache/cache.hh +++ b/src/mem/cache/cache.hh @@ -162,7 +162,8 @@ class Cache : public BaseCache * @return Pointer to the cache block touched by the request. NULL if it * was a miss. */ - bool access(PacketPtr pkt, BlkType *&blk, int &lat); + bool access(PacketPtr pkt, BlkType *&blk, + int &lat, PacketList &writebacks); /** *Handle doing the Compare and Swap function for SPARC. diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 47d20f915..7bab3012b 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -260,7 +260,8 @@ Cache<TagStore>::squash(int threadNum) template<class TagStore> bool -Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk, int &lat) +Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk, + int &lat, PacketList &writebacks) { if (pkt->req->isUncacheable()) { blk = NULL; @@ -308,7 +309,6 @@ Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk, int &lat) // into the cache without having a writeable copy (or any copy at // all). if (pkt->cmd == MemCmd::Writeback) { - PacketList writebacks; assert(blkSize == pkt->getSize()); if (blk == NULL) { // need to do a replacement @@ -323,12 +323,6 @@ Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk, int &lat) } std::memcpy(blk->data, pkt->getPtr<uint8_t>(), blkSize); blk->status |= BlkDirty; - // copy writebacks from replacement to write buffer - while (!writebacks.empty()) { - PacketPtr wbPkt = writebacks.front(); - allocateWriteBuffer(wbPkt, curTick + hitLatency, true); - writebacks.pop_front(); - } // nothing else to do; writeback doesn't expect response assert(!pkt->needsResponse()); hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++; @@ -427,13 +421,13 @@ Cache<TagStore>::timingAccess(PacketPtr pkt) int lat = hitLatency; BlkType *blk = NULL; - bool satisfied = access(pkt, blk, lat); + PacketList writebacks; + + bool satisfied = access(pkt, blk, lat, writebacks); #if 0 /** @todo make the fast write alloc (wh64) work with coherence. */ - PacketList writebacks; - // If this is a block size write/hint (WH64) allocate the block here // if the coherence protocol allows it. if (!blk && pkt->getSize() >= blkSize && coherence->allowFastWrites() && @@ -451,13 +445,6 @@ Cache<TagStore>::timingAccess(PacketPtr pkt) ++fastWrites; } } - - // copy writebacks to write buffer - while (!writebacks.empty()) { - PacketPtr wbPkt = writebacks.front(); - allocateWriteBuffer(wbPkt, time, true); - writebacks.pop_front(); - } #endif bool needsResponse = pkt->needsResponse(); @@ -527,6 +514,13 @@ Cache<TagStore>::timingAccess(PacketPtr pkt) } } + // copy writebacks to write buffer + while (!writebacks.empty()) { + PacketPtr wbPkt = writebacks.front(); + allocateWriteBuffer(wbPkt, time, true); + writebacks.pop_front(); + } + return true; } @@ -614,8 +608,9 @@ Cache<TagStore>::atomicAccess(PacketPtr pkt) // access in timing mode BlkType *blk = NULL; + PacketList writebacks; - if (!access(pkt, blk, lat)) { + if (!access(pkt, blk, lat, writebacks)) { // MISS PacketPtr busPkt = getBusPacket(pkt, blk, pkt->needsExclusive()); @@ -646,21 +641,20 @@ Cache<TagStore>::atomicAccess(PacketPtr pkt) pkt->makeAtomicResponse(); pkt->copyError(busPkt); } else if (isCacheFill && !is_error) { - PacketList writebacks; blk = handleFill(busPkt, blk, writebacks); satisfyCpuSideRequest(pkt, blk); delete busPkt; - - // Handle writebacks if needed - while (!writebacks.empty()){ - PacketPtr wbPkt = writebacks.front(); - memSidePort->sendAtomic(wbPkt); - writebacks.pop_front(); - delete wbPkt; - } } } + // Handle writebacks if needed + while (!writebacks.empty()){ + PacketPtr wbPkt = writebacks.front(); + memSidePort->sendAtomic(wbPkt); + writebacks.pop_front(); + delete wbPkt; + } + // We now have the block one way or another (hit or completed miss) if (pkt->needsResponse()) { |