diff -r c0a515fba3ac -r 5f4df071ed2a src/mem/ruby/system/Sequencer.hh --- a/src/mem/ruby/system/Sequencer.hh Wed Aug 11 14:36:18 2010 -0700 +++ b/src/mem/ruby/system/Sequencer.hh Wed Aug 11 14:36:18 2010 -0700 @@ -105,11 +105,12 @@ void hitCallback(SequencerRequest* request, GenericMachineType mach, - DataBlock& data); + DataBlock& data, + bool success); bool insertRequest(SequencerRequest* request); - void handleLlscWrites(const Address& address, SequencerRequest* request); + bool handleLlsc(const Address& address, SequencerRequest* request); // Private copy constructor and assignment operator Sequencer(const Sequencer& obj); diff -r c0a515fba3ac -r 5f4df071ed2a src/mem/ruby/system/Sequencer.cc --- a/src/mem/ruby/system/Sequencer.cc Wed Aug 11 14:36:18 2010 -0700 +++ b/src/mem/ruby/system/Sequencer.cc Wed Aug 11 14:36:18 2010 -0700 @@ -304,9 +304,15 @@ markRemoved(); } -void -Sequencer::handleLlscWrites(const Address& address, SequencerRequest* request) +bool +Sequencer::handleLlsc(const Address& address, SequencerRequest* request) { + // + // 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->ruby_request.type == RubyRequestType_Locked_Write) { if (!m_dataCache_ptr->isLocked(address, m_version)) { // @@ -314,6 +320,7 @@ // setting the extra data to zero. // request->ruby_request.pkt->req->setExtraData(0); + success = false; } else { // // For successful SC requests, indicate the success to the cpu by @@ -321,6 +328,9 @@ // request->ruby_request.pkt->req->setExtraData(1); } + // + // Independent of success, all SC operations must clear the lock + // m_dataCache_ptr->clearLocked(address); } else if (request->ruby_request.type == RubyRequestType_Locked_Read) { // @@ -334,6 +344,7 @@ // m_dataCache_ptr->clearLocked(address); } + return success; } void @@ -367,7 +378,7 @@ // For Alpha, properly handle LL, SC, and write requests with respect to // locked cache blocks. // - handleLlscWrites(address, request); + bool success = handleLlsc(address, request); if (request->ruby_request.type == RubyRequestType_RMW_Read) { m_controller->blockOnQueue(address, m_mandatory_q_ptr); @@ -375,7 +386,7 @@ m_controller->unblock(address); } - hitCallback(request, mach, data); + hitCallback(request, mach, data, success); } void @@ -403,13 +414,14 @@ (request->ruby_request.type == RubyRequestType_RMW_Read) || (request->ruby_request.type == RubyRequestType_IFETCH)); - hitCallback(request, mach, data); + hitCallback(request, mach, data, true); } void Sequencer::hitCallback(SequencerRequest* srequest, GenericMachineType mach, - DataBlock& data) + DataBlock& data, + bool success) { const RubyRequest & ruby_request = srequest->ruby_request; Address request_address(ruby_request.paddr); @@ -435,10 +447,17 @@ g_system_ptr->getProfiler()->missLatency(miss_latency, type, mach); if (Debug::getProtocolTrace()) { - g_system_ptr->getProfiler()-> - profileTransition("Seq", m_version, - Address(ruby_request.paddr), "", "Done", "", - csprintf("%d cycles", miss_latency)); + if (success) { + g_system_ptr->getProfiler()-> + profileTransition("Seq", m_version, + Address(ruby_request.paddr), "", "Done", "", + csprintf("%d cycles", miss_latency)); + } else { + g_system_ptr->getProfiler()-> + profileTransition("Seq", m_version, + Address(ruby_request.paddr), "", "SC_Failed", "", + csprintf("%d cycles", miss_latency)); + } } } #if 0