if (pkt->isInvalidate()) {
// Invalidation trumps our writeback... discard here
- assert(0);
markInService(mshr);
}
return;
} else {
// check for non-response packets (requests & writebacks)
PacketPtr pkt = myCache()->getTimingPacket();
- assert(pkt != NULL);
- MSHR *mshr = dynamic_cast<MSHR*>(pkt->senderState);
+ if (pkt == NULL) {
+ // can happen if e.g. we attempt a writeback and fail, but
+ // before the retry, the writeback is eliminated because
+ // we snoop another cache's ReadEx.
+ waitingOnRetry = false;
+ } else {
+ MSHR *mshr = dynamic_cast<MSHR*>(pkt->senderState);
- bool success = sendTiming(pkt);
- DPRINTF(Cache, "Address %x was %s in sending the timing request\n",
- pkt->getAddr(), success ? "successful" : "unsuccessful");
+ bool success = sendTiming(pkt);
+ DPRINTF(Cache, "Address %x was %s in sending the timing request\n",
+ pkt->getAddr(), success ? "successful" : "unsuccessful");
- waitingOnRetry = !success;
- if (waitingOnRetry) {
- DPRINTF(CachePort, "now waiting on a retry\n");
- } else {
- myCache()->markInService(mshr);
+ waitingOnRetry = !success;
+ if (waitingOnRetry) {
+ DPRINTF(CachePort, "now waiting on a retry\n");
+ } else {
+ myCache()->markInService(mshr);
+ }
}
}
// We're awaiting an exclusive copy, so ownership is pending.
// It's up to us to respond once the data arrives.
target->assertMemInhibit();
- } else if (target->needsExclusive()) {
+ }
+
+ if (target->needsExclusive()) {
// This transaction will take away our pending copy
pendingInvalidate = true;
} else {
- // If we're not going to supply data or perform an
- // invalidation, we don't need to save this.
- return;
+ // We'll keep our pending copy, but we can't let the other guy
+ // think he's getting it exclusive
+ target->assertShared();
}
targets.push_back(Target(target, when, _order, false));