PersistentTable.cc revision 6797
16899SN/A 28851Sandreas.hansson@arm.com/* 38851Sandreas.hansson@arm.com * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 48851Sandreas.hansson@arm.com * All rights reserved. 58851Sandreas.hansson@arm.com * 68851Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 78851Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 88851Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 98851Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 108851Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 118851Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 128851Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 138851Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 146899SN/A * contributors may be used to endorse or promote products derived from 157553SN/A * this software without specific prior written permission. 166899SN/A * 176899SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 186899SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 196899SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 206899SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 216899SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 226899SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 236899SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 246899SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 256899SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 266899SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 276899SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 286899SN/A */ 296899SN/A 306899SN/A#include "mem/ruby/system/PersistentTable.hh" 316899SN/A#include "mem/gems_common/util.hh" 326899SN/A 336899SN/A// randomize so that handoffs are not locality-aware 346899SN/A// int persistent_randomize[] = {0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15}; 356899SN/A// int persistent_randomize[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; 366899SN/A 376899SN/A 386899SN/APersistentTable::PersistentTable() 396899SN/A{ 406899SN/A m_map_ptr = new Map<Address, PersistentTableEntry>; 416899SN/A} 4211793Sbrandon.potter@amd.com 4311793Sbrandon.potter@amd.comPersistentTable::~PersistentTable() 4411800Sbrandon.potter@amd.com{ 457632SBrad.Beckmann@amd.com delete m_map_ptr; 468232Snate@binkert.org m_map_ptr = NULL; 476899SN/A} 486899SN/A 497553SN/Avoid PersistentTable::persistentRequestLock(const Address& address, 5013892Sgabeblack@google.com MachineID locker, 5112129Sspwilson2@wisc.edu AccessType type) 5212129Sspwilson2@wisc.edu{ 537553SN/A 547553SN/A // if (locker == m_chip_ptr->getID() ) 556899SN/A // cout << "Chip " << m_chip_ptr->getID() << ": " << llocker 567553SN/A // << " requesting lock for " << address << endl; 576899SN/A 588851Sandreas.hansson@arm.com // MachineID locker = (MachineID) persistent_randomize[llocker]; 598851Sandreas.hansson@arm.com 608851Sandreas.hansson@arm.com assert(address == line_address(address)); 618851Sandreas.hansson@arm.com if (!m_map_ptr->exist(address)) { 628851Sandreas.hansson@arm.com // Allocate if not present 638851Sandreas.hansson@arm.com PersistentTableEntry entry; 647053SN/A entry.m_starving.add(locker); 657553SN/A if (type == AccessType_Write) { 666899SN/A entry.m_request_to_write.add(locker); 676899SN/A } 687553SN/A m_map_ptr->add(address, entry); 696899SN/A } else { 707053SN/A PersistentTableEntry& entry = m_map_ptr->lookup(address); 717053SN/A 726899SN/A // 736899SN/A // Make sure we're not already in the locked set 747053SN/A // 757553SN/A assert(!(entry.m_starving.isElement(locker))); 766899SN/A 777053SN/A entry.m_starving.add(locker); 787553SN/A if (type == AccessType_Write) { 796899SN/A entry.m_request_to_write.add(locker); 806899SN/A } 8113784Sgabeblack@google.com assert(entry.m_marked.isSubset(entry.m_starving)); 8213784Sgabeblack@google.com } 836899SN/A} 846899SN/A 858922Swilliam.wang@arm.comvoid PersistentTable::persistentRequestUnlock(const Address& address, 8613892Sgabeblack@google.com MachineID unlocker) 878922Swilliam.wang@arm.com{ 888922Swilliam.wang@arm.com // if (unlocker == m_chip_ptr->getID() ) 8913784Sgabeblack@google.com // cout << "Chip " << m_chip_ptr->getID() << ": " << uunlocker 908922Swilliam.wang@arm.com // << " requesting unlock for " << address << endl; 918922Swilliam.wang@arm.com 928922Swilliam.wang@arm.com // MachineID unlocker = (MachineID) persistent_randomize[uunlocker]; 936899SN/A 946899SN/A assert(address == line_address(address)); 956899SN/A assert(m_map_ptr->exist(address)); 966899SN/A PersistentTableEntry& entry = m_map_ptr->lookup(address); 978975Sandreas.hansson@arm.com 986899SN/A // 998965Sandreas.hansson@arm.com // Make sure we're in the locked set 10011320Ssteve.reinhardt@amd.com // 1017553SN/A assert(entry.m_starving.isElement(unlocker)); 1027553SN/A assert(entry.m_marked.isSubset(entry.m_starving)); 1037553SN/A entry.m_starving.remove(unlocker); 1047053SN/A entry.m_marked.remove(unlocker); 1057053SN/A entry.m_request_to_write.remove(unlocker); 1066899SN/A assert(entry.m_marked.isSubset(entry.m_starving)); 1076899SN/A 1088922Swilliam.wang@arm.com // Deallocate if empty 1097553SN/A if (entry.m_starving.isEmpty()) { 1106899SN/A assert(entry.m_marked.isEmpty()); 1117053SN/A m_map_ptr->erase(address); 1126899SN/A } 1137053SN/A} 1146899SN/A 1156899SN/Abool PersistentTable::okToIssueStarving(const Address& address, 1167053SN/A MachineID machId) const 1177553SN/A{ 1186899SN/A assert(address == line_address(address)); 1197553SN/A if (!m_map_ptr->exist(address)) { 1207553SN/A // 1217553SN/A // No entry present 1227553SN/A // 1236899SN/A return true; 12411320Ssteve.reinhardt@amd.com } else if (m_map_ptr->lookup(address).m_starving.isElement(machId)) { 1257823Ssteve.reinhardt@amd.com // 1266899SN/A // We can't issue another lockdown until are previous unlock has occurred 1276899SN/A // 1287053SN/A return false; 1297553SN/A } else { 1307053SN/A return (m_map_ptr->lookup(address).m_marked.isEmpty()); 1317553SN/A } 1327553SN/A} 1337823Ssteve.reinhardt@amd.com 1347553SN/AMachineID PersistentTable::findSmallest(const Address& address) const 1357053SN/A{ 1367553SN/A assert(address == line_address(address)); 1377053SN/A assert(m_map_ptr->exist(address)); 1386899SN/A const PersistentTableEntry& entry = m_map_ptr->lookup(address); 1396899SN/A return entry.m_starving.smallestElement(); 1407553SN/A} 1417553SN/A 1426899SN/AAccessType PersistentTable::typeOfSmallest(const Address& address) const 1437553SN/A{ 1446899SN/A assert(address == line_address(address)); 145 assert(m_map_ptr->exist(address)); 146 const PersistentTableEntry& entry = m_map_ptr->lookup(address); 147 if (entry.m_request_to_write.isElement(entry.m_starving.smallestElement())) { 148 return AccessType_Write; 149 } else { 150 return AccessType_Read; 151 } 152} 153 154void PersistentTable::markEntries(const Address& address) 155{ 156 assert(address == line_address(address)); 157 if (m_map_ptr->exist(address)) { 158 PersistentTableEntry& entry = m_map_ptr->lookup(address); 159 160 // 161 // None should be marked 162 // 163 assert(entry.m_marked.isEmpty()); 164 165 // 166 // Mark all the nodes currently in the table 167 // 168 entry.m_marked = entry.m_starving; 169 } 170} 171 172bool PersistentTable::isLocked(const Address& address) const 173{ 174 assert(address == line_address(address)); 175 // If an entry is present, it must be locked 176 return (m_map_ptr->exist(address)); 177} 178 179int PersistentTable::countStarvingForAddress(const Address& address) const 180{ 181 if (m_map_ptr->exist(address)) { 182 PersistentTableEntry& entry = m_map_ptr->lookup(address); 183 return (entry.m_starving.count()); 184 } 185 else { 186 return 0; 187 } 188} 189 190int PersistentTable::countReadStarvingForAddress(const Address& address) const 191{ 192 if (m_map_ptr->exist(address)) { 193 PersistentTableEntry& entry = m_map_ptr->lookup(address); 194 return (entry.m_starving.count() - entry.m_request_to_write.count()); 195 } 196 else { 197 return 0; 198 } 199} 200 201void PersistentTable::print(ostream& out) const 202{ 203} 204 205