diff options
Diffstat (limited to 'src/mem/cache/miss')
-rw-r--r-- | src/mem/cache/miss/mshr.cc | 90 | ||||
-rw-r--r-- | src/mem/cache/miss/mshr.hh | 17 |
2 files changed, 75 insertions, 32 deletions
diff --git a/src/mem/cache/miss/mshr.cc b/src/mem/cache/miss/mshr.cc index 1f2c05a6e..24ff3b33c 100644 --- a/src/mem/cache/miss/mshr.cc +++ b/src/mem/cache/miss/mshr.cc @@ -68,12 +68,16 @@ MSHR::allocate(Addr _addr, int _size, PacketPtr target) // Don't know of a case where we would allocate a new MSHR for a // snoop (mem0-side request), so set cpuSide to true here. targets.push_back(Target(target, true)); + assert(deferredTargets.empty()); + deferredNeedsExclusive = false; + pendingInvalidate = false; } void MSHR::deallocate() { assert(targets.empty()); + assert(deferredTargets.empty()); assert(ntargets == 0); inService = false; //allocIter = NULL; @@ -84,41 +88,77 @@ MSHR::deallocate() * Adds a target to an MSHR */ void -MSHR::allocateTarget(PacketPtr target, bool cpuSide) +MSHR::allocateTarget(PacketPtr target) { - //If we append an invalidate and we issued a read to the bus, - //but now have some pending writes, we need to move - //the invalidate to before the first non-read - if (inService && !inServiceForExclusive && needsExclusive - && !cpuSide && target->isInvalidate()) { - std::list<Target> temp; - - while (!targets.empty()) { - if (targets.front().pkt->needsExclusive()) break; - //Place on top of temp stack - temp.push_front(targets.front()); - //Remove from targets - targets.pop_front(); + if (inService) { + if (!deferredTargets.empty() || pendingInvalidate || + (!needsExclusive && target->needsExclusive())) { + // need to put on deferred list + deferredTargets.push_back(Target(target, true)); + if (target->needsExclusive()) { + deferredNeedsExclusive = true; + } + } else { + // still OK to append to outstanding request + targets.push_back(Target(target, true)); + } + } else { + if (target->needsExclusive()) { + needsExclusive = true; } - //Now that we have all the reads off until first non-read, we can - //place the invalidate on - targets.push_front(Target(target, cpuSide)); + targets.push_back(Target(target, true)); + } - //Now we pop off the temp_stack and put them back - while (!temp.empty()) { - targets.push_front(temp.front()); - temp.pop_front(); - } + ++ntargets; +} + +void +MSHR::allocateSnoopTarget(PacketPtr target) +{ + assert(inService); // don't bother to call otherwise + + if (pendingInvalidate) { + // a prior snoop has already appended an invalidation, so + // logically we don't have the block anymore... + return; } - else { - targets.push_back(Target(target, cpuSide)); + + if (needsExclusive) { + // 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()) { + // 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; } + targets.push_back(Target(target, false)); ++ntargets; +} + + +bool +MSHR::promoteDeferredTargets() +{ + if (deferredTargets.empty()) { + return false; + } + + assert(targets.empty()); + targets = deferredTargets; + deferredTargets.clear(); assert(targets.size() == ntargets); - needsExclusive = needsExclusive || target->needsExclusive(); + needsExclusive = deferredNeedsExclusive; + pendingInvalidate = false; + deferredNeedsExclusive = false; + + return true; } diff --git a/src/mem/cache/miss/mshr.hh b/src/mem/cache/miss/mshr.hh index 195438e46..f4e090a12 100644 --- a/src/mem/cache/miss/mshr.hh +++ b/src/mem/cache/miss/mshr.hh @@ -85,9 +85,6 @@ class MSHR : public Packet::SenderState /** Size of the request. */ int size; - /** Data associated with the request (if a write). */ - uint8_t *writeData; - /** True if the request has been sent to the bus. */ bool inService; @@ -95,12 +92,13 @@ class MSHR : public Packet::SenderState bool isCacheFill; /** True if we need to get an exclusive copy of the block. */ bool needsExclusive; + /** True if the request is uncacheable */ bool _isUncacheable; - /** True if the request that has been sent to the bus is for en - * exclusive copy. */ - bool inServiceForExclusive; + bool deferredNeedsExclusive; + bool pendingInvalidate; + /** Thread number of the miss. */ short threadNum; /** The number of currently allocated targets. */ @@ -124,6 +122,8 @@ private: /** List of all requests that match the address */ TargetList targets; + TargetList deferredTargets; + public: bool isUncacheable() { return _isUncacheable; } @@ -153,7 +153,8 @@ public: * Add a request to the list of targets. * @param target The target. */ - void allocateTarget(PacketPtr target, bool cpuSide); + void allocateTarget(PacketPtr target); + void allocateSnoopTarget(PacketPtr target); /** A simple constructor. */ MSHR(); @@ -201,6 +202,8 @@ public: return tgt->isCpuSide() && !tgt->pkt->needsResponse(); } + bool promoteDeferredTargets(); + /** * Prints the contents of this MSHR to stderr. */ |