diff options
author | Steve Reinhardt <stever@eecs.umich.edu> | 2007-07-23 22:28:40 -0700 |
---|---|---|
committer | Steve Reinhardt <stever@eecs.umich.edu> | 2007-07-23 22:28:40 -0700 |
commit | 1f9ea6e122f6a39d936aec2f8f5ce72d267799a8 (patch) | |
tree | 973cc374a80ae441a3ef6c7888342244a37d394f /src/mem/cache/cache_impl.hh | |
parent | 97f7ee2e507733eb9dd1802c16900fd14ae6b7f3 (diff) | |
download | gem5-1f9ea6e122f6a39d936aec2f8f5ce72d267799a8.tar.xz |
A couple more minor bug fixes for multilevel coherence.
--HG--
extra : convert_revision : 370f9e34911157765be6fd49e826fa1af589b466
Diffstat (limited to 'src/mem/cache/cache_impl.hh')
-rw-r--r-- | src/mem/cache/cache_impl.hh | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index efd7f4588..412d10599 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -148,7 +148,13 @@ void Cache<TagStore>::satisfyCpuSideRequest(PacketPtr pkt, BlkType *blk) { assert(blk); - assert(pkt->needsExclusive() ? blk->isWritable() : blk->isValid()); + // Occasionally this is not true... if we are a lower-level cache + // satisfying a string of Read and ReadEx requests from + // upper-level caches, a Read will mark the block as shared but we + // can satisfy a following ReadEx anyway since we can rely on the + // Read requester(s) to have buffered the ReadEx snoop and to + // invalidate their blocks after receiving them. + // assert(pkt->needsExclusive() ? blk->isWritable() : blk->isValid()); assert(pkt->getOffset(blkSize) + pkt->getSize() <= blkSize); // Check RMW operations first since both isRead() and @@ -727,7 +733,7 @@ Cache<TagStore>::handleResponse(PacketPtr pkt) Tick completion_time; if (blk != NULL) { satisfyCpuSideRequest(target->pkt, blk); - // How many bytes pass the first request is this one + // How many bytes past the first request is this one int transfer_offset = target->pkt->getOffset(blkSize) - initial_offset; if (transfer_offset < 0) { @@ -738,10 +744,9 @@ Cache<TagStore>::handleResponse(PacketPtr pkt) completion_time = tags->getHitLatency() + transfer_offset ? pkt->finishTime : pkt->firstWordTime; - if (!target->pkt->req->isUncacheable()) { - missLatency[target->pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/] += - completion_time - target->recvTime; - } + assert(!target->pkt->req->isUncacheable()); + missLatency[target->pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/] += + completion_time - target->recvTime; } else { // not a cache fill, just forwarding response completion_time = tags->getHitLatency() + pkt->finishTime; @@ -1004,7 +1009,9 @@ template<class TagStore> void Cache<TagStore>::snoopTiming(PacketPtr pkt) { - if (pkt->req->isUncacheable()) { + // Note that some deferred snoops don't have requests, since the + // original access may have already completed + if (pkt->req && pkt->req->isUncacheable()) { //Can't get a hit on an uncacheable address //Revisit this for multi level coherence return; |