In the future, for things like this, you should probably use "hg cp" to indicate that you forked the file in the history. Same with memtest_ruby.py.
Nate On Wed, Nov 18, 2009 at 6:05 PM, Brad Beckmann <[email protected]> wrote: > changeset db88ebe2c9fc in /z/repo/m5 > details: http://repo.m5sim.org/m5?cmd=changeset;node=db88ebe2c9fc > description: > ruby: split CacheMemory.hh into a .hh and a .cc > > diffstat: > > 3 files changed, 460 insertions(+), 459 deletions(-) > src/mem/ruby/system/CacheMemory.cc | 459 ++++++++++++++++++++++++++++++++++++ > src/mem/ruby/system/CacheMemory.hh | 459 ------------------------------------ > src/mem/ruby/system/SConscript | 1 > > diffs (truncated from 942 to 300 lines): > > diff -r 8da9d36fc14a -r db88ebe2c9fc src/mem/ruby/system/CacheMemory.cc > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/src/mem/ruby/system/CacheMemory.cc Wed Nov 18 16:33:35 2009 -0800 > @@ -0,0 +1,459 @@ > +/* > + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > + * met: redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer; > + * redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution; > + * neither the name of the copyright holders nor the names of its > + * contributors may be used to endorse or promote products derived from > + * this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT > + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR > + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT > + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, > + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT > + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE > + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#include "mem/ruby/system/CacheMemory.hh" > + > +// Output operator declaration > +//ostream& operator<<(ostream& out, const CacheMemory<ENTRY>& obj); > + > +// ******************* Definitions ******************* > + > +// Output operator definition > +ostream& operator<<(ostream& out, const CacheMemory& obj) > +{ > + obj.print(out); > + out << flush; > + return out; > +} > + > + > +// **************************************************************** > + > +CacheMemory::CacheMemory(const string & name) > + : m_cache_name(name) > +{ > + m_profiler_ptr = new CacheProfiler(name); > +} > + > +void CacheMemory::init(const vector<string> & argv) > +{ > + int cache_size = 0; > + string policy; > + > + m_controller = NULL; > + for (uint32 i=0; i<argv.size(); i+=2) { > + if (argv[i] == "size_kb") { > + cache_size = atoi(argv[i+1].c_str()); > + } else if (argv[i] == "latency") { > + m_latency = atoi(argv[i+1].c_str()); > + } else if (argv[i] == "assoc") { > + m_cache_assoc = atoi(argv[i+1].c_str()); > + } else if (argv[i] == "replacement_policy") { > + policy = argv[i+1]; > + } else if (argv[i] == "controller") { > + m_controller = RubySystem::getController(argv[i+1]); > + } else { > + cerr << "WARNING: CacheMemory: Unknown configuration parameter: " << > argv[i] << endl; > + } > + } > + > + m_cache_num_sets = cache_size / m_cache_assoc; > + m_cache_num_set_bits = log_int(m_cache_num_sets); > + > + if(policy == "PSEUDO_LRU") > + m_replacementPolicy_ptr = new PseudoLRUPolicy(m_cache_num_sets, > m_cache_assoc); > + else if (policy == "LRU") > + m_replacementPolicy_ptr = new LRUPolicy(m_cache_num_sets, m_cache_assoc); > + else > + assert(false); > + > + m_cache.setSize(m_cache_num_sets); > + m_locked.setSize(m_cache_num_sets); > + for (int i = 0; i < m_cache_num_sets; i++) { > + m_cache[i].setSize(m_cache_assoc); > + m_locked[i].setSize(m_cache_assoc); > + for (int j = 0; j < m_cache_assoc; j++) { > + m_cache[i][j] = NULL; > + m_locked[i][j] = -1; > + } > + } > +} > + > +CacheMemory::~CacheMemory() > +{ > + if(m_replacementPolicy_ptr != NULL) > + delete m_replacementPolicy_ptr; > +} > + > +void CacheMemory::printConfig(ostream& out) > +{ > + out << "Cache config: " << m_cache_name << endl; > + if (m_controller != NULL) > + out << " controller: " << m_controller->getName() << endl; > + out << " cache_associativity: " << m_cache_assoc << endl; > + out << " num_cache_sets_bits: " << m_cache_num_set_bits << endl; > + const int cache_num_sets = 1 << m_cache_num_set_bits; > + out << " num_cache_sets: " << cache_num_sets << endl; > + out << " cache_set_size_bytes: " << cache_num_sets * > RubySystem::getBlockSizeBytes() << endl; > + out << " cache_set_size_Kbytes: " > + << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<10) > << endl; > + out << " cache_set_size_Mbytes: " > + << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<20) > << endl; > + out << " cache_size_bytes: " > + << cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc << > endl; > + out << " cache_size_Kbytes: " > + << double(cache_num_sets * RubySystem::getBlockSizeBytes() * > m_cache_assoc) / (1<<10) << endl; > + out << " cache_size_Mbytes: " > + << double(cache_num_sets * RubySystem::getBlockSizeBytes() * > m_cache_assoc) / (1<<20) << endl; > +} > + > +// PRIVATE METHODS > + > +// convert a Address to its location in the cache > +Index CacheMemory::addressToCacheSet(const Address& address) const > +{ > + assert(address == line_address(address)); > + return address.bitSelect(RubySystem::getBlockSizeBits(), > RubySystem::getBlockSizeBits() + m_cache_num_set_bits-1); > +} > + > +// Given a cache index: returns the index of the tag in a set. > +// returns -1 if the tag is not found. > +int CacheMemory::findTagInSet(Index cacheSet, const Address& tag) const > +{ > + assert(tag == line_address(tag)); > + // search the set for the tags > + for (int i=0; i < m_cache_assoc; i++) { > + if ((m_cache[cacheSet][i] != NULL) && > + (m_cache[cacheSet][i]->m_Address == tag) && > + (m_cache[cacheSet][i]->m_Permission != AccessPermission_NotPresent)) > { > + return i; > + } > + } > + return -1; // Not found > +} > + > +// Given a cache index: returns the index of the tag in a set. > +// returns -1 if the tag is not found. > +int CacheMemory::findTagInSetIgnorePermissions(Index cacheSet, const > Address& tag) const > +{ > + assert(tag == line_address(tag)); > + // search the set for the tags > + for (int i=0; i < m_cache_assoc; i++) { > + if (m_cache[cacheSet][i] != NULL && m_cache[cacheSet][i]->m_Address == > tag) > + return i; > + } > + return -1; // Not found > +} > + > +// PUBLIC METHODS > +bool CacheMemory::tryCacheAccess(const Address& address, > + CacheRequestType type, > + DataBlock*& data_ptr) > +{ > + assert(address == line_address(address)); > + DEBUG_EXPR(CACHE_COMP, HighPrio, address); > + Index cacheSet = addressToCacheSet(address); > + int loc = findTagInSet(cacheSet, address); > + if(loc != -1){ // Do we even have a tag match? > + AbstractCacheEntry* entry = m_cache[cacheSet][loc]; > + m_replacementPolicy_ptr->touch(cacheSet, loc, > g_eventQueue_ptr->getTime()); > + data_ptr = &(entry->getDataBlk()); > + > + if(entry->m_Permission == AccessPermission_Read_Write) { > + return true; > + } > + if ((entry->m_Permission == AccessPermission_Read_Only) && > + (type == CacheRequestType_LD || type == CacheRequestType_IFETCH)) { > + return true; > + } > + // The line must not be accessible > + } > + data_ptr = NULL; > + return false; > +} > + > +bool CacheMemory::testCacheAccess(const Address& address, > + CacheRequestType type, > + DataBlock*& data_ptr) > +{ > + assert(address == line_address(address)); > + DEBUG_EXPR(CACHE_COMP, HighPrio, address); > + Index cacheSet = addressToCacheSet(address); > + int loc = findTagInSet(cacheSet, address); > + if(loc != -1){ // Do we even have a tag match? > + AbstractCacheEntry* entry = m_cache[cacheSet][loc]; > + m_replacementPolicy_ptr->touch(cacheSet, loc, > g_eventQueue_ptr->getTime()); > + data_ptr = &(entry->getDataBlk()); > + > + return (m_cache[cacheSet][loc]->m_Permission != > AccessPermission_NotPresent); > + } > + data_ptr = NULL; > + return false; > +} > + > +// tests to see if an address is present in the cache > +bool CacheMemory::isTagPresent(const Address& address) const > +{ > + assert(address == line_address(address)); > + Index cacheSet = addressToCacheSet(address); > + int location = findTagInSet(cacheSet, address); > + > + if (location == -1) { > + // We didn't find the tag > + DEBUG_EXPR(CACHE_COMP, LowPrio, address); > + DEBUG_MSG(CACHE_COMP, LowPrio, "No tag match"); > + return false; > + } > + DEBUG_EXPR(CACHE_COMP, LowPrio, address); > + DEBUG_MSG(CACHE_COMP, LowPrio, "found"); > + return true; > +} > + > +// Returns true if there is: > +// a) a tag match on this address or there is > +// b) an unused line in the same cache "way" > +bool CacheMemory::cacheAvail(const Address& address) const > +{ > + assert(address == line_address(address)); > + > + Index cacheSet = addressToCacheSet(address); > + > + for (int i=0; i < m_cache_assoc; i++) { > + AbstractCacheEntry* entry = m_cache[cacheSet][i]; > + if (entry != NULL) { > + if (entry->m_Address == address || // Already > in the cache > + entry->m_Permission == AccessPermission_NotPresent) { // We found > an empty entry > + return true; > + } > + } else { > + return true; > + } > + } > + return false; > +} > + > +void CacheMemory::allocate(const Address& address, AbstractCacheEntry* entry) > +{ > + assert(address == line_address(address)); > + assert(!isTagPresent(address)); > + assert(cacheAvail(address)); > + DEBUG_EXPR(CACHE_COMP, HighPrio, address); > + > + // Find the first open slot > + Index cacheSet = addressToCacheSet(address); > + for (int i=0; i < m_cache_assoc; i++) { > + if (m_cache[cacheSet][i] == NULL || > + m_cache[cacheSet][i]->m_Permission == AccessPermission_NotPresent) { > + m_cache[cacheSet][i] = entry; // Init entry > + m_cache[cacheSet][i]->m_Address = address; > + m_cache[cacheSet][i]->m_Permission = AccessPermission_Invalid; > + m_locked[cacheSet][i] = -1; > + > + m_replacementPolicy_ptr->touch(cacheSet, i, > g_eventQueue_ptr->getTime()); > + > + return; > + } > + } > + ERROR_MSG("Allocate didn't find an available entry"); > +} > + > +void CacheMemory::deallocate(const Address& address) > +{ > + assert(address == line_address(address)); > + assert(isTagPresent(address)); > + DEBUG_EXPR(CACHE_COMP, HighPrio, address); > + Index cacheSet = addressToCacheSet(address); > + int location = findTagInSet(cacheSet, address); > + if (location != -1){ > + delete m_cache[cacheSet][location]; > + m_cache[cacheSet][location] = NULL; > + m_locked[cacheSet][location] = -1; > + } > +} > + > +// Returns with the physical address of the conflicting cache line > +Address CacheMemory::cacheProbe(const Address& address) const > +{ > + assert(address == line_address(address)); > + assert(!cacheAvail(address)); > + > + Index cacheSet = addressToCacheSet(address); > + return > m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)]->m_Address; > _______________________________________________ > m5-dev mailing list > [email protected] > http://m5sim.org/mailman/listinfo/m5-dev > > _______________________________________________ m5-dev mailing list [email protected] http://m5sim.org/mailman/listinfo/m5-dev
