diff options
author | Ron Dreslinski <rdreslin@umich.edu> | 2006-11-10 22:45:50 -0500 |
---|---|---|
committer | Ron Dreslinski <rdreslin@umich.edu> | 2006-11-10 22:45:50 -0500 |
commit | f876bc2bf0e04b888c2748c0cabf8d11b31f41b7 (patch) | |
tree | 8dcd8a817d203442fdcbc332d7fed0d5ab8f8701 /src/mem/cache/base_cache.hh | |
parent | 9a6e896d3bc904745f090aad1a6d40f04f5ac2ef (diff) | |
download | gem5-f876bc2bf0e04b888c2748c0cabf8d11b31f41b7.tar.xz |
More fixes for functional accesses. It now makes the writeback memory leak to crash all configs.
Working on that now.
src/mem/cache/base_cache.cc:
Keep a list of the responders so we can search them on functional accesses.
src/mem/cache/base_cache.hh:
Properly put things on a list for responses so we can search the list.
Also, be sure to check the outgoing ports lists on a functional access (factor some common code out there)
src/mem/cache/cache_impl.hh:
Properly return when the first read hit on a functional access.
Make sure to call to check the other ports list of packets before forwarding it out.
--HG--
extra : convert_revision : 1d21cb55ff29c15716617efc48441329707c088a
Diffstat (limited to 'src/mem/cache/base_cache.hh')
-rw-r--r-- | src/mem/cache/base_cache.hh | 121 |
1 files changed, 112 insertions, 9 deletions
diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh index ea7544fbb..9a79bd36c 100644 --- a/src/mem/cache/base_cache.hh +++ b/src/mem/cache/base_cache.hh @@ -105,7 +105,11 @@ class BaseCache : public MemObject void clearBlocked(); - bool canDrain() { return drainList.empty(); } + bool checkFunctional(PacketPtr pkt); + + void checkAndSendFunctional(PacketPtr pkt); + + bool canDrain() { return drainList.empty() && transmitList.empty(); } bool blocked; @@ -117,15 +121,16 @@ class BaseCache : public MemObject std::list<PacketPtr> drainList; + std::list<std::pair<Tick,PacketPtr> > transmitList; }; struct CacheEvent : public Event { CachePort *cachePort; PacketPtr pkt; + bool newResponse; - CacheEvent(CachePort *_cachePort); - CacheEvent(CachePort *_cachePort, PacketPtr _pkt); + CacheEvent(CachePort *_cachePort, bool response); void process(); const char *description(); }; @@ -133,6 +138,9 @@ class BaseCache : public MemObject public: //Made public so coherence can get at it. CachePort *cpuSidePort; + CacheEvent *sendEvent; + CacheEvent *memSendEvent; + protected: CachePort *memSidePort; @@ -353,6 +361,12 @@ class BaseCache : public MemObject snoopRangesSent = false; } + ~BaseCache() + { + delete sendEvent; + delete memSendEvent; + } + virtual void init(); /** @@ -467,7 +481,8 @@ class BaseCache : public MemObject { if (!doMasterRequest() && !memSidePort->waitingOnRetry) { - BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(memSidePort); + BaseCache::CacheEvent * reqCpu = + new BaseCache::CacheEvent(memSidePort, false); reqCpu->schedule(time); } uint8_t flag = 1<<cause; @@ -503,7 +518,8 @@ class BaseCache : public MemObject { if (!doSlaveRequest() && !cpuSidePort->waitingOnRetry) { - BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(cpuSidePort); + BaseCache::CacheEvent * reqCpu = + new BaseCache::CacheEvent(cpuSidePort, false); reqCpu->schedule(time); } uint8_t flag = 1<<cause; @@ -528,9 +544,38 @@ class BaseCache : public MemObject */ void respond(PacketPtr pkt, Tick time) { + assert(time >= curTick); if (pkt->needsResponse()) { - CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt); +/* CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt); reqCpu->schedule(time); +*/ + if (cpuSidePort->transmitList.empty()) { + assert(!sendEvent->scheduled()); + sendEvent->schedule(time); + cpuSidePort->transmitList.push_back(std::pair<Tick,PacketPtr> + (time,pkt)); + return; + } + + // something is on the list and this belongs at the end + if (time >= cpuSidePort->transmitList.back().first) { + cpuSidePort->transmitList.push_back(std::pair<Tick,PacketPtr> + (time,pkt)); + return; + } + // Something is on the list and this belongs somewhere else + std::list<std::pair<Tick,PacketPtr> >::iterator i = + cpuSidePort->transmitList.begin(); + std::list<std::pair<Tick,PacketPtr> >::iterator end = + cpuSidePort->transmitList.end(); + bool done = false; + + while (i != end && !done) { + if (time < i->first) + cpuSidePort->transmitList.insert(i,std::pair<Tick,PacketPtr> + (time,pkt)); + i++; + } } else { if (pkt->cmd != Packet::UpgradeReq) @@ -548,12 +593,42 @@ class BaseCache : public MemObject */ void respondToMiss(PacketPtr pkt, Tick time) { + assert(time >= curTick); if (!pkt->req->isUncacheable()) { - missLatency[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/] += time - pkt->time; + missLatency[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/] += + time - pkt->time; } if (pkt->needsResponse()) { - CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt); +/* CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt); reqCpu->schedule(time); +*/ + if (cpuSidePort->transmitList.empty()) { + assert(!sendEvent->scheduled()); + sendEvent->schedule(time); + cpuSidePort->transmitList.push_back(std::pair<Tick,PacketPtr> + (time,pkt)); + return; + } + + // something is on the list and this belongs at the end + if (time >= cpuSidePort->transmitList.back().first) { + cpuSidePort->transmitList.push_back(std::pair<Tick,PacketPtr> + (time,pkt)); + return; + } + // Something is on the list and this belongs somewhere else + std::list<std::pair<Tick,PacketPtr> >::iterator i = + cpuSidePort->transmitList.begin(); + std::list<std::pair<Tick,PacketPtr> >::iterator end = + cpuSidePort->transmitList.end(); + bool done = false; + + while (i != end && !done) { + if (time < i->first) + cpuSidePort->transmitList.insert(i,std::pair<Tick,PacketPtr> + (time,pkt)); + i++; + } } else { if (pkt->cmd != Packet::UpgradeReq) @@ -570,9 +645,37 @@ class BaseCache : public MemObject */ void respondToSnoop(PacketPtr pkt, Tick time) { + assert(time >= curTick); assert (pkt->needsResponse()); - CacheEvent *reqMem = new CacheEvent(memSidePort, pkt); +/* CacheEvent *reqMem = new CacheEvent(memSidePort, pkt); reqMem->schedule(time); +*/ + if (memSidePort->transmitList.empty()) { + assert(!memSendEvent->scheduled()); + memSendEvent->schedule(time); + memSidePort->transmitList.push_back(std::pair<Tick,PacketPtr> + (time,pkt)); + return; + } + + // something is on the list and this belongs at the end + if (time >= memSidePort->transmitList.back().first) { + memSidePort->transmitList.push_back(std::pair<Tick,PacketPtr> + (time,pkt)); + return; + } + // Something is on the list and this belongs somewhere else + std::list<std::pair<Tick,PacketPtr> >::iterator i = + memSidePort->transmitList.begin(); + std::list<std::pair<Tick,PacketPtr> >::iterator end = + memSidePort->transmitList.end(); + bool done = false; + + while (i != end && !done) { + if (time < i->first) + memSidePort->transmitList.insert(i,std::pair<Tick,PacketPtr>(time,pkt)); + i++; + } } /** |