X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmem%2Fpacket_queue.cc;h=acf29dd8f0fd4a041efb187b0f93694a36567d30;hb=01a8783d5840b18c90c3ed245cd32f0ea4a56149;hp=f7df3314fe6498526b85f74015ad81dd46bdf59c;hpb=7a8dda49a4ec33be17bbd101ebd68e02562b9c3d;p=gem5.git diff --git a/src/mem/packet_queue.cc b/src/mem/packet_queue.cc index f7df3314f..acf29dd8f 100644 --- a/src/mem/packet_queue.cc +++ b/src/mem/packet_queue.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012,2015 ARM Limited + * Copyright (c) 2012,2015,2018 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -36,9 +36,6 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Ali Saidi - * Andreas Hansson */ #include "mem/packet_queue.hh" @@ -47,11 +44,13 @@ #include "debug/Drain.hh" #include "debug/PacketQueue.hh" -using namespace std; - PacketQueue::PacketQueue(EventManager& _em, const std::string& _label, + const std::string& _sendEventName, + bool force_order, bool disable_sanity_check) - : em(_em), sendEvent(this), _disableSanityCheck(disable_sanity_check), + : em(_em), sendEvent([this]{ processSendEvent(); }, _sendEventName), + _disableSanityCheck(disable_sanity_check), + forceOrder(force_order), label(_label), waitingOnRetry(false) { } @@ -70,19 +69,19 @@ PacketQueue::retry() } bool -PacketQueue::hasAddr(Addr addr) const +PacketQueue::checkConflict(const PacketPtr pkt, const int blk_size) const { // caller is responsible for ensuring that all packets have the // same alignment for (const auto& p : transmitList) { - if (p.pkt->getAddr() == addr) + if (p.pkt->matchBlockAddr(pkt, blk_size)) return true; } return false; } bool -PacketQueue::checkFunctional(PacketPtr pkt) +PacketQueue::trySatisfyFunctional(PacketPtr pkt) { pkt->pushLabel(label); @@ -92,7 +91,7 @@ PacketQueue::checkFunctional(PacketPtr pkt) while (!found && i != transmitList.end()) { // If the buffered packet contains data, and it overlaps the // current packet, then update data - found = pkt->checkFunctional(i->pkt); + found = pkt->trySatisfyFunctional(i->pkt); ++i; } @@ -102,11 +101,11 @@ PacketQueue::checkFunctional(PacketPtr pkt) } void -PacketQueue::schedSendTiming(PacketPtr pkt, Tick when, bool force_order) +PacketQueue::schedSendTiming(PacketPtr pkt, Tick when) { DPRINTF(PacketQueue, "%s for %s address %x size %d when %lu ord: %i\n", __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize(), when, - force_order); + forceOrder); // we can still send a packet before the end of this tick assert(when >= curTick()); @@ -121,13 +120,6 @@ PacketQueue::schedSendTiming(PacketPtr pkt, Tick when, bool force_order) name()); } - // nothing on the list - if (transmitList.empty()) { - transmitList.emplace_front(when, pkt); - schedSendEvent(when); - return; - } - // we should either have an outstanding retry, or a send event // scheduled, but there is an unfortunate corner case where the // x86 page-table walker and timing CPU send out a new request as @@ -137,18 +129,23 @@ PacketQueue::schedSendTiming(PacketPtr pkt, Tick when, bool force_order) // assert(waitingOnRetry || sendEvent.scheduled()); // this belongs in the middle somewhere, so search from the end to - // order by tick; however, if force_order is set, also make sure + // order by tick; however, if forceOrder is set, also make sure // not to re-order in front of some existing packet with the same // address - auto i = transmitList.end(); - --i; - while (i != transmitList.begin() && when < i->tick && - !(force_order && i->pkt->getAddr() == pkt->getAddr())) - --i; - - // emplace inserts the element before the position pointed to by - // the iterator, so advance it one step - transmitList.emplace(++i, when, pkt); + auto it = transmitList.end(); + while (it != transmitList.begin()) { + --it; + if ((forceOrder && it->pkt->matchAddr(pkt)) || it->tick <= when) { + // emplace inserts the element before the position pointed to by + // the iterator, so advance it one step + transmitList.emplace(++it, when, pkt); + return; + } + } + // either the packet list is empty or this has to be inserted + // before every other packet + transmitList.emplace_front(when, pkt); + schedSendEvent(when); } void @@ -237,7 +234,8 @@ PacketQueue::drain() ReqPacketQueue::ReqPacketQueue(EventManager& _em, MasterPort& _masterPort, const std::string _label) - : PacketQueue(_em, _label), masterPort(_masterPort) + : PacketQueue(_em, _label, name(_masterPort, _label)), + masterPort(_masterPort) { } @@ -249,8 +247,10 @@ ReqPacketQueue::sendTiming(PacketPtr pkt) SnoopRespPacketQueue::SnoopRespPacketQueue(EventManager& _em, MasterPort& _masterPort, + bool force_order, const std::string _label) - : PacketQueue(_em, _label), masterPort(_masterPort) + : PacketQueue(_em, _label, name(_masterPort, _label), force_order), + masterPort(_masterPort) { } @@ -261,8 +261,10 @@ SnoopRespPacketQueue::sendTiming(PacketPtr pkt) } RespPacketQueue::RespPacketQueue(EventManager& _em, SlavePort& _slavePort, + bool force_order, const std::string _label) - : PacketQueue(_em, _label), slavePort(_slavePort) + : PacketQueue(_em, _label, name(_slavePort, _label), force_order), + slavePort(_slavePort) { }