changeset bf82f1f7b040 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=bf82f1f7b040
description:
ruby: handle llsc accesses through CacheEntry, not CacheMemory
The sequencer takes care of llsc accesses by calling upon functions
from the CacheMemory. This is unnecessary once the required CacheEntry
object
is available. Thus some of the calls to findTagInSet() are avoided.
diffstat:
src/mem/ruby/slicc_interface/AbstractCacheEntry.cc | 25 ++++++++++++++++++
src/mem/ruby/slicc_interface/AbstractCacheEntry.hh | 5 +++
src/mem/ruby/structures/CacheMemory.cc | 6 ++--
src/mem/ruby/structures/CacheMemory.hh | 5 +++
src/mem/ruby/system/Sequencer.cc | 30 ++++++++++-----------
5 files changed, 52 insertions(+), 19 deletions(-)
diffs (165 lines):
diff -r bf2fc8f7e432 -r bf82f1f7b040
src/mem/ruby/slicc_interface/AbstractCacheEntry.cc
--- a/src/mem/ruby/slicc_interface/AbstractCacheEntry.cc Fri Aug 14
19:26:43 2015 -0500
+++ b/src/mem/ruby/slicc_interface/AbstractCacheEntry.cc Fri Aug 14
19:28:42 2015 -0500
@@ -28,6 +28,9 @@
#include "mem/ruby/slicc_interface/AbstractCacheEntry.hh"
+#include "base/trace.hh"
+#include "debug/RubyCache.hh"
+
AbstractCacheEntry::AbstractCacheEntry()
{
m_Permission = AccessPermission_NotPresent;
@@ -48,3 +51,25 @@
m_locked = -1;
}
}
+
+void
+AbstractCacheEntry::setLocked(int context)
+{
+ DPRINTF(RubyCache, "Setting Lock for addr: %x to %d\n", m_Address,
context);
+ m_locked = context;
+}
+
+void
+AbstractCacheEntry::clearLocked()
+{
+ DPRINTF(RubyCache, "Clear Lock for addr: %x\n", m_Address);
+ m_locked = -1;
+}
+
+bool
+AbstractCacheEntry::isLocked(int context) const
+{
+ DPRINTF(RubyCache, "Testing Lock for addr: %llx cur %d con %d\n",
+ m_Address, m_locked, context);
+ return m_locked == context;
+}
diff -r bf2fc8f7e432 -r bf82f1f7b040
src/mem/ruby/slicc_interface/AbstractCacheEntry.hh
--- a/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh Fri Aug 14
19:26:43 2015 -0500
+++ b/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh Fri Aug 14
19:28:42 2015 -0500
@@ -56,6 +56,11 @@
virtual DataBlock& getDataBlk()
{ panic("getDataBlk() not implemented!"); }
+ // Functions for locking and unlocking the cache entry. These are required
+ // for supporting atomic memory accesses.
+ void setLocked(int context);
+ void clearLocked();
+ bool isLocked(int context) const;
Addr m_Address; // Address of this block, required by CacheMemory
int m_locked; // Holds info whether the address is locked,
diff -r bf2fc8f7e432 -r bf82f1f7b040 src/mem/ruby/structures/CacheMemory.cc
--- a/src/mem/ruby/structures/CacheMemory.cc Fri Aug 14 19:26:43 2015 -0500
+++ b/src/mem/ruby/structures/CacheMemory.cc Fri Aug 14 19:28:42 2015 -0500
@@ -413,7 +413,7 @@
int64 cacheSet = addressToCacheSet(address);
int loc = findTagInSet(cacheSet, address);
assert(loc != -1);
- m_cache[cacheSet][loc]->m_locked = context;
+ m_cache[cacheSet][loc]->setLocked(context);
}
void
@@ -424,7 +424,7 @@
int64 cacheSet = addressToCacheSet(address);
int loc = findTagInSet(cacheSet, address);
assert(loc != -1);
- m_cache[cacheSet][loc]->m_locked = -1;
+ m_cache[cacheSet][loc]->clearLocked();
}
bool
@@ -436,7 +436,7 @@
assert(loc != -1);
DPRINTF(RubyCache, "Testing Lock for addr: %llx cur %d con %d\n",
address, m_cache[cacheSet][loc]->m_locked, context);
- return m_cache[cacheSet][loc]->m_locked == context;
+ return m_cache[cacheSet][loc]->isLocked(context);
}
void
diff -r bf2fc8f7e432 -r bf82f1f7b040 src/mem/ruby/structures/CacheMemory.hh
--- a/src/mem/ruby/structures/CacheMemory.hh Fri Aug 14 19:26:43 2015 -0500
+++ b/src/mem/ruby/structures/CacheMemory.hh Fri Aug 14 19:28:42 2015 -0500
@@ -107,6 +107,11 @@
// Set this address to most recently used
void setMRU(Addr address);
+ // Functions for locking and unlocking cache lines corresponding to the
+ // provided address. These are required for supporting atomic memory
+ // accesses. These are to be used when only the address of the cache entry
+ // is available. In case the entry itself is available. use the functions
+ // provided by the AbstractCacheEntry class.
void setLocked (Addr addr, int context);
void clearLocked (Addr addr);
bool isLocked (Addr addr, int context);
diff -r bf2fc8f7e432 -r bf82f1f7b040 src/mem/ruby/system/Sequencer.cc
--- a/src/mem/ruby/system/Sequencer.cc Fri Aug 14 19:26:43 2015 -0500
+++ b/src/mem/ruby/system/Sequencer.cc Fri Aug 14 19:28:42 2015 -0500
@@ -317,28 +317,27 @@
void
Sequencer::invalidateSC(Addr address)
{
- RequestTable::iterator i = m_writeRequestTable.find(address);
- if (i != m_writeRequestTable.end()) {
- SequencerRequest* request = i->second;
- // The controller has lost the coherence permissions, hence the lock
- // on the cache line maintained by the cache should be cleared.
- if (request->m_type == RubyRequestType_Store_Conditional) {
- m_dataCache_ptr->clearLocked(address);
- }
+ AbstractCacheEntry *e = m_dataCache_ptr->lookup(address);
+ // The controller has lost the coherence permissions, hence the lock
+ // on the cache line maintained by the cache should be cleared.
+ if (e && e->isLocked(m_version)) {
+ e->clearLocked();
}
}
bool
Sequencer::handleLlsc(Addr address, SequencerRequest* request)
{
- //
+ AbstractCacheEntry *e = m_dataCache_ptr->lookup(address);
+ if (!e)
+ return true;
+
// The success flag indicates whether the LLSC operation was successful.
// LL ops will always succeed, but SC may fail if the cache line is no
// longer locked.
- //
bool success = true;
if (request->m_type == RubyRequestType_Store_Conditional) {
- if (!m_dataCache_ptr->isLocked(address, m_version)) {
+ if (!e->isLocked(m_version)) {
//
// For failed SC requests, indicate the failure to the cpu by
// setting the extra data to zero.
@@ -355,19 +354,18 @@
//
// Independent of success, all SC operations must clear the lock
//
- m_dataCache_ptr->clearLocked(address);
+ e->clearLocked();
} else if (request->m_type == RubyRequestType_Load_Linked) {
//
// Note: To fully follow Alpha LLSC semantics, should the LL clear any
// previously locked cache lines?
//
- m_dataCache_ptr->setLocked(address, m_version);
- } else if ((m_dataCache_ptr->isTagPresent(address)) &&
- (m_dataCache_ptr->isLocked(address, m_version))) {
+ e->setLocked(m_version);
+ } else if (e->isLocked(m_version)) {
//
// Normal writes should clear the locked address
//
- m_dataCache_ptr->clearLocked(address);
+ e->clearLocked();
}
return success;
}
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev