diff options
Diffstat (limited to 'src/mem/cache/miss')
-rw-r--r-- | src/mem/cache/miss/mshr.cc | 24 | ||||
-rw-r--r-- | src/mem/cache/miss/mshr.hh | 26 | ||||
-rw-r--r-- | src/mem/cache/miss/mshr_queue.cc | 45 | ||||
-rw-r--r-- | src/mem/cache/miss/mshr_queue.hh | 23 |
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; } }; |