2c2
< * Copyright (c) 2012-2013, 2015 ARM Limited
---
> * Copyright (c) 2012-2013, 2015-2016 ARM Limited
48d47
< #include "base/trace.hh"
50d48
< #include "debug/Drain.hh"
55,66c53,56
< int num_entries, int reserve, int demand_reserve,
< int _index)
< : label(_label), numEntries(num_entries + reserve - 1),
< numReserve(reserve), demandReserve(demand_reserve),
< registers(numEntries), allocated(0),
< inServiceEntries(0), index(_index)
< {
< for (int i = 0; i < numEntries; ++i) {
< registers[i].queue = this;
< freeList.push_back(&registers[i]);
< }
< }
---
> int num_entries, int reserve, int demand_reserve)
> : Queue<MSHR>(_label, num_entries, reserve),
> demandReserve(demand_reserve)
> {}
69,147d58
< MSHRQueue::findMatch(Addr blk_addr, bool is_secure) const
< {
< for (const auto& mshr : allocatedList) {
< // we ignore any MSHRs allocated for uncacheable accesses and
< // simply ignore them when matching, in the cache we never
< // check for matches when adding new uncacheable entries, and
< // we do not want normal cacheable accesses being added to an
< // MSHR serving an uncacheable access
< if (!mshr->isUncacheable() && mshr->blkAddr == blk_addr &&
< mshr->isSecure == is_secure) {
< return mshr;
< }
< }
< return NULL;
< }
<
< bool
< MSHRQueue::findMatches(Addr blk_addr, bool is_secure,
< vector<MSHR*>& matches) const
< {
< // Need an empty vector
< assert(matches.empty());
< bool retval = false;
< for (const auto& mshr : allocatedList) {
< if (!mshr->isUncacheable() && mshr->blkAddr == blk_addr &&
< mshr->isSecure == is_secure) {
< retval = true;
< matches.push_back(mshr);
< }
< }
< return retval;
< }
<
<
< bool
< MSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr)
< {
< pkt->pushLabel(label);
< for (const auto& mshr : allocatedList) {
< if (mshr->blkAddr == blk_addr && mshr->checkFunctional(pkt)) {
< pkt->popLabel();
< return true;
< }
< }
< pkt->popLabel();
< return false;
< }
<
<
< MSHR *
< MSHRQueue::findPending(Addr blk_addr, bool is_secure) const
< {
< for (const auto& mshr : readyList) {
< if (mshr->blkAddr == blk_addr && mshr->isSecure == is_secure) {
< return mshr;
< }
< }
< return NULL;
< }
<
<
< MSHR::Iterator
< MSHRQueue::addToReadyList(MSHR *mshr)
< {
< if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) {
< return readyList.insert(readyList.end(), mshr);
< }
<
< for (auto i = readyList.begin(); i != readyList.end(); ++i) {
< if ((*i)->readyTime > mshr->readyTime) {
< return readyList.insert(i, mshr);
< }
< }
< assert(false);
< return readyList.end(); // keep stupid compilers happy
< }
<
<
< MSHR *
164d74
<
166,192d75
< MSHRQueue::deallocate(MSHR *mshr)
< {
< deallocateOne(mshr);
< }
<
< MSHR::Iterator
< MSHRQueue::deallocateOne(MSHR *mshr)
< {
< MSHR::Iterator retval = allocatedList.erase(mshr->allocIter);
< freeList.push_front(mshr);
< allocated--;
< if (mshr->inService) {
< inServiceEntries--;
< } else {
< readyList.erase(mshr->readyIter);
< }
< mshr->deallocate();
< if (drainState() == DrainState::Draining && allocated == 0) {
< // Notify the drain manager that we have completed draining if
< // there are no other outstanding requests in this MSHR queue.
< DPRINTF(Drain, "MSHRQueue now empty, signalling drained\n");
< signalDrainDone();
< }
< return retval;
< }
<
< void
205,210c88,90
< if (mshr->markInService(pending_modified_resp)) {
< deallocate(mshr);
< } else {
< readyList.erase(mshr->readyIter);
< inServiceEntries += 1;
< }
---
> mshr->markInService(pending_modified_resp);
> readyList.erase(mshr->readyIter);
> _numInService += 1;
218c98
< --inServiceEntries;
---
> --_numInService;
235c115
< deallocateOne(mshr);
---
> deallocate(mshr);
241,246d120
<
< DrainState
< MSHRQueue::drain()
< {
< return allocated == 0 ? DrainState::Drained : DrainState::Draining;
< }