summaryrefslogtreecommitdiff
path: root/src/mem/cache/miss
diff options
context:
space:
mode:
authorSteve Reinhardt <stever@eecs.umich.edu>2007-06-25 06:47:05 -0700
committerSteve Reinhardt <stever@eecs.umich.edu>2007-06-25 06:47:05 -0700
commit529f12a531c331e4bdcf595a3aaf65ee5ef6b72d (patch)
treec8489da2cd683b4e958fee2a33cacecacc2bd5f7 /src/mem/cache/miss
parent47bce8ef7875420b2e26ebd834ed0d4146b65d5b (diff)
downloadgem5-529f12a531c331e4bdcf595a3aaf65ee5ef6b72d.tar.xz
Get rid of requestCauses. Use timestamped queue to make
sure we don't re-request bus prematurely. Use callback to avoid calling sendRetry() recursively within recvTiming. --HG-- extra : convert_revision : a907a2781b4b00aa8eb1ea7147afc81d6b424140
Diffstat (limited to 'src/mem/cache/miss')
-rw-r--r--src/mem/cache/miss/mshr.cc24
-rw-r--r--src/mem/cache/miss/mshr.hh26
-rw-r--r--src/mem/cache/miss/mshr_queue.cc45
-rw-r--r--src/mem/cache/miss/mshr_queue.hh23
4 files changed, 77 insertions, 41 deletions
diff --git a/src/mem/cache/miss/mshr.cc b/src/mem/cache/miss/mshr.cc
index 24ff3b33c..8fa11ab2e 100644
--- a/src/mem/cache/miss/mshr.cc
+++ b/src/mem/cache/miss/mshr.cc
@@ -37,6 +37,7 @@
#include <assert.h>
#include <string>
#include <vector>
+#include <algorithm>
#include "mem/cache/miss/mshr.hh"
#include "sim/core.hh" // for curTick
@@ -54,10 +55,13 @@ MSHR::MSHR()
}
void
-MSHR::allocate(Addr _addr, int _size, PacketPtr target)
+MSHR::allocate(Addr _addr, int _size, PacketPtr target,
+ Tick when, Counter _order)
{
addr = _addr;
size = _size;
+ readyTick = when;
+ order = _order;
assert(target);
isCacheFill = false;
needsExclusive = target->needsExclusive();
@@ -66,8 +70,8 @@ MSHR::allocate(Addr _addr, int _size, PacketPtr target)
threadNum = 0;
ntargets = 1;
// 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));
+ // snoop (mem-side request), so set cpuSide to true here.
+ targets.push_back(Target(target, when, _order, true));
assert(deferredTargets.empty());
deferredNeedsExclusive = false;
pendingInvalidate = false;
@@ -88,33 +92,33 @@ MSHR::deallocate()
* Adds a target to an MSHR
*/
void
-MSHR::allocateTarget(PacketPtr target)
+MSHR::allocateTarget(PacketPtr target, Tick when, Counter _order)
{
if (inService) {
if (!deferredTargets.empty() || pendingInvalidate ||
(!needsExclusive && target->needsExclusive())) {
// need to put on deferred list
- deferredTargets.push_back(Target(target, true));
+ deferredTargets.push_back(Target(target, when, _order, true));
if (target->needsExclusive()) {
deferredNeedsExclusive = true;
}
} else {
// still OK to append to outstanding request
- targets.push_back(Target(target, true));
+ targets.push_back(Target(target, when, _order, true));
}
} else {
if (target->needsExclusive()) {
needsExclusive = true;
}
- targets.push_back(Target(target, true));
+ targets.push_back(Target(target, when, _order, true));
}
++ntargets;
}
void
-MSHR::allocateSnoopTarget(PacketPtr target)
+MSHR::allocateSnoopTarget(PacketPtr target, Tick when, Counter _order)
{
assert(inService); // don't bother to call otherwise
@@ -137,7 +141,7 @@ MSHR::allocateSnoopTarget(PacketPtr target)
return;
}
- targets.push_back(Target(target, false));
+ targets.push_back(Target(target, when, _order, false));
++ntargets;
}
@@ -157,6 +161,8 @@ MSHR::promoteDeferredTargets()
needsExclusive = deferredNeedsExclusive;
pendingInvalidate = false;
deferredNeedsExclusive = false;
+ order = targets.front().order;
+ readyTick = std::max(curTick, targets.front().time);
return true;
}
diff --git a/src/mem/cache/miss/mshr.hh b/src/mem/cache/miss/mshr.hh
index f4e090a12..92288cf52 100644
--- a/src/mem/cache/miss/mshr.hh
+++ b/src/mem/cache/miss/mshr.hh
@@ -55,13 +55,14 @@ class MSHR : public Packet::SenderState
class Target {
public:
Tick time; //!< Time when request was received (for stats)
+ Counter order; //!< Global order (for memory consistency mgmt)
PacketPtr pkt; //!< Pending request packet.
bool cpuSide; //!< Did request come from cpu side or mem side?
bool isCpuSide() { return cpuSide; }
- Target(PacketPtr _pkt, bool _cpuSide, Tick _time = curTick)
- : time(_time), pkt(_pkt), cpuSide(_cpuSide)
+ Target(PacketPtr _pkt, Tick _time, Counter _order, bool _cpuSide)
+ : time(_time), order(_order), pkt(_pkt), cpuSide(_cpuSide)
{}
};
@@ -79,6 +80,12 @@ class MSHR : public Packet::SenderState
/** Pointer to queue containing this MSHR. */
MSHRQueue *queue;
+ /** Cycle when ready to issue */
+ Tick readyTick;
+
+ /** Order number assigned by the miss queue. */
+ Counter order;
+
/** Address of the request. */
Addr addr;
@@ -103,8 +110,6 @@ class MSHR : public Packet::SenderState
short threadNum;
/** The number of currently allocated targets. */
short ntargets;
- /** Order number of assigned by the miss queue. */
- uint64_t order;
/**
* Pointer to this MSHR on the ready list.
@@ -136,13 +141,8 @@ public:
* @param size The number of bytes to request.
* @param pkt The original miss.
*/
- void allocate(Addr addr, int size, PacketPtr pkt);
-
- /**
- * Allocate this MSHR as a buffer for the given request.
- * @param target The memory request to buffer.
- */
- void allocateAsBuffer(PacketPtr target);
+ void allocate(Addr addr, int size, PacketPtr pkt,
+ Tick when, Counter _order);
/**
* Mark this MSHR as free.
@@ -153,8 +153,8 @@ public:
* Add a request to the list of targets.
* @param target The target.
*/
- void allocateTarget(PacketPtr target);
- void allocateSnoopTarget(PacketPtr target);
+ void allocateTarget(PacketPtr target, Tick when, Counter order);
+ void allocateSnoopTarget(PacketPtr target, Tick when, Counter order);
/** A simple constructor. */
MSHR();
diff --git a/src/mem/cache/miss/mshr_queue.cc b/src/mem/cache/miss/mshr_queue.cc
index 3407e2588..18184bd20 100644
--- a/src/mem/cache/miss/mshr_queue.cc
+++ b/src/mem/cache/miss/mshr_queue.cc
@@ -90,8 +90,8 @@ MSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const
MSHR *
MSHRQueue::findPending(Addr addr, int size) const
{
- MSHR::ConstIterator i = pendingList.begin();
- MSHR::ConstIterator end = pendingList.end();
+ MSHR::ConstIterator i = readyList.begin();
+ MSHR::ConstIterator end = readyList.end();
for (; i != end; ++i) {
MSHR *mshr = *i;
if (mshr->addr < addr) {
@@ -107,17 +107,37 @@ MSHRQueue::findPending(Addr addr, int size) const
return NULL;
}
+
+MSHR::Iterator
+MSHRQueue::addToReadyList(MSHR *mshr)
+{
+ if (readyList.empty() || readyList.back()->readyTick <= mshr->readyTick) {
+ return readyList.insert(readyList.end(), mshr);
+ }
+
+ MSHR::Iterator i = readyList.begin();
+ MSHR::Iterator end = readyList.end();
+ for (; i != end; ++i) {
+ if ((*i)->readyTick > mshr->readyTick) {
+ return readyList.insert(i, mshr);
+ }
+ }
+ assert(false);
+}
+
+
MSHR *
-MSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt)
+MSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt,
+ Tick when, Counter order)
{
assert(!freeList.empty());
MSHR *mshr = freeList.front();
assert(mshr->getNumTargets() == 0);
freeList.pop_front();
- mshr->allocate(addr, size, pkt);
+ mshr->allocate(addr, size, pkt, when, order);
mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
- mshr->readyIter = pendingList.insert(pendingList.end(), mshr);
+ mshr->readyIter = addToReadyList(mshr);
allocated += 1;
return mshr;
@@ -139,7 +159,7 @@ MSHRQueue::deallocateOne(MSHR *mshr)
if (mshr->inService) {
inServiceEntries--;
} else {
- pendingList.erase(mshr->readyIter);
+ readyList.erase(mshr->readyIter);
}
mshr->deallocate();
return retval;
@@ -150,14 +170,15 @@ MSHRQueue::moveToFront(MSHR *mshr)
{
if (!mshr->inService) {
assert(mshr == *(mshr->readyIter));
- pendingList.erase(mshr->readyIter);
- mshr->readyIter = pendingList.insert(pendingList.begin(), mshr);
+ readyList.erase(mshr->readyIter);
+ mshr->readyIter = readyList.insert(readyList.begin(), mshr);
}
}
void
MSHRQueue::markInService(MSHR *mshr)
{
+ assert(!mshr->inService);
if (mshr->isSimpleForward()) {
// we just forwarded the request packet & don't expect a
// response, so get rid of it
@@ -167,23 +188,23 @@ MSHRQueue::markInService(MSHR *mshr)
return;
}
mshr->inService = true;
- pendingList.erase(mshr->readyIter);
+ readyList.erase(mshr->readyIter);
//mshr->readyIter = NULL;
inServiceEntries += 1;
- //pendingList.pop_front();
+ //readyList.pop_front();
}
void
MSHRQueue::markPending(MSHR *mshr)
{
- //assert(mshr->readyIter == NULL);
+ assert(mshr->inService);
mshr->inService = false;
--inServiceEntries;
/**
* @ todo might want to add rerequests to front of pending list for
* performance.
*/
- mshr->readyIter = pendingList.insert(pendingList.end(), mshr);
+ mshr->readyIter = addToReadyList(mshr);
}
void
diff --git a/src/mem/cache/miss/mshr_queue.hh b/src/mem/cache/miss/mshr_queue.hh
index 806aa9c64..fd61dec8b 100644
--- a/src/mem/cache/miss/mshr_queue.hh
+++ b/src/mem/cache/miss/mshr_queue.hh
@@ -51,7 +51,7 @@ class MSHRQueue
/** Holds pointers to all allocated entries. */
MSHR::List allocatedList;
/** Holds pointers to entries that haven't been sent to the bus. */
- MSHR::List pendingList;
+ MSHR::List readyList;
/** Holds non allocated entries. */
MSHR::List freeList;
@@ -69,6 +69,9 @@ class MSHRQueue
*/
const int numReserve;
+ MSHR::Iterator addToReadyList(MSHR *mshr);
+
+
public:
/** The number of allocated entries. */
int allocated;
@@ -121,7 +124,8 @@ class MSHRQueue
*
* @pre There are free entries.
*/
- MSHR *allocate(Addr addr, int size, PacketPtr &pkt);
+ MSHR *allocate(Addr addr, int size, PacketPtr &pkt,
+ Tick when, Counter order);
/**
* Removes the given MSHR from the queue. This places the MSHR on the
@@ -147,7 +151,7 @@ class MSHRQueue
/**
* Mark the given MSHR as in service. This removes the MSHR from the
- * pendingList. Deallocates the MSHR if it does not expect a response.
+ * readyList. Deallocates the MSHR if it does not expect a response.
* @param mshr The MSHR to mark in service.
*/
void markInService(MSHR *mshr);
@@ -171,7 +175,7 @@ class MSHRQueue
*/
bool havePending() const
{
- return !pendingList.empty();
+ return !readyList.empty();
}
/**
@@ -184,15 +188,20 @@ class MSHRQueue
}
/**
- * Returns the MSHR at the head of the pendingList.
+ * Returns the MSHR at the head of the readyList.
* @return The next request to service.
*/
MSHR *getNextMSHR() const
{
- if (pendingList.empty()) {
+ if (readyList.empty() || readyList.front()->readyTick > curTick) {
return NULL;
}
- return pendingList.front();
+ return readyList.front();
+ }
+
+ Tick nextMSHRReadyTick() const
+ {
+ return readyList.empty() ? MaxTick : readyList.front()->readyTick;
}
};