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 346797SN/APersistentTable::PersistentTable() 356791SN/A{ 366791SN/A} 376791SN/A 386791SN/APersistentTable::~PersistentTable() 396791SN/A{ 407054SN/A} 416791SN/A 427039SN/Avoid 4311025Snilay@cs.wisc.eduPersistentTable::persistentRequestLock(Addr address, 447039SN/A MachineID locker, 457039SN/A AccessType type) 466791SN/A{ 4711025Snilay@cs.wisc.edu assert(address == makeLineAddress(address)); 487039SN/A 497455SN/A static const PersistentTableEntry dflt; 507455SN/A pair<AddressMap::iterator, bool> r = 517455SN/A m_map.insert(AddressMap::value_type(address, dflt)); 527455SN/A bool present = !r.second; 537455SN/A AddressMap::iterator i = r.first; 547455SN/A PersistentTableEntry &entry = i->second; 557455SN/A 567455SN/A if (present) { 577039SN/A // Make sure we're not already in the locked set 587039SN/A assert(!(entry.m_starving.isElement(locker))); 597455SN/A } 607039SN/A 617455SN/A entry.m_starving.add(locker); 627455SN/A if (type == AccessType_Write) 637455SN/A entry.m_request_to_write.add(locker); 647455SN/A 657455SN/A if (present) 667039SN/A assert(entry.m_marked.isSubset(entry.m_starving)); 677039SN/A} 687039SN/A 697039SN/Avoid 7011025Snilay@cs.wisc.eduPersistentTable::persistentRequestUnlock(Addr address, 717039SN/A MachineID unlocker) 727039SN/A{ 7311025Snilay@cs.wisc.edu assert(address == makeLineAddress(address)); 747455SN/A assert(m_map.count(address)); 757455SN/A PersistentTableEntry& entry = m_map[address]; 766797SN/A 776797SN/A // 787039SN/A // Make sure we're in the locked set 796797SN/A // 807039SN/A assert(entry.m_starving.isElement(unlocker)); 817039SN/A assert(entry.m_marked.isSubset(entry.m_starving)); 827039SN/A entry.m_starving.remove(unlocker); 837039SN/A entry.m_marked.remove(unlocker); 847039SN/A entry.m_request_to_write.remove(unlocker); 857039SN/A assert(entry.m_marked.isSubset(entry.m_starving)); 866791SN/A 877039SN/A // Deallocate if empty 887039SN/A if (entry.m_starving.isEmpty()) { 897039SN/A assert(entry.m_marked.isEmpty()); 907455SN/A m_map.erase(address); 916791SN/A } 926791SN/A} 936791SN/A 947039SN/Abool 9511025Snilay@cs.wisc.eduPersistentTable::okToIssueStarving(Addr address, 967039SN/A MachineID machId) const 976791SN/A{ 9811025Snilay@cs.wisc.edu assert(address == makeLineAddress(address)); 997455SN/A 1007455SN/A AddressMap::const_iterator i = m_map.find(address); 1017455SN/A if (i == m_map.end()) { 1027039SN/A // No entry present 1037039SN/A return true; 1047455SN/A } 1057455SN/A 1067455SN/A const PersistentTableEntry &entry = i->second; 1077455SN/A 1087455SN/A if (entry.m_starving.isElement(machId)) { 1097039SN/A // We can't issue another lockdown until are previous unlock 1107039SN/A // has occurred 1117039SN/A return false; 1127039SN/A } 1137455SN/A 1147455SN/A return entry.m_marked.isEmpty(); 1156791SN/A} 1166791SN/A 1177039SN/AMachineID 11811025Snilay@cs.wisc.eduPersistentTable::findSmallest(Addr address) const 1196791SN/A{ 12011025Snilay@cs.wisc.edu assert(address == makeLineAddress(address)); 1217455SN/A AddressMap::const_iterator i = m_map.find(address); 1227455SN/A assert(i != m_map.end()); 1237455SN/A const PersistentTableEntry& entry = i->second; 1247039SN/A return entry.m_starving.smallestElement(); 1256791SN/A} 1266791SN/A 1277039SN/AAccessType 12811025Snilay@cs.wisc.eduPersistentTable::typeOfSmallest(Addr address) const 1296791SN/A{ 13011025Snilay@cs.wisc.edu assert(address == makeLineAddress(address)); 1317455SN/A AddressMap::const_iterator i = m_map.find(address); 1327455SN/A assert(i != m_map.end()); 1337455SN/A const PersistentTableEntry& entry = i->second; 1347039SN/A if (entry.m_request_to_write. 1357039SN/A isElement(entry.m_starving.smallestElement())) { 1367039SN/A return AccessType_Write; 1377039SN/A } else { 1387039SN/A return AccessType_Read; 1397039SN/A } 1406791SN/A} 1416791SN/A 1427039SN/Avoid 14311025Snilay@cs.wisc.eduPersistentTable::markEntries(Addr address) 1446791SN/A{ 14511025Snilay@cs.wisc.edu assert(address == makeLineAddress(address)); 1467455SN/A AddressMap::iterator i = m_map.find(address); 1477455SN/A if (i == m_map.end()) 1487455SN/A return; 1497039SN/A 1507455SN/A PersistentTableEntry& entry = i->second; 1517039SN/A 1527455SN/A // None should be marked 1537455SN/A assert(entry.m_marked.isEmpty()); 1547455SN/A 1557455SN/A // Mark all the nodes currently in the table 1567455SN/A entry.m_marked = entry.m_starving; 1576791SN/A} 1586791SN/A 1597039SN/Abool 16011025Snilay@cs.wisc.eduPersistentTable::isLocked(Addr address) const 1616791SN/A{ 16211025Snilay@cs.wisc.edu assert(address == makeLineAddress(address)); 1636797SN/A 1647039SN/A // If an entry is present, it must be locked 1657455SN/A return m_map.count(address) > 0; 1666791SN/A} 1676791SN/A 1687039SN/Aint 16911025Snilay@cs.wisc.eduPersistentTable::countStarvingForAddress(Addr address) const 1706791SN/A{ 17111025Snilay@cs.wisc.edu assert(address == makeLineAddress(address)); 1727455SN/A AddressMap::const_iterator i = m_map.find(address); 1737455SN/A if (i == m_map.end()) 1747039SN/A return 0; 1757455SN/A 1767455SN/A const PersistentTableEntry& entry = i->second; 1777455SN/A return entry.m_starving.count(); 1786791SN/A} 1796791SN/A 1807039SN/Aint 18111025Snilay@cs.wisc.eduPersistentTable::countReadStarvingForAddress(Addr address) const 1826791SN/A{ 18311025Snilay@cs.wisc.edu assert(address == makeLineAddress(address)); 1847455SN/A AddressMap::const_iterator i = m_map.find(address); 1857455SN/A if (i == m_map.end()) 1867039SN/A return 0; 1877455SN/A 1887455SN/A const PersistentTableEntry& entry = i->second; 1897455SN/A return entry.m_starving.count() - entry.m_request_to_write.count(); 1906791SN/A} 1916791SN/A 1927039SN/Avoid 1937039SN/APersistentTable::print(ostream& out) const 1946797SN/A{ 1956797SN/A} 1966791SN/A 197