m_instCache_ptr = NULL;
m_dataCache_ptr = NULL;
m_controller = NULL;
+ m_servicing_atomic = 200;
+ m_atomics_counter = 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"
WARN_MSG("Possible Deadlock detected");
WARN_EXPR(request);
WARN_EXPR(m_version);
+ WARN_EXPR(request->ruby_request.paddr);
WARN_EXPR(keys.size());
WARN_EXPR(current_time);
WARN_EXPR(request->issue_time);
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);
+ }
+ else if (request->ruby_request.type == RubyRequestType_RMW_Write) {
+ m_controller->clear_atomic();
+ }
hitCallback(request, data);
}
removeRequest(request);
assert((request->ruby_request.type == RubyRequestType_LD) ||
+ (request->ruby_request.type == RubyRequestType_RMW_Read) ||
(request->ruby_request.type == RubyRequestType_IFETCH));
hitCallback(request, data);
// update the data
if (ruby_request.data != NULL) {
if ((type == RubyRequestType_LD) ||
- (type == RubyRequestType_IFETCH)) {
+ (type == RubyRequestType_IFETCH) ||
+ (type == RubyRequestType_RMW_Read)) {
memcpy(ruby_request.data, data.getData(request_address.getOffset(), ruby_request.len), ruby_request.len);
} else {
data.setData(ruby_request.data, request_address.getOffset(), ruby_request.len);
}
}
-
+ if (type == RubyRequestType_RMW_Write) {
+ if (m_servicing_atomic != ruby_request.proc_id) {
+ assert(0);
+ }
+ assert(m_atomics_counter > 0);
+ m_atomics_counter--;
+ if (m_atomics_counter == 0) {
+ m_servicing_atomic = 200;
+ }
+ }
m_hit_callback(srequest->id);
delete srequest;
}
// Returns true if the sequencer already has a load or store outstanding
-bool Sequencer::isReady(const RubyRequest& request) const {
+bool Sequencer::isReady(const RubyRequest& request, bool dont_set) {
// POLINA: check if we are currently flushing the write buffer, if so Ruby is returned as not ready
// to simulate stalling of the front-end
// Do we stall all the sequencers? If it is atomic instruction - yes!
return false;
}
+ assert(request.proc_id != 100);
+ if (m_servicing_atomic != 200 && m_servicing_atomic != request.proc_id) {
+ assert(m_atomics_counter > 0);
+ return false;
+ }
+ else {
+ if (!dont_set) {
+ if (request.type == RubyRequestType_RMW_Read) {
+ if (m_servicing_atomic == 200) {
+ assert(m_atomics_counter == 0);
+ m_servicing_atomic = request.proc_id;
+ }
+ else {
+ assert(m_servicing_atomic == request.proc_id);
+ }
+ m_atomics_counter++;
+ }
+ else {
+ if (m_servicing_atomic == request.proc_id) {
+ if (request.type != RubyRequestType_RMW_Write) {
+ m_servicing_atomic = 200;
+ m_atomics_counter = 0;
+ }
+ }
+ }
+ }
+ }
+
return true;
}
int64_t id = makeUniqueRequestID();
SequencerRequest *srequest = new SequencerRequest(request, id, g_eventQueue_ptr->getTime());
bool found = insertRequest(srequest);
- if (!found)
+ if (!found) {
if (request.type == RubyRequestType_Locked_Write) {
// NOTE: it is OK to check the locked flag here as the mandatory queue will be checked first
// ensuring that nothing comes between checking the flag and servicing the store
m_dataCache_ptr->clearLocked(line_address(Address(request.paddr)));
}
}
+ if (request.type == RubyRequestType_RMW_Write) {
+ m_controller->started_writes();
+ }
issueRequest(request);
// TODO: issue hardware prefetches here
return id;
+ }
+ else {
+ assert(0);
+ }
}
else {
return -1;
ctype = CacheRequestType_ST;
break;
case RubyRequestType_Locked_Read:
- ctype = CacheRequestType_ST;
- break;
case RubyRequestType_Locked_Write:
- ctype = CacheRequestType_ST;
- break;
case RubyRequestType_RMW_Read:
- ctype = CacheRequestType_ATOMIC;
- break;
case RubyRequestType_RMW_Write:
ctype = CacheRequestType_ATOMIC;
break;
}
Address line_addr(request.paddr);
line_addr.makeLineAddress();
- CacheMsg msg(line_addr, Address(request.paddr), ctype, Address(request.pc), amtype, request.len, PrefetchBit_No);
+ CacheMsg msg(line_addr, Address(request.paddr), ctype, Address(request.pc), amtype, request.len, PrefetchBit_No, request.proc_id);
if (Debug::getProtocolTrace()) {
g_system_ptr->getProfiler()->profileTransition("Seq", m_version, Address(request.paddr),