RubySystem.cc revision 9208
19243SN/A/* 211846Swendy.elsasser@arm.com * Copyright (c) 1999-2011 Mark D. Hill and David A. Wood 39243SN/A * All rights reserved. 49243SN/A * 59243SN/A * Redistribution and use in source and binary forms, with or without 69243SN/A * modification, are permitted provided that the following conditions are 79243SN/A * met: redistributions of source code must retain the above copyright 89243SN/A * notice, this list of conditions and the following disclaimer; 99243SN/A * redistributions in binary form must reproduce the above copyright 109243SN/A * notice, this list of conditions and the following disclaimer in the 119243SN/A * documentation and/or other materials provided with the distribution; 129243SN/A * neither the name of the copyright holders nor the names of its 139243SN/A * contributors may be used to endorse or promote products derived from 149831SN/A * this software without specific prior written permission. 159831SN/A * 169831SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179243SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189243SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 199243SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 209243SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 219243SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 229243SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239243SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249243SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259243SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 269243SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279243SN/A */ 289243SN/A 299243SN/A#include <fcntl.h> 309243SN/A#include <zlib.h> 319243SN/A 329243SN/A#include <cstdio> 339243SN/A 349243SN/A#include "base/intmath.hh" 359243SN/A#include "base/output.hh" 369243SN/A#include "debug/RubyCacheTrace.hh" 379243SN/A#include "mem/ruby/common/Address.hh" 389243SN/A#include "mem/ruby/network/Network.hh" 399243SN/A#include "mem/ruby/profiler/Profiler.hh" 409243SN/A#include "mem/ruby/system/System.hh" 419243SN/A#include "sim/eventq.hh" 429967SN/A#include "sim/simulate.hh" 4310618SOmar.Naji@arm.com 4411678Swendy.elsasser@arm.comusing namespace std; 459243SN/A 469243SN/Aint RubySystem::m_random_seed; 4711793Sbrandon.potter@amd.combool RubySystem::m_randomization; 4811793Sbrandon.potter@amd.comint RubySystem::m_block_size_bytes; 4910146Sandreas.hansson@arm.comint RubySystem::m_block_size_bits; 509356SN/Auint64 RubySystem::m_memory_size_bytes; 5110146Sandreas.hansson@arm.comint RubySystem::m_memory_size_bits; 5210247Sandreas.hansson@arm.com 5310208Sandreas.hansson@arm.comNetwork* RubySystem::m_network_ptr; 549352SN/AProfiler* RubySystem::m_profiler_ptr; 559814SN/AMemoryVector* RubySystem::m_mem_vec_ptr; 569243SN/A 579243SN/ARubySystem::RubySystem(const Params *p) 5810432SOmar.Naji@arm.com : ClockedObject(p) 599243SN/A{ 6010146Sandreas.hansson@arm.com if (g_system_ptr != NULL) 619243SN/A fatal("Only one RubySystem object currently allowed.\n"); 6210619Sandreas.hansson@arm.com 639243SN/A m_random_seed = p->random_seed; 6410211Sandreas.hansson@arm.com srandom(m_random_seed); 6511678Swendy.elsasser@arm.com m_randomization = p->randomization; 6610618SOmar.Naji@arm.com 6710489SOmar.Naji@arm.com m_block_size_bytes = p->block_size_bytes; 689831SN/A assert(isPowerOf2(m_block_size_bytes)); 699831SN/A m_block_size_bits = floorLog2(m_block_size_bytes); 709831SN/A 719831SN/A m_memory_size_bytes = p->mem_size; 729831SN/A if (m_memory_size_bytes == 0) { 7310140SN/A m_memory_size_bits = 0; 7410646Sandreas.hansson@arm.com } else { 759243SN/A m_memory_size_bits = floorLog2(m_memory_size_bytes); 7610394Swendy.elsasser@arm.com } 7710394Swendy.elsasser@arm.com 789566SN/A g_system_ptr = this; 799243SN/A if (p->no_mem_vec) { 809243SN/A m_mem_vec_ptr = NULL; 8110140SN/A } else { 8210140SN/A m_mem_vec_ptr = new MemoryVector; 8310147Sandreas.hansson@arm.com m_mem_vec_ptr->resize(m_memory_size_bytes); 8410147Sandreas.hansson@arm.com } 8510393Swendy.elsasser@arm.com 8610394Swendy.elsasser@arm.com // 8710394Swendy.elsasser@arm.com // Print ruby configuration and stats at exit 8811673SOmar.Naji@arm.com // 8911673SOmar.Naji@arm.com RubyExitCallback* rubyExitCB = new RubyExitCallback(p->stats_filename); 909243SN/A registerExitCallback(rubyExitCB); 919243SN/A m_warmup_enabled = false; 9210141SN/A m_cooldown_enabled = false; 939726SN/A} 949726SN/A 9510618SOmar.Naji@arm.comvoid 9610618SOmar.Naji@arm.comRubySystem::init() 979243SN/A{ 9810620Sandreas.hansson@arm.com m_profiler_ptr->clearStats(); 9910620Sandreas.hansson@arm.com} 10010620Sandreas.hansson@arm.com 10110620Sandreas.hansson@arm.comvoid 10210620Sandreas.hansson@arm.comRubySystem::registerNetwork(Network* network_ptr) 10310889Sandreas.hansson@arm.com{ 10410889Sandreas.hansson@arm.com m_network_ptr = network_ptr; 10510889Sandreas.hansson@arm.com} 10610618SOmar.Naji@arm.com 10712081Sspwilson2@wisc.eduvoid 10810618SOmar.Naji@arm.comRubySystem::registerProfiler(Profiler* profiler_ptr) 10910246Sandreas.hansson@arm.com{ 11010246Sandreas.hansson@arm.com m_profiler_ptr = profiler_ptr; 11110140SN/A} 11210140SN/A 11310140SN/Avoid 11410140SN/ARubySystem::registerAbstractController(AbstractController* cntrl) 11510140SN/A{ 1169243SN/A m_abs_cntrl_vec.push_back(cntrl); 1179243SN/A} 1189567SN/A 1199243SN/Avoid 12010489SOmar.Naji@arm.comRubySystem::registerSparseMemory(SparseMemory* s) 12110489SOmar.Naji@arm.com{ 12210489SOmar.Naji@arm.com m_sparse_memory_vector.push_back(s); 12310489SOmar.Naji@arm.com} 12410489SOmar.Naji@arm.com 12510489SOmar.Naji@arm.comvoid 12610489SOmar.Naji@arm.comRubySystem::registerMemController(MemoryControl *mc) { 12710489SOmar.Naji@arm.com m_memory_controller = mc; 12810489SOmar.Naji@arm.com} 12910489SOmar.Naji@arm.com 1309243SN/ARubySystem::~RubySystem() 1319243SN/A{ 1329831SN/A delete m_network_ptr; 1339831SN/A delete m_profiler_ptr; 1349831SN/A if (m_mem_vec_ptr) 1359831SN/A delete m_mem_vec_ptr; 1369831SN/A} 1379243SN/A 13810207Sandreas.hansson@arm.comvoid 13910207Sandreas.hansson@arm.comRubySystem::printStats(ostream& out) 14010207Sandreas.hansson@arm.com{ 14110207Sandreas.hansson@arm.com const time_t T = time(NULL); 14210207Sandreas.hansson@arm.com tm *localTime = localtime(&T); 14310394Swendy.elsasser@arm.com char buf[100]; 14410394Swendy.elsasser@arm.com strftime(buf, 100, "%b/%d/%Y %H:%M:%S", localTime); 14510394Swendy.elsasser@arm.com 14610394Swendy.elsasser@arm.com out << "Real time: " << buf << endl; 14710394Swendy.elsasser@arm.com 14810394Swendy.elsasser@arm.com m_profiler_ptr->printStats(out); 14910394Swendy.elsasser@arm.com m_network_ptr->printStats(out); 15010394Swendy.elsasser@arm.com} 15110394Swendy.elsasser@arm.com 15210394Swendy.elsasser@arm.comvoid 15310394Swendy.elsasser@arm.comRubySystem::writeCompressedTrace(uint8_t *raw_data, string filename, 15410394Swendy.elsasser@arm.com uint64 uncompressed_trace_size) 15510394Swendy.elsasser@arm.com{ 15610394Swendy.elsasser@arm.com // Create the checkpoint file for the memory 15710394Swendy.elsasser@arm.com string thefile = Checkpoint::dir() + "/" + filename.c_str(); 15810394Swendy.elsasser@arm.com 15910394Swendy.elsasser@arm.com int fd = creat(thefile.c_str(), 0664); 16010394Swendy.elsasser@arm.com if (fd < 0) { 16110394Swendy.elsasser@arm.com perror("creat"); 16210394Swendy.elsasser@arm.com fatal("Can't open memory trace file '%s'\n", filename); 16310394Swendy.elsasser@arm.com } 16410394Swendy.elsasser@arm.com 16510561SOmar.Naji@arm.com gzFile compressedMemory = gzdopen(fd, "wb"); 16610561SOmar.Naji@arm.com if (compressedMemory == NULL) 16710394Swendy.elsasser@arm.com fatal("Insufficient memory to allocate compression state for %s\n", 16810394Swendy.elsasser@arm.com filename); 16910394Swendy.elsasser@arm.com 17010394Swendy.elsasser@arm.com if (gzwrite(compressedMemory, raw_data, uncompressed_trace_size) != 17110394Swendy.elsasser@arm.com uncompressed_trace_size) { 17210394Swendy.elsasser@arm.com fatal("Write failed on memory trace file '%s'\n", filename); 1739243SN/A } 1749243SN/A 1759243SN/A if (gzclose(compressedMemory)) { 17610146Sandreas.hansson@arm.com fatal("Close failed on memory trace file '%s'\n", filename); 17710140SN/A } 17810466Sandreas.hansson@arm.com delete raw_data; 17910466Sandreas.hansson@arm.com} 18010466Sandreas.hansson@arm.com 18110146Sandreas.hansson@arm.comvoid 18210140SN/ARubySystem::serialize(std::ostream &os) 18310140SN/A{ 18410140SN/A m_cooldown_enabled = true; 18510646Sandreas.hansson@arm.com 18610646Sandreas.hansson@arm.com vector<Sequencer*> sequencer_map; 18710646Sandreas.hansson@arm.com Sequencer* sequencer_ptr = NULL; 18810646Sandreas.hansson@arm.com int cntrl_id = -1; 18910646Sandreas.hansson@arm.com 19010646Sandreas.hansson@arm.com 19110646Sandreas.hansson@arm.com for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) { 19210646Sandreas.hansson@arm.com sequencer_map.push_back(m_abs_cntrl_vec[cntrl]->getSequencer()); 19310646Sandreas.hansson@arm.com if (sequencer_ptr == NULL) { 19410646Sandreas.hansson@arm.com sequencer_ptr = sequencer_map[cntrl]; 19510646Sandreas.hansson@arm.com cntrl_id = cntrl; 19610646Sandreas.hansson@arm.com } 19710646Sandreas.hansson@arm.com } 19810646Sandreas.hansson@arm.com 19910646Sandreas.hansson@arm.com assert(sequencer_ptr != NULL); 20010646Sandreas.hansson@arm.com 20110646Sandreas.hansson@arm.com for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) { 20210646Sandreas.hansson@arm.com if (sequencer_map[cntrl] == NULL) { 20310646Sandreas.hansson@arm.com sequencer_map[cntrl] = sequencer_ptr; 20410646Sandreas.hansson@arm.com } 20510646Sandreas.hansson@arm.com } 20610646Sandreas.hansson@arm.com 20710646Sandreas.hansson@arm.com DPRINTF(RubyCacheTrace, "Recording Cache Trace\n"); 20810646Sandreas.hansson@arm.com // Create the CacheRecorder and record the cache trace 20910646Sandreas.hansson@arm.com m_cache_recorder = new CacheRecorder(NULL, 0, sequencer_map); 21010646Sandreas.hansson@arm.com 21110646Sandreas.hansson@arm.com for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) { 21210646Sandreas.hansson@arm.com m_abs_cntrl_vec[cntrl]->recordCacheTrace(cntrl, m_cache_recorder); 21310646Sandreas.hansson@arm.com } 21410646Sandreas.hansson@arm.com 21510646Sandreas.hansson@arm.com DPRINTF(RubyCacheTrace, "Cache Trace Complete\n"); 21610646Sandreas.hansson@arm.com // save the current tick value 21710646Sandreas.hansson@arm.com Tick curtick_original = curTick(); 21810646Sandreas.hansson@arm.com // save the event queue head 21910646Sandreas.hansson@arm.com Event* eventq_head = eventq->replaceHead(NULL); 22010646Sandreas.hansson@arm.com DPRINTF(RubyCacheTrace, "Recording current tick %ld and event queue\n", 22110646Sandreas.hansson@arm.com curtick_original); 22210646Sandreas.hansson@arm.com 22310646Sandreas.hansson@arm.com // Schedule an event to start cache cooldown 22410646Sandreas.hansson@arm.com DPRINTF(RubyCacheTrace, "Starting cache flush\n"); 22510140SN/A enqueueRubyEvent(curTick()); 22610140SN/A simulate(); 22710140SN/A DPRINTF(RubyCacheTrace, "Cache flush complete\n"); 22810146Sandreas.hansson@arm.com 2299243SN/A // Restore eventq head 23010619Sandreas.hansson@arm.com eventq_head = eventq->replaceHead(eventq_head); 23110619Sandreas.hansson@arm.com // Restore curTick 23210618SOmar.Naji@arm.com curTick(curtick_original); 23310619Sandreas.hansson@arm.com 23410619Sandreas.hansson@arm.com uint8_t *raw_data = NULL; 23510619Sandreas.hansson@arm.com 23610619Sandreas.hansson@arm.com if (m_mem_vec_ptr != NULL) { 23710619Sandreas.hansson@arm.com uint64 memory_trace_size = m_mem_vec_ptr->collatePages(raw_data); 23810619Sandreas.hansson@arm.com 23910619Sandreas.hansson@arm.com string memory_trace_file = name() + ".memory.gz"; 24010619Sandreas.hansson@arm.com writeCompressedTrace(raw_data, memory_trace_file, 24110619Sandreas.hansson@arm.com memory_trace_size); 24210619Sandreas.hansson@arm.com 24310619Sandreas.hansson@arm.com SERIALIZE_SCALAR(memory_trace_file); 24410619Sandreas.hansson@arm.com SERIALIZE_SCALAR(memory_trace_size); 24510619Sandreas.hansson@arm.com 24610619Sandreas.hansson@arm.com } else { 24710619Sandreas.hansson@arm.com for (int i = 0; i < m_sparse_memory_vector.size(); ++i) { 24810618SOmar.Naji@arm.com m_sparse_memory_vector[i]->recordBlocks(cntrl_id, 2499243SN/A m_cache_recorder); 2509243SN/A } 2519243SN/A } 25210146Sandreas.hansson@arm.com 2539243SN/A // Aggergate the trace entries together into a single array 2549243SN/A raw_data = new uint8_t[4096]; 2559243SN/A uint64 cache_trace_size = m_cache_recorder->aggregateRecords(&raw_data, 25611334Sandreas.hansson@arm.com 4096); 25711334Sandreas.hansson@arm.com string cache_trace_file = name() + ".cache.gz"; 25811334Sandreas.hansson@arm.com writeCompressedTrace(raw_data, cache_trace_file, cache_trace_size); 2599243SN/A 2609243SN/A SERIALIZE_SCALAR(cache_trace_file); 2619243SN/A SERIALIZE_SCALAR(cache_trace_size); 2629243SN/A 26311334Sandreas.hansson@arm.com m_cooldown_enabled = false; 2649243SN/A} 2659243SN/A 2669243SN/Avoid 2679243SN/ARubySystem::readCompressedTrace(string filename, uint8_t *&raw_data, 2689243SN/A uint64& uncompressed_trace_size) 2699243SN/A{ 2709243SN/A // Read the trace file 2719243SN/A gzFile compressedTrace; 27210146Sandreas.hansson@arm.com 2739243SN/A // trace file 2749831SN/A int fd = open(filename.c_str(), O_RDONLY); 2759831SN/A if (fd < 0) { 2769831SN/A perror("open"); 2779243SN/A fatal("Unable to open trace file %s", filename); 2789831SN/A } 2799831SN/A 2809243SN/A compressedTrace = gzdopen(fd, "rb"); 2819243SN/A if (compressedTrace == NULL) { 2829243SN/A fatal("Insufficient memory to allocate compression state for %s\n", 28310146Sandreas.hansson@arm.com filename); 2849243SN/A } 2859831SN/A 2869831SN/A raw_data = new uint8_t[uncompressed_trace_size]; 2879831SN/A if (gzread(compressedTrace, raw_data, uncompressed_trace_size) < 2889243SN/A uncompressed_trace_size) { 2899243SN/A fatal("Unable to read complete trace from file %s\n", filename); 29010146Sandreas.hansson@arm.com } 29110146Sandreas.hansson@arm.com 29210143SN/A if (gzclose(compressedTrace)) { 2939243SN/A fatal("Failed to close cache trace file '%s'\n", filename); 2949669SN/A } 29510136SN/A} 29610136SN/A 2979243SN/Avoid 2989967SN/ARubySystem::unserialize(Checkpoint *cp, const string §ion) 29910245Sandreas.hansson@arm.com{ 30010245Sandreas.hansson@arm.com // 30110245Sandreas.hansson@arm.com // The main purpose for clearing stats in the unserialize process is so 3029243SN/A // that the profiler can correctly set its start time to the unserialized 30310286Sandreas.hansson@arm.com // value of curTick() 30410286Sandreas.hansson@arm.com // 3059831SN/A clearStats(); 3069243SN/A uint8_t *uncompressed_trace = NULL; 3079491SN/A 3089831SN/A if (m_mem_vec_ptr != NULL) { 30910136SN/A string memory_trace_file; 3109491SN/A uint64 memory_trace_size = 0; 3119491SN/A 3129831SN/A UNSERIALIZE_SCALAR(memory_trace_file); 3139243SN/A UNSERIALIZE_SCALAR(memory_trace_size); 3149669SN/A memory_trace_file = cp->cptDir + "/" + memory_trace_file; 3159566SN/A 3169566SN/A readCompressedTrace(memory_trace_file, uncompressed_trace, 3179669SN/A memory_trace_size); 3189669SN/A m_mem_vec_ptr->populatePages(uncompressed_trace); 3199669SN/A 3209669SN/A delete uncompressed_trace; 3219669SN/A uncompressed_trace = NULL; 3229669SN/A } 3239669SN/A 3249669SN/A string cache_trace_file; 3259669SN/A uint64 cache_trace_size = 0; 3269669SN/A 32711189Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(cache_trace_file); 3289669SN/A UNSERIALIZE_SCALAR(cache_trace_size); 32910136SN/A cache_trace_file = cp->cptDir + "/" + cache_trace_file; 33010286Sandreas.hansson@arm.com 33110286Sandreas.hansson@arm.com readCompressedTrace(cache_trace_file, uncompressed_trace, 33210286Sandreas.hansson@arm.com cache_trace_size); 3339669SN/A m_warmup_enabled = true; 3349669SN/A 3359669SN/A vector<Sequencer*> sequencer_map; 33610286Sandreas.hansson@arm.com Sequencer* t = NULL; 33710286Sandreas.hansson@arm.com for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) { 3389669SN/A sequencer_map.push_back(m_abs_cntrl_vec[cntrl]->getSequencer()); 3399669SN/A if(t == NULL) t = sequencer_map[cntrl]; 3409491SN/A } 3419243SN/A 3429243SN/A assert(t != NULL); 3439243SN/A 3449491SN/A for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) { 3459491SN/A if (sequencer_map[cntrl] == NULL) { 3469243SN/A sequencer_map[cntrl] = t; 3479243SN/A } 3489243SN/A } 34911189Sandreas.hansson@arm.com 3509243SN/A m_cache_recorder = new CacheRecorder(uncompressed_trace, cache_trace_size, 35110136SN/A sequencer_map); 3529491SN/A} 3539491SN/A 3549491SN/Avoid 35510286Sandreas.hansson@arm.comRubySystem::startup() 35610286Sandreas.hansson@arm.com{ 35710286Sandreas.hansson@arm.com if (m_warmup_enabled) { 3589566SN/A // save the current tick value 3599566SN/A Tick curtick_original = curTick(); 3609566SN/A // save the event queue head 3619566SN/A Event* eventq_head = eventq->replaceHead(NULL); 3629566SN/A // set curTick to 0 3639491SN/A curTick(0); 3649491SN/A 3659243SN/A // Schedule an event to start cache warmup 3669243SN/A enqueueRubyEvent(curTick()); 3679243SN/A simulate(); 3689491SN/A 3699243SN/A delete m_cache_recorder; 3709243SN/A m_cache_recorder = NULL; 3719243SN/A m_warmup_enabled = false; 37210286Sandreas.hansson@arm.com // reset DRAM so that it's not waiting for events on the old event 37310286Sandreas.hansson@arm.com // queue 3749243SN/A m_memory_controller->reset(); 37511189Sandreas.hansson@arm.com // Restore eventq head 3769243SN/A eventq_head = eventq->replaceHead(eventq_head); 3779243SN/A // Restore curTick 3789243SN/A curTick(curtick_original); 3799243SN/A } 3809243SN/A} 3819243SN/A 3829243SN/Avoid 38310245Sandreas.hansson@arm.comRubySystem::RubyEvent::process() 3849243SN/A{ 3859243SN/A if (ruby_system->m_warmup_enabled) { 3869831SN/A ruby_system->m_cache_recorder->enqueueNextFetchRequest(); 3879243SN/A } else if (ruby_system->m_cooldown_enabled) { 3889243SN/A ruby_system->m_cache_recorder->enqueueNextFlushRequest(); 3899567SN/A } 3909567SN/A} 3919967SN/A 3929967SN/Avoid 39310618SOmar.Naji@arm.comRubySystem::clearStats() const 3949243SN/A{ 3959243SN/A m_profiler_ptr->clearStats(); 3969243SN/A m_network_ptr->clearStats(); 39710146Sandreas.hansson@arm.com} 3989243SN/A 3999243SN/A#ifdef CHECK_COHERENCE 4009243SN/A// This code will check for cases if the given cache block is exclusive in 4019243SN/A// one node and shared in another-- a coherence violation 4029243SN/A// 4039831SN/A// To use, the SLICC specification must call sequencer.checkCoherence(address) 4049831SN/A// when the controller changes to a state with new permissions. Do this 4059831SN/A// in setState. The SLICC spec must also define methods "isBlockShared" 4069831SN/A// and "isBlockExclusive" that are specific to that protocol 4079831SN/A// 4089831SN/Avoid 4099831SN/ARubySystem::checkGlobalCoherenceInvariant(const Address& addr) 4109831SN/A{ 4119243SN/A#if 0 4129831SN/A NodeID exclusive = -1; 4139831SN/A bool sharedDetected = false; 4149831SN/A NodeID lastShared = -1; 4159831SN/A 4169831SN/A for (int i = 0; i < m_chip_vector.size(); i++) { 4179831SN/A if (m_chip_vector[i]->isBlockExclusive(addr)) { 4189831SN/A if (exclusive != -1) { 4199243SN/A // coherence violation 4209831SN/A WARN_EXPR(exclusive); 4219831SN/A WARN_EXPR(m_chip_vector[i]->getID()); 4229831SN/A WARN_EXPR(addr); 42310889Sandreas.hansson@arm.com WARN_EXPR(getTime()); 42410889Sandreas.hansson@arm.com ERROR_MSG("Coherence Violation Detected -- 2 exclusive chips"); 42510889Sandreas.hansson@arm.com } else if (sharedDetected) { 42610889Sandreas.hansson@arm.com WARN_EXPR(lastShared); 42710889Sandreas.hansson@arm.com WARN_EXPR(m_chip_vector[i]->getID()); 42810889Sandreas.hansson@arm.com WARN_EXPR(addr); 42910889Sandreas.hansson@arm.com WARN_EXPR(getTime()); 43010889Sandreas.hansson@arm.com ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared"); 43110889Sandreas.hansson@arm.com } else { 43210889Sandreas.hansson@arm.com exclusive = m_chip_vector[i]->getID(); 43310889Sandreas.hansson@arm.com } 43410889Sandreas.hansson@arm.com } else if (m_chip_vector[i]->isBlockShared(addr)) { 43510889Sandreas.hansson@arm.com sharedDetected = true; 43610889Sandreas.hansson@arm.com lastShared = m_chip_vector[i]->getID(); 43710889Sandreas.hansson@arm.com 43810889Sandreas.hansson@arm.com if (exclusive != -1) { 4399831SN/A WARN_EXPR(lastShared); 4409243SN/A WARN_EXPR(exclusive); 4419831SN/A WARN_EXPR(addr); 4429831SN/A WARN_EXPR(getTime()); 4439831SN/A ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared"); 4449831SN/A } 4459831SN/A } 4469831SN/A } 4479831SN/A#endif 4489831SN/A} 4499831SN/A#endif 4509831SN/A 4519831SN/ARubySystem * 4529831SN/ARubySystemParams::create() 4539966SN/A{ 4549831SN/A return new RubySystem(this); 4559831SN/A} 4569831SN/A 4579831SN/A/** 4589831SN/A * virtual process function that is invoked when the callback 4599831SN/A * queue is executed. 4609831SN/A */ 4619831SN/Avoid 4629831SN/ARubyExitCallback::process() 46311678Swendy.elsasser@arm.com{ 46411678Swendy.elsasser@arm.com std::ostream *os = simout.create(stats_filename); 46511678Swendy.elsasser@arm.com RubySystem::printStats(*os); 4669831SN/A} 4679831SN/A