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