summaryrefslogtreecommitdiff
path: root/src/mem/cache/miss
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/cache/miss')
-rw-r--r--src/mem/cache/miss/mshr.cc90
-rw-r--r--src/mem/cache/miss/mshr.hh17
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.
*/