diff options
-rw-r--r-- | src/mem/cache/mshr.cc | 13 | ||||
-rw-r--r-- | src/mem/packet.hh | 19 |
2 files changed, 30 insertions, 2 deletions
diff --git a/src/mem/cache/mshr.cc b/src/mem/cache/mshr.cc index 6fa22c9b4..86e2bebad 100644 --- a/src/mem/cache/mshr.cc +++ b/src/mem/cache/mshr.cc @@ -82,7 +82,10 @@ MSHR::TargetList::add(PacketPtr pkt, Tick readyTime, } if (markPending) { - MSHR *mshr = dynamic_cast<MSHR*>(pkt->senderState); + // Iterate over the SenderState stack and see if we find + // an MSHR entry. If we do, set the downstreamPending + // flag. Otherwise, do nothing. + MSHR *mshr = pkt->findNextSenderState<MSHR>(); if (mshr != NULL) { assert(!mshr->downstreamPending); mshr->downstreamPending = true; @@ -130,7 +133,13 @@ MSHR::TargetList::clearDownstreamPending() Iterator end_i = end(); for (Iterator i = begin(); i != end_i; ++i) { if (i->markedPending) { - MSHR *mshr = dynamic_cast<MSHR*>(i->pkt->senderState); + // Iterate over the SenderState stack and see if we find + // an MSHR entry. If we find one, clear the + // downstreamPending flag by calling + // clearDownstreamPending(). This recursively clears the + // downstreamPending flag in all caches this packet has + // passed through. + MSHR *mshr = i->pkt->findNextSenderState<MSHR>(); if (mshr != NULL) { mshr->clearDownstreamPending(); } diff --git a/src/mem/packet.hh b/src/mem/packet.hh index 6da1fe97d..6d9e88b8f 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -454,6 +454,25 @@ class Packet : public Printable */ SenderState *popSenderState(); + /** + * Go through the sender state stack and return the first instance + * that is of type T (as determined by a dynamic_cast). If there + * is no sender state of type T, NULL is returned. + * + * @return The topmost state of type T + */ + template <typename T> + T * findNextSenderState() const + { + T *t = NULL; + SenderState* sender_state = senderState; + while (t == NULL && sender_state != NULL) { + t = dynamic_cast<T*>(sender_state); + sender_state = sender_state->predecessor; + } + return t; + } + /// Return the string name of the cmd field (for debugging and /// tracing). const std::string &cmdString() const { return cmd.toString(); } |