summaryrefslogtreecommitdiff
path: root/src/mem/ruby/system
diff options
context:
space:
mode:
authorDerek Hower <drh5@cs.wisc.edu>2010-01-19 17:11:36 -0600
committerDerek Hower <drh5@cs.wisc.edu>2010-01-19 17:11:36 -0600
commit07ea0891f1699f6194a05516948ce3824fb8fb38 (patch)
treeb5c22e3fe49a7e0d277fdb9ac5ee87c2aa0321e5 /src/mem/ruby/system
parent279f179babc9e5663156777c533c06edc91bce9a (diff)
downloadgem5-07ea0891f1699f6194a05516948ce3824fb8fb38.tar.xz
ruby: new atomics implementation
This patch changes the way that Ruby handles atomic RMW instructions. This implementation, unlike the prior one, is protocol independent. It works by locking an address from the sequencer immediately after the read portion of an RMW completes. When that address is locked, the coherence controller will only satisfy requests coming from one port (e.g., the mandatory queue) and will ignore all others. After the write portion completed, the line is unlocked. This should also work with multi-line atomics, as long as the blocks are always acquired in the same order.
Diffstat (limited to 'src/mem/ruby/system')
-rw-r--r--src/mem/ruby/system/Sequencer.cc47
-rw-r--r--src/mem/ruby/system/Sequencer.hh2
2 files changed, 3 insertions, 46 deletions
diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc
index a8b4b075a..b4716c346 100644
--- a/src/mem/ruby/system/Sequencer.cc
+++ b/src/mem/ruby/system/Sequencer.cc
@@ -66,8 +66,6 @@ void Sequencer::init(const vector<string> & argv)
m_instCache_ptr = NULL;
m_dataCache_ptr = NULL;
m_controller = NULL;
- m_atomic_reads = 0;
- m_atomic_writes = 0;
for (size_t i=0; i<argv.size(); i+=2) {
if ( argv[i] == "controller") {
m_controller = RubySystem::getController(argv[i+1]); // args[i] = "L1Cache"
@@ -285,15 +283,15 @@ void Sequencer::writeCallback(const Address& address, DataBlock& data) {
(request->ruby_request.type == RubyRequestType_RMW_Write) ||
(request->ruby_request.type == RubyRequestType_Locked_Read) ||
(request->ruby_request.type == RubyRequestType_Locked_Write));
- // POLINA: the assumption is that atomics are only on data cache and not instruction cache
+
if (request->ruby_request.type == RubyRequestType_Locked_Read) {
m_dataCache_ptr->setLocked(address, m_version);
}
else if (request->ruby_request.type == RubyRequestType_RMW_Read) {
- m_controller->set_atomic(address);
+ m_controller->blockOnQueue(address, m_mandatory_q_ptr);
}
else if (request->ruby_request.type == RubyRequestType_RMW_Write) {
- m_controller->clear_atomic(address);
+ m_controller->unblock(address);
}
hitCallback(request, data);
@@ -438,42 +436,12 @@ void Sequencer::issueRequest(const RubyRequest& request) {
CacheRequestType ctype;
switch(request.type) {
case RubyRequestType_IFETCH:
- if (m_atomic_reads > 0 && m_atomic_writes == 0) {
- m_controller->reset_atomics();
- m_atomic_writes = 0;
- m_atomic_reads = 0;
- }
- else if (m_atomic_writes > 0) {
- assert(m_atomic_reads > m_atomic_writes);
- cerr << "WARNING: Expected: " << m_atomic_reads << " RMW_Writes, but only received: " << m_atomic_writes << endl;
- assert(false);
- }
ctype = CacheRequestType_IFETCH;
break;
case RubyRequestType_LD:
- if (m_atomic_reads > 0 && m_atomic_writes == 0) {
- m_controller->reset_atomics();
- m_atomic_writes = 0;
- m_atomic_reads = 0;
- }
- else if (m_atomic_writes > 0) {
- assert(m_atomic_reads > m_atomic_writes);
- cerr << "WARNING: Expected: " << m_atomic_reads << " RMW_Writes, but only received: " << m_atomic_writes << endl;
- assert(false);
- }
ctype = CacheRequestType_LD;
break;
case RubyRequestType_ST:
- if (m_atomic_reads > 0 && m_atomic_writes == 0) {
- m_controller->reset_atomics();
- m_atomic_writes = 0;
- m_atomic_reads = 0;
- }
- else if (m_atomic_writes > 0) {
- assert(m_atomic_reads > m_atomic_writes);
- cerr << "WARNING: Expected: " << m_atomic_reads << " RMW_Writes, but only received: " << m_atomic_writes << endl;
- assert(false);
- }
ctype = CacheRequestType_ST;
break;
case RubyRequestType_Locked_Read:
@@ -481,18 +449,9 @@ void Sequencer::issueRequest(const RubyRequest& request) {
ctype = CacheRequestType_ATOMIC;
break;
case RubyRequestType_RMW_Read:
- assert(m_atomic_writes == 0);
- m_atomic_reads++;
ctype = CacheRequestType_ATOMIC;
break;
case RubyRequestType_RMW_Write:
- assert(m_atomic_reads > 0);
- assert(m_atomic_writes < m_atomic_reads);
- m_atomic_writes++;
- if (m_atomic_reads == m_atomic_writes) {
- m_atomic_reads = 0;
- m_atomic_writes = 0;
- }
ctype = CacheRequestType_ATOMIC;
break;
default:
diff --git a/src/mem/ruby/system/Sequencer.hh b/src/mem/ruby/system/Sequencer.hh
index ce53dd8d7..1621bbbdc 100644
--- a/src/mem/ruby/system/Sequencer.hh
+++ b/src/mem/ruby/system/Sequencer.hh
@@ -128,8 +128,6 @@ private:
// Global outstanding request count, across all request tables
int m_outstanding_count;
bool m_deadlock_check_scheduled;
- int m_atomic_reads;
- int m_atomic_writes;
int m_store_waiting_on_load_cycles;
int m_store_waiting_on_store_cycles;