/*
- * 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
* 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"
#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)
{
}
}
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);
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;
}
}
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());
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
// 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
ReqPacketQueue::ReqPacketQueue(EventManager& _em, MasterPort& _masterPort,
const std::string _label)
- : PacketQueue(_em, _label), masterPort(_masterPort)
+ : PacketQueue(_em, _label, name(_masterPort, _label)),
+ masterPort(_masterPort)
{
}
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)
{
}
}
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)
{
}