diff options
author | Ron Dreslinski <rdreslin@umich.edu> | 2006-10-19 19:00:43 -0400 |
---|---|---|
committer | Ron Dreslinski <rdreslin@umich.edu> | 2006-10-19 19:00:43 -0400 |
commit | 9cf063eb8e0b9d4af40f0e8fe609f9135be899f5 (patch) | |
tree | 6c001f86099f6e84dc70849c52101b3b1c6b3bd1 /src/mem | |
parent | 39d24f7241e0645bd4cf1e71d37be9b4e913cb9b (diff) | |
parent | bf917535f835b296d6fd88d3c63f3b692ffb1509 (diff) | |
download | gem5-9cf063eb8e0b9d4af40f0e8fe609f9135be899f5.tar.xz |
Merge zizzer:/bk/newmem
into zazzer.eecs.umich.edu:/z/rdreslin/m5bk/newmemcleanest
--HG--
extra : convert_revision : c6611b32537918f5bf183788227ddf69a9a9a069
Diffstat (limited to 'src/mem')
-rw-r--r-- | src/mem/cache/cache_blk.hh | 83 | ||||
-rw-r--r-- | src/mem/cache/cache_impl.hh | 10 | ||||
-rw-r--r-- | src/mem/cache/tags/lru.cc | 1 | ||||
-rw-r--r-- | src/mem/page_table.cc | 5 |
4 files changed, 87 insertions, 12 deletions
diff --git a/src/mem/cache/cache_blk.hh b/src/mem/cache/cache_blk.hh index 078c82d82..7b999e4b1 100644 --- a/src/mem/cache/cache_blk.hh +++ b/src/mem/cache/cache_blk.hh @@ -35,8 +35,11 @@ #ifndef __CACHE_BLK_HH__ #define __CACHE_BLK_HH__ +#include <list> + #include "sim/root.hh" // for Tick #include "arch/isa_traits.hh" // for Addr +#include "mem/request.hh" /** * Cache block status bit assignments @@ -96,6 +99,35 @@ class CacheBlk /** Number of references to this block since it was brought in. */ int refCount; + protected: + /** + * Represents that the indicated thread context has a "lock" on + * the block, in the LL/SC sense. + */ + class Lock { + public: + int cpuNum; // locking CPU + int threadNum; // locking thread ID within CPU + + // check for matching execution context + bool matchesContext(Request *req) + { + return (cpuNum == req->getCpuNum() && + threadNum == req->getThreadNum()); + } + + Lock(Request *req) + : cpuNum(req->getCpuNum()), threadNum(req->getThreadNum()) + { + } + }; + + /** List of thread contexts that have performed a load-locked (LL) + * on the block since the last store. */ + std::list<Lock> lockList; + + public: + CacheBlk() : asid(-1), tag(0), data(0) ,size(0), status(0), whenReady(0), set(-1), refCount(0) @@ -175,7 +207,58 @@ class CacheBlk return (status & BlkHWPrefetched) != 0; } + /** + * Track the fact that a local locked was issued to the block. If + * multiple LLs get issued from the same context we could have + * redundant records on the list, but that's OK, as they'll all + * get blown away at the next store. + */ + void trackLoadLocked(Request *req) + { + assert(req->isLocked()); + lockList.push_front(Lock(req)); + } + + /** + * Clear the list of valid load locks. Should be called whenever + * block is written to or invalidated. + */ + void clearLoadLocks() { lockList.clear(); } + /** + * Handle interaction of load-locked operations and stores. + * @return True if write should proceed, false otherwise. Returns + * false only in the case of a failed store conditional. + */ + bool checkWrite(Request *req) + { + if (req->isLocked()) { + // it's a store conditional... have to check for matching + // load locked. + bool success = false; + + for (std::list<Lock>::iterator i = lockList.begin(); + i != lockList.end(); ++i) + { + if (i->matchesContext(req)) { + // it's a store conditional, and as far as the memory + // system can tell, the requesting context's lock is + // still valid. + success = true; + break; + } + } + + req->setScResult(success ? 1 : 0); + clearLoadLocks(); + return success; + } else { + // for *all* stores (conditional or otherwise) we have to + // clear the list of load-locks as they're all invalid now. + clearLoadLocks(); + return true; + } + } }; #endif //__CACHE_BLK_HH__ diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 8683352db..b5d7e1960 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -86,11 +86,6 @@ doAtomicAccess(Packet *pkt, bool isCpuSide) { if (isCpuSide) { - //Temporary solution to LL/SC - if (pkt->isWrite() && (pkt->req->isLocked())) { - pkt->req->setScResult(1); - } - probe(pkt, true, NULL); //TEMP ALWAYS SUCCES FOR NOW pkt->result = Packet::Success; @@ -116,11 +111,6 @@ doFunctionalAccess(Packet *pkt, bool isCpuSide) //TEMP USE CPU?THREAD 0 0 pkt->req->setThreadContext(0,0); - //Temporary solution to LL/SC - if (pkt->isWrite() && (pkt->req->isLocked())) { - assert("Can't handle LL/SC on functional path\n"); - } - probe(pkt, false, memSidePort); //TEMP ALWAYS SUCCESFUL FOR NOW pkt->result = Packet::Success; diff --git a/src/mem/cache/tags/lru.cc b/src/mem/cache/tags/lru.cc index a9ae049c3..3eb083327 100644 --- a/src/mem/cache/tags/lru.cc +++ b/src/mem/cache/tags/lru.cc @@ -246,6 +246,7 @@ LRU::invalidateBlk(Addr addr) if (blk) { blk->status = 0; blk->isTouched = false; + blk->clearLoadLocks(); tagsInUse--; } } diff --git a/src/mem/page_table.cc b/src/mem/page_table.cc index 32da4282c..fa6d5ddfb 100644 --- a/src/mem/page_table.cc +++ b/src/mem/page_table.cc @@ -167,13 +167,14 @@ void PageTable::serialize(std::ostream &os) { paramOut(os, "ptable.size", pTable.size()); + int count = 0; m5::hash_map<Addr,Addr>::iterator iter; - while (iter != pTable.end()) { + m5::hash_map<Addr,Addr>::iterator end; + for (iter = pTable.begin(); iter != end; ++iter,++count) { paramOut(os, csprintf("ptable.entry%dvaddr", count),iter->first); paramOut(os, csprintf("ptable.entry%dpaddr", count),iter->second); - ++count; } assert(count == pTable.size()); } |