X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmem%2Fcache%2Fcache_blk.hh;h=7b999e4b1f655388174f73849fb4975175520a34;hb=7245d4530d0c8367fa7b1adadcb55e1e8bd466e7;hp=cf1bd20e2eb12626985d3f9464122065c07bbdef;hpb=ed8564a6b9f0702a40995d95cc4da54de3d35462;p=gem5.git diff --git a/src/mem/cache/cache_blk.hh b/src/mem/cache/cache_blk.hh index cf1bd20e2..7b999e4b1 100644 --- a/src/mem/cache/cache_blk.hh +++ b/src/mem/cache/cache_blk.hh @@ -35,9 +35,11 @@ #ifndef __CACHE_BLK_HH__ #define __CACHE_BLK_HH__ +#include + #include "sim/root.hh" // for Tick #include "arch/isa_traits.hh" // for Addr -#include "cpu/exec_context.hh" +#include "mem/request.hh" /** * Cache block status bit assignments @@ -88,9 +90,6 @@ class CacheBlk /** Which curTick will this block be accessable */ Tick whenReady; - /** Save the exec context so that writebacks can use them. */ - ExecContext *xc; - /** * The set this block belongs to. * @todo Move this into subclasses when we fix CacheTags to use them. @@ -100,8 +99,37 @@ 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 lockList; + + public: + CacheBlk() - : asid(-1), tag(0), data(0) ,size(0), status(0), whenReady(0), xc(0), + : asid(-1), tag(0), data(0) ,size(0), status(0), whenReady(0), set(-1), refCount(0) {} @@ -118,7 +146,6 @@ class CacheBlk size = rhs.size; status = rhs.status; whenReady = rhs.whenReady; - xc = rhs.xc; set = rhs.set; refCount = rhs.refCount; return *this; @@ -180,24 +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(); } -/** - * Output a CacheBlk to the given ostream. - * @param out The stream for the output. - * @param blk The cache block to print. - * - * @return The output stream. - */ -inline std::ostream & -operator<<(std::ostream &out, const CacheBlk &blk) -{ - out << std::hex << std::endl; - out << " Tag: " << blk.tag << std::endl; - out << " Status: " << blk.status << std::endl; + /** + * 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; - return(out << std::dec); -} + for (std::list::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__