Sequencer.cc (6833:38da844de114) | Sequencer.cc (6845:9740ade45962) |
---|---|
1 2/* 3 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright --- 13 unchanged lines hidden (view full) --- 22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 | 1 2/* 3 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright --- 13 unchanged lines hidden (view full) --- 22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 |
30#include "mem/ruby/libruby.hh" |
|
30#include "mem/ruby/common/Global.hh" 31#include "mem/ruby/system/Sequencer.hh" 32#include "mem/ruby/system/System.hh" 33#include "mem/protocol/Protocol.hh" 34#include "mem/ruby/profiler/Profiler.hh" 35#include "mem/ruby/system/CacheMemory.hh" 36#include "mem/protocol/CacheMsg.hh" 37#include "mem/ruby/recorder/Tracer.hh" --- 317 unchanged lines hidden (view full) --- 355 m_servicing_atomic = 200; 356 } 357 } 358 m_hit_callback(srequest->id); 359 delete srequest; 360} 361 362// Returns true if the sequencer already has a load or store outstanding | 31#include "mem/ruby/common/Global.hh" 32#include "mem/ruby/system/Sequencer.hh" 33#include "mem/ruby/system/System.hh" 34#include "mem/protocol/Protocol.hh" 35#include "mem/ruby/profiler/Profiler.hh" 36#include "mem/ruby/system/CacheMemory.hh" 37#include "mem/protocol/CacheMsg.hh" 38#include "mem/ruby/recorder/Tracer.hh" --- 317 unchanged lines hidden (view full) --- 356 m_servicing_atomic = 200; 357 } 358 } 359 m_hit_callback(srequest->id); 360 delete srequest; 361} 362 363// Returns true if the sequencer already has a load or store outstanding |
363bool Sequencer::isReady(const RubyRequest& request, bool dont_set) { | 364int Sequencer::isReady(const RubyRequest& request) { |
364 // POLINA: check if we are currently flushing the write buffer, if so Ruby is returned as not ready 365 // to simulate stalling of the front-end 366 // Do we stall all the sequencers? If it is atomic instruction - yes! 367 if (m_outstanding_count >= m_max_outstanding_requests) { | 365 // POLINA: check if we are currently flushing the write buffer, if so Ruby is returned as not ready 366 // to simulate stalling of the front-end 367 // Do we stall all the sequencers? If it is atomic instruction - yes! 368 if (m_outstanding_count >= m_max_outstanding_requests) { |
368 return false; | 369 return LIBRUBY_BUFFER_FULL; |
369 } 370 371 if( m_writeRequestTable.exist(line_address(Address(request.paddr))) || 372 m_readRequestTable.exist(line_address(Address(request.paddr))) ){ 373 //cout << "OUTSTANDING REQUEST EXISTS " << p << " VER " << m_version << endl; 374 //printProgress(cout); | 370 } 371 372 if( m_writeRequestTable.exist(line_address(Address(request.paddr))) || 373 m_readRequestTable.exist(line_address(Address(request.paddr))) ){ 374 //cout << "OUTSTANDING REQUEST EXISTS " << p << " VER " << m_version << endl; 375 //printProgress(cout); |
375 return false; | 376 return LIBRUBY_ALIASED_REQUEST; |
376 } | 377 } |
377 378 if (m_servicing_atomic != 200 && m_servicing_atomic != request.proc_id) { 379 assert(m_atomics_counter > 0); 380 return false; | 378 379 if (request.type == RubyRequestType_RMW_Read) { 380 if (m_servicing_atomic == 200) { 381 assert(m_atomics_counter == 0); 382 m_servicing_atomic = request.proc_id; 383 } 384 else { 385 assert(m_servicing_atomic == request.proc_id); 386 } 387 m_atomics_counter++; |
381 } 382 else { | 388 } 389 else { |
383 if (!dont_set) { 384 if (request.type == RubyRequestType_RMW_Read) { 385 if (m_servicing_atomic == 200) { 386 assert(m_atomics_counter == 0); 387 m_servicing_atomic = request.proc_id; 388 } 389 else { 390 assert(m_servicing_atomic == request.proc_id); 391 } 392 m_atomics_counter++; | 390 if (m_servicing_atomic == request.proc_id) { 391 if (request.type != RubyRequestType_RMW_Write) { 392 m_servicing_atomic = 200; 393 m_atomics_counter = 0; |
393 } | 394 } |
394 else { 395 if (m_servicing_atomic == request.proc_id) { 396 if (request.type != RubyRequestType_RMW_Write) { 397 m_servicing_atomic = 200; 398 m_atomics_counter = 0; 399 } 400 } 401 } | |
402 } 403 } 404 | 395 } 396 } 397 |
405 return true; | 398 return 1; |
406} 407 408bool Sequencer::empty() const { 409 return (m_writeRequestTable.size() == 0) && (m_readRequestTable.size() == 0); 410} 411 412 413int64_t Sequencer::makeRequest(const RubyRequest & request) 414{ 415 assert(Address(request.paddr).getOffset() + request.len <= RubySystem::getBlockSizeBytes()); | 399} 400 401bool Sequencer::empty() const { 402 return (m_writeRequestTable.size() == 0) && (m_readRequestTable.size() == 0); 403} 404 405 406int64_t Sequencer::makeRequest(const RubyRequest & request) 407{ 408 assert(Address(request.paddr).getOffset() + request.len <= RubySystem::getBlockSizeBytes()); |
416 if (isReady(request)) { | 409 int ready = isReady(request); 410 if (ready > 0) { |
417 int64_t id = makeUniqueRequestID(); 418 SequencerRequest *srequest = new SequencerRequest(request, id, g_eventQueue_ptr->getTime()); 419 bool found = insertRequest(srequest); 420 if (!found) { 421 if (request.type == RubyRequestType_Locked_Write) { 422 // NOTE: it is OK to check the locked flag here as the mandatory queue will be checked first 423 // ensuring that nothing comes between checking the flag and servicing the store 424 if (!m_dataCache_ptr->isLocked(line_address(Address(request.paddr)), m_version)) { --- 11 unchanged lines hidden (view full) --- 436 // TODO: issue hardware prefetches here 437 return id; 438 } 439 else { 440 assert(0); 441 } 442 } 443 else { | 411 int64_t id = makeUniqueRequestID(); 412 SequencerRequest *srequest = new SequencerRequest(request, id, g_eventQueue_ptr->getTime()); 413 bool found = insertRequest(srequest); 414 if (!found) { 415 if (request.type == RubyRequestType_Locked_Write) { 416 // NOTE: it is OK to check the locked flag here as the mandatory queue will be checked first 417 // ensuring that nothing comes between checking the flag and servicing the store 418 if (!m_dataCache_ptr->isLocked(line_address(Address(request.paddr)), m_version)) { --- 11 unchanged lines hidden (view full) --- 430 // TODO: issue hardware prefetches here 431 return id; 432 } 433 else { 434 assert(0); 435 } 436 } 437 else { |
444 return -1; | 438 return ready; |
445 } 446} 447 448void Sequencer::issueRequest(const RubyRequest& request) { 449 450 // TODO: get rid of CacheMsg, CacheRequestType, and AccessModeTYpe, & have SLICC use RubyRequest and subtypes natively 451 CacheRequestType ctype; 452 switch(request.type) { --- 88 unchanged lines hidden --- | 439 } 440} 441 442void Sequencer::issueRequest(const RubyRequest& request) { 443 444 // TODO: get rid of CacheMsg, CacheRequestType, and AccessModeTYpe, & have SLICC use RubyRequest and subtypes natively 445 CacheRequestType ctype; 446 switch(request.type) { --- 88 unchanged lines hidden --- |