Fix handling of writeback-induced writebacks in atomic mode.

--HG--
extra : convert_revision : 4fa64f8a929f1aa36a9d5a71b8d1816b497aca4c
This commit is contained in:
Steve Reinhardt
2008-03-25 10:01:21 -04:00
parent 623dd7ed3a
commit 29be31ce31
2 changed files with 24 additions and 29 deletions

View File

@@ -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.

View File

@@ -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()) {