PersistentTable.cc revision 11025
16791SN/A/* 26791SN/A * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 36791SN/A * All rights reserved. 46791SN/A * 56791SN/A * Redistribution and use in source and binary forms, with or without 66791SN/A * modification, are permitted provided that the following conditions are 76791SN/A * met: redistributions of source code must retain the above copyright 86791SN/A * notice, this list of conditions and the following disclaimer; 96791SN/A * redistributions in binary form must reproduce the above copyright 106791SN/A * notice, this list of conditions and the following disclaimer in the 116791SN/A * documentation and/or other materials provided with the distribution; 126791SN/A * neither the name of the copyright holders nor the names of its 136791SN/A * contributors may be used to endorse or promote products derived from 146791SN/A * this software without specific prior written permission. 156791SN/A * 166791SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176791SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186791SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196791SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206791SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216791SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226791SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236791SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246791SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256791SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266791SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276791SN/A */ 286791SN/A 2910301Snilay@cs.wisc.edu#include "mem/ruby/structures/PersistentTable.hh" 306791SN/A 317055SN/Ausing namespace std; 327055SN/A 336791SN/A// randomize so that handoffs are not locality-aware 347039SN/A#if 0 357039SN/Aint persistent_randomize[] = {0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 367039SN/A 10, 14, 3, 7, 11, 15}; 377039SN/Aint persistent_randomize[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 387039SN/A 10, 11, 12, 13, 14, 15}; 397039SN/A#endif 406791SN/A 416797SN/APersistentTable::PersistentTable() 426791SN/A{ 436791SN/A} 446791SN/A 456791SN/APersistentTable::~PersistentTable() 466791SN/A{ 477054SN/A} 486791SN/A 497039SN/Avoid 5011025Snilay@cs.wisc.eduPersistentTable::persistentRequestLock(Addr address, 517039SN/A MachineID locker, 527039SN/A AccessType type) 536791SN/A{ 547039SN/A#if 0 557039SN/A if (locker == m_chip_ptr->getID()) 567039SN/A cout << "Chip " << m_chip_ptr->getID() << ": " << llocker 577039SN/A << " requesting lock for " << address << endl; 586791SN/A 597039SN/A MachineID locker = (MachineID) persistent_randomize[llocker]; 607039SN/A#endif 616791SN/A 6211025Snilay@cs.wisc.edu assert(address == makeLineAddress(address)); 637039SN/A 647455SN/A static const PersistentTableEntry dflt; 657455SN/A pair<AddressMap::iterator, bool> r = 667455SN/A m_map.insert(AddressMap::value_type(address, dflt)); 677455SN/A bool present = !r.second; 687455SN/A AddressMap::iterator i = r.first; 697455SN/A PersistentTableEntry &entry = i->second; 707455SN/A 717455SN/A if (present) { 727039SN/A // Make sure we're not already in the locked set 737039SN/A assert(!(entry.m_starving.isElement(locker))); 747455SN/A } 757039SN/A 767455SN/A entry.m_starving.add(locker); 777455SN/A if (type == AccessType_Write) 787455SN/A entry.m_request_to_write.add(locker); 797455SN/A 807455SN/A if (present) 817039SN/A assert(entry.m_marked.isSubset(entry.m_starving)); 827039SN/A} 837039SN/A 847039SN/Avoid 8511025Snilay@cs.wisc.eduPersistentTable::persistentRequestUnlock(Addr address, 867039SN/A MachineID unlocker) 877039SN/A{ 887039SN/A#if 0 897039SN/A if (unlocker == m_chip_ptr->getID()) 907039SN/A cout << "Chip " << m_chip_ptr->getID() << ": " << uunlocker 917039SN/A << " requesting unlock for " << address << endl; 927039SN/A 937039SN/A MachineID unlocker = (MachineID) persistent_randomize[uunlocker]; 947039SN/A#endif 957039SN/A 9611025Snilay@cs.wisc.edu assert(address == makeLineAddress(address)); 977455SN/A assert(m_map.count(address)); 987455SN/A PersistentTableEntry& entry = m_map[address]; 996797SN/A 1006797SN/A // 1017039SN/A // Make sure we're in the locked set 1026797SN/A // 1037039SN/A assert(entry.m_starving.isElement(unlocker)); 1047039SN/A assert(entry.m_marked.isSubset(entry.m_starving)); 1057039SN/A entry.m_starving.remove(unlocker); 1067039SN/A entry.m_marked.remove(unlocker); 1077039SN/A entry.m_request_to_write.remove(unlocker); 1087039SN/A assert(entry.m_marked.isSubset(entry.m_starving)); 1096791SN/A 1107039SN/A // Deallocate if empty 1117039SN/A if (entry.m_starving.isEmpty()) { 1127039SN/A assert(entry.m_marked.isEmpty()); 1137455SN/A m_map.erase(address); 1146791SN/A } 1156791SN/A} 1166791SN/A 1177039SN/Abool 11811025Snilay@cs.wisc.eduPersistentTable::okToIssueStarving(Addr address, 1197039SN/A MachineID machId) const 1206791SN/A{ 12111025Snilay@cs.wisc.edu assert(address == makeLineAddress(address)); 1227455SN/A 1237455SN/A AddressMap::const_iterator i = m_map.find(address); 1247455SN/A if (i == m_map.end()) { 1257039SN/A // No entry present 1267039SN/A return true; 1277455SN/A } 1287455SN/A 1297455SN/A const PersistentTableEntry &entry = i->second; 1307455SN/A 1317455SN/A if (entry.m_starving.isElement(machId)) { 1327039SN/A // We can't issue another lockdown until are previous unlock 1337039SN/A // has occurred 1347039SN/A return false; 1357039SN/A } 1367455SN/A 1377455SN/A return entry.m_marked.isEmpty(); 1386791SN/A} 1396791SN/A 1407039SN/AMachineID 14111025Snilay@cs.wisc.eduPersistentTable::findSmallest(Addr address) const 1426791SN/A{ 14311025Snilay@cs.wisc.edu assert(address == makeLineAddress(address)); 1447455SN/A AddressMap::const_iterator i = m_map.find(address); 1457455SN/A assert(i != m_map.end()); 1467455SN/A const PersistentTableEntry& entry = i->second; 1477039SN/A return entry.m_starving.smallestElement(); 1486791SN/A} 1496791SN/A 1507039SN/AAccessType 15111025Snilay@cs.wisc.eduPersistentTable::typeOfSmallest(Addr address) const 1526791SN/A{ 15311025Snilay@cs.wisc.edu assert(address == makeLineAddress(address)); 1547455SN/A AddressMap::const_iterator i = m_map.find(address); 1557455SN/A assert(i != m_map.end()); 1567455SN/A const PersistentTableEntry& entry = i->second; 1577039SN/A if (entry.m_request_to_write. 1587039SN/A isElement(entry.m_starving.smallestElement())) { 1597039SN/A return AccessType_Write; 1607039SN/A } else { 1617039SN/A return AccessType_Read; 1627039SN/A } 1636791SN/A} 1646791SN/A 1657039SN/Avoid 16611025Snilay@cs.wisc.eduPersistentTable::markEntries(Addr address) 1676791SN/A{ 16811025Snilay@cs.wisc.edu assert(address == makeLineAddress(address)); 1697455SN/A AddressMap::iterator i = m_map.find(address); 1707455SN/A if (i == m_map.end()) 1717455SN/A return; 1727039SN/A 1737455SN/A PersistentTableEntry& entry = i->second; 1747039SN/A 1757455SN/A // None should be marked 1767455SN/A assert(entry.m_marked.isEmpty()); 1777455SN/A 1787455SN/A // Mark all the nodes currently in the table 1797455SN/A entry.m_marked = entry.m_starving; 1806791SN/A} 1816791SN/A 1827039SN/Abool 18311025Snilay@cs.wisc.eduPersistentTable::isLocked(Addr address) const 1846791SN/A{ 18511025Snilay@cs.wisc.edu assert(address == makeLineAddress(address)); 1866797SN/A 1877039SN/A // If an entry is present, it must be locked 1887455SN/A return m_map.count(address) > 0; 1896791SN/A} 1906791SN/A 1917039SN/Aint 19211025Snilay@cs.wisc.eduPersistentTable::countStarvingForAddress(Addr address) const 1936791SN/A{ 19411025Snilay@cs.wisc.edu assert(address == makeLineAddress(address)); 1957455SN/A AddressMap::const_iterator i = m_map.find(address); 1967455SN/A if (i == m_map.end()) 1977039SN/A return 0; 1987455SN/A 1997455SN/A const PersistentTableEntry& entry = i->second; 2007455SN/A return entry.m_starving.count(); 2016791SN/A} 2026791SN/A 2037039SN/Aint 20411025Snilay@cs.wisc.eduPersistentTable::countReadStarvingForAddress(Addr address) const 2056791SN/A{ 20611025Snilay@cs.wisc.edu assert(address == makeLineAddress(address)); 2077455SN/A AddressMap::const_iterator i = m_map.find(address); 2087455SN/A if (i == m_map.end()) 2097039SN/A return 0; 2107455SN/A 2117455SN/A const PersistentTableEntry& entry = i->second; 2127455SN/A return entry.m_starving.count() - entry.m_request_to_write.count(); 2136791SN/A} 2146791SN/A 2157039SN/Avoid 2167039SN/APersistentTable::print(ostream& out) const 2176797SN/A{ 2186797SN/A} 2196791SN/A 220