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