PersistentTable.cc revision 6797
12155SN/A 22155SN/A/* 32155SN/A * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 42155SN/A * All rights reserved. 52155SN/A * 62155SN/A * Redistribution and use in source and binary forms, with or without 72155SN/A * modification, are permitted provided that the following conditions are 82155SN/A * met: redistributions of source code must retain the above copyright 92155SN/A * notice, this list of conditions and the following disclaimer; 102155SN/A * redistributions in binary form must reproduce the above copyright 112155SN/A * notice, this list of conditions and the following disclaimer in the 122155SN/A * documentation and/or other materials provided with the distribution; 132155SN/A * neither the name of the copyright holders nor the names of its 142155SN/A * contributors may be used to endorse or promote products derived from 152155SN/A * this software without specific prior written permission. 162155SN/A * 172155SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 182155SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 192155SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 202155SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 212155SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 222155SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 232155SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 242155SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 252155SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 262155SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 272155SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282665Ssaidi@eecs.umich.edu */ 292665Ssaidi@eecs.umich.edu 302155SN/A#include "mem/ruby/system/PersistentTable.hh" 314202Sbinkertn@umich.edu#include "mem/gems_common/util.hh" 322155SN/A 337768SAli.Saidi@ARM.com// randomize so that handoffs are not locality-aware 347768SAli.Saidi@ARM.com// int persistent_randomize[] = {0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15}; 357768SAli.Saidi@ARM.com// int persistent_randomize[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; 362178SN/A 372178SN/A 382178SN/APersistentTable::PersistentTable() 392178SN/A{ 402178SN/A m_map_ptr = new Map<Address, PersistentTableEntry>; 412178SN/A} 422178SN/A 432178SN/APersistentTable::~PersistentTable() 442178SN/A{ 452178SN/A delete m_map_ptr; 462178SN/A m_map_ptr = NULL; 472155SN/A} 485865Sksewell@umich.edu 496181Sksewell@umich.eduvoid PersistentTable::persistentRequestLock(const Address& address, 506181Sksewell@umich.edu MachineID locker, 515865Sksewell@umich.edu AccessType type) 523918Ssaidi@eecs.umich.edu{ 535865Sksewell@umich.edu 542623SN/A // if (locker == m_chip_ptr->getID() ) 553918Ssaidi@eecs.umich.edu // cout << "Chip " << m_chip_ptr->getID() << ": " << llocker 562155SN/A // << " requesting lock for " << address << endl; 572155SN/A 582292SN/A // MachineID locker = (MachineID) persistent_randomize[llocker]; 596181Sksewell@umich.edu 606181Sksewell@umich.edu assert(address == line_address(address)); 613918Ssaidi@eecs.umich.edu if (!m_map_ptr->exist(address)) { 622292SN/A // Allocate if not present 632292SN/A PersistentTableEntry entry; 642292SN/A entry.m_starving.add(locker); 653918Ssaidi@eecs.umich.edu if (type == AccessType_Write) { 662292SN/A entry.m_request_to_write.add(locker); 672292SN/A } 682766Sktlim@umich.edu m_map_ptr->add(address, entry); 692766Sktlim@umich.edu } else { 702766Sktlim@umich.edu PersistentTableEntry& entry = m_map_ptr->lookup(address); 712921Sktlim@umich.edu 722921Sktlim@umich.edu // 732766Sktlim@umich.edu // Make sure we're not already in the locked set 742766Sktlim@umich.edu // 755529Snate@binkert.org assert(!(entry.m_starving.isElement(locker))); 762766Sktlim@umich.edu 774762Snate@binkert.org entry.m_starving.add(locker); 782155SN/A if (type == AccessType_Write) { 792155SN/A entry.m_request_to_write.add(locker); 802155SN/A } 812155SN/A assert(entry.m_marked.isSubset(entry.m_starving)); 822155SN/A } 832155SN/A} 842766Sktlim@umich.edu 852155SN/Avoid PersistentTable::persistentRequestUnlock(const Address& address, 865865Sksewell@umich.edu MachineID unlocker) 872155SN/A{ 882155SN/A // if (unlocker == m_chip_ptr->getID() ) 892155SN/A // cout << "Chip " << m_chip_ptr->getID() << ": " << uunlocker 902155SN/A // << " requesting unlock for " << address << endl; 912178SN/A 922178SN/A // MachineID unlocker = (MachineID) persistent_randomize[uunlocker]; 937756SAli.Saidi@ARM.com 942766Sktlim@umich.edu assert(address == line_address(address)); 952178SN/A assert(m_map_ptr->exist(address)); 962178SN/A PersistentTableEntry& entry = m_map_ptr->lookup(address); 976994Snate@binkert.org 982178SN/A // 992766Sktlim@umich.edu // Make sure we're in the locked set 1002766Sktlim@umich.edu // 1012766Sktlim@umich.edu assert(entry.m_starving.isElement(unlocker)); 1022788Sktlim@umich.edu assert(entry.m_marked.isSubset(entry.m_starving)); 1032178SN/A entry.m_starving.remove(unlocker); 1042733Sktlim@umich.edu entry.m_marked.remove(unlocker); 1052733Sktlim@umich.edu entry.m_request_to_write.remove(unlocker); 1062817Sksewell@umich.edu assert(entry.m_marked.isSubset(entry.m_starving)); 1072733Sktlim@umich.edu 1084486Sbinkertn@umich.edu // Deallocate if empty 1094486Sbinkertn@umich.edu if (entry.m_starving.isEmpty()) { 1104776Sgblack@eecs.umich.edu assert(entry.m_marked.isEmpty()); 1114776Sgblack@eecs.umich.edu m_map_ptr->erase(address); 1128739Sgblack@eecs.umich.edu } 1136365Sgblack@eecs.umich.edu} 1144486Sbinkertn@umich.edu 1154202Sbinkertn@umich.edubool PersistentTable::okToIssueStarving(const Address& address, 1164202Sbinkertn@umich.edu MachineID machId) const 1174202Sbinkertn@umich.edu{ 1188541Sgblack@eecs.umich.edu assert(address == line_address(address)); 1194202Sbinkertn@umich.edu if (!m_map_ptr->exist(address)) { 1204202Sbinkertn@umich.edu // 1214776Sgblack@eecs.umich.edu // No entry present 1228739Sgblack@eecs.umich.edu // 1236365Sgblack@eecs.umich.edu return true; 1244202Sbinkertn@umich.edu } else if (m_map_ptr->lookup(address).m_starving.isElement(machId)) { 1258777Sgblack@eecs.umich.edu // 1264202Sbinkertn@umich.edu // We can't issue another lockdown until are previous unlock has occurred 1274202Sbinkertn@umich.edu // 1284202Sbinkertn@umich.edu return false; 1295217Ssaidi@eecs.umich.edu } else { 1304202Sbinkertn@umich.edu return (m_map_ptr->lookup(address).m_marked.isEmpty()); 1312155SN/A } 1324202Sbinkertn@umich.edu} 1334776Sgblack@eecs.umich.edu 1344776Sgblack@eecs.umich.eduMachineID PersistentTable::findSmallest(const Address& address) const 1354776Sgblack@eecs.umich.edu{ 1364776Sgblack@eecs.umich.edu assert(address == line_address(address)); 1372766Sktlim@umich.edu assert(m_map_ptr->exist(address)); 1384202Sbinkertn@umich.edu const PersistentTableEntry& entry = m_map_ptr->lookup(address); 1398335Snate@binkert.org return entry.m_starving.smallestElement(); 1402733Sktlim@umich.edu} 1412733Sktlim@umich.edu 1422733Sktlim@umich.eduAccessType PersistentTable::typeOfSmallest(const Address& address) const 1432733Sktlim@umich.edu{ 1442733Sktlim@umich.edu assert(address == line_address(address)); 1452874Sktlim@umich.edu assert(m_map_ptr->exist(address)); 1462874Sktlim@umich.edu const PersistentTableEntry& entry = m_map_ptr->lookup(address); 1472874Sktlim@umich.edu if (entry.m_request_to_write.isElement(entry.m_starving.smallestElement())) { 1484202Sbinkertn@umich.edu return AccessType_Write; 1492733Sktlim@umich.edu } else { 1505192Ssaidi@eecs.umich.edu return AccessType_Read; 1518335Snate@binkert.org } 1528335Snate@binkert.org} 1538335Snate@binkert.org 1548335Snate@binkert.orgvoid PersistentTable::markEntries(const Address& address) 1558335Snate@binkert.org{ 1568335Snate@binkert.org assert(address == line_address(address)); 1578335Snate@binkert.org if (m_map_ptr->exist(address)) { 1588335Snate@binkert.org PersistentTableEntry& entry = m_map_ptr->lookup(address); 1598335Snate@binkert.org 1608335Snate@binkert.org // 1618335Snate@binkert.org // None should be marked 1628335Snate@binkert.org // 1638335Snate@binkert.org assert(entry.m_marked.isEmpty()); 1648335Snate@binkert.org 1658335Snate@binkert.org // 1668335Snate@binkert.org // Mark all the nodes currently in the table 1678335Snate@binkert.org // 1688335Snate@binkert.org entry.m_marked = entry.m_starving; 1698335Snate@binkert.org } 1708335Snate@binkert.org} 1718335Snate@binkert.org 1728335Snate@binkert.orgbool PersistentTable::isLocked(const Address& address) const 1738335Snate@binkert.org{ 1748335Snate@binkert.org assert(address == line_address(address)); 1758471SGiacomo.Gabrielli@arm.com // If an entry is present, it must be locked 1768335Snate@binkert.org return (m_map_ptr->exist(address)); 1778335Snate@binkert.org} 1785192Ssaidi@eecs.umich.edu 1798232Snate@binkert.orgint PersistentTable::countStarvingForAddress(const Address& address) const 1808232Snate@binkert.org{ 1818232Snate@binkert.org if (m_map_ptr->exist(address)) { 1828300Schander.sudanthi@arm.com PersistentTableEntry& entry = m_map_ptr->lookup(address); 1838300Schander.sudanthi@arm.com return (entry.m_starving.count()); 1845192Ssaidi@eecs.umich.edu } 1858300Schander.sudanthi@arm.com else { 1868300Schander.sudanthi@arm.com return 0; 1876036Sksewell@umich.edu } 1888300Schander.sudanthi@arm.com} 1898300Schander.sudanthi@arm.com 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