PersistentTable.cc revision 11025
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// randomize so that handoffs are not locality-aware
347039SN/A#if 0
357039SN/Aint persistent_randomize[] = {0, 4, 8, 12, 1, 5, 9, 13, 2, 6,
367039SN/A                              10, 14, 3, 7, 11, 15};
377039SN/Aint persistent_randomize[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
387039SN/A                              10, 11, 12, 13, 14, 15};
397039SN/A#endif
406791SN/A
416797SN/APersistentTable::PersistentTable()
426791SN/A{
436791SN/A}
446791SN/A
456791SN/APersistentTable::~PersistentTable()
466791SN/A{
477054SN/A}
486791SN/A
497039SN/Avoid
5011025Snilay@cs.wisc.eduPersistentTable::persistentRequestLock(Addr address,
517039SN/A                                       MachineID locker,
527039SN/A                                       AccessType type)
536791SN/A{
547039SN/A#if 0
557039SN/A    if (locker == m_chip_ptr->getID())
567039SN/A        cout << "Chip " << m_chip_ptr->getID() << ": " << llocker
577039SN/A             << " requesting lock for " << address << endl;
586791SN/A
597039SN/A    MachineID locker = (MachineID) persistent_randomize[llocker];
607039SN/A#endif
616791SN/A
6211025Snilay@cs.wisc.edu    assert(address == makeLineAddress(address));
637039SN/A
647455SN/A    static const PersistentTableEntry dflt;
657455SN/A    pair<AddressMap::iterator, bool> r =
667455SN/A        m_map.insert(AddressMap::value_type(address, dflt));
677455SN/A    bool present = !r.second;
687455SN/A    AddressMap::iterator i = r.first;
697455SN/A    PersistentTableEntry &entry = i->second;
707455SN/A
717455SN/A    if (present) {
727039SN/A        // Make sure we're not already in the locked set
737039SN/A        assert(!(entry.m_starving.isElement(locker)));
747455SN/A    }
757039SN/A
767455SN/A    entry.m_starving.add(locker);
777455SN/A    if (type == AccessType_Write)
787455SN/A        entry.m_request_to_write.add(locker);
797455SN/A
807455SN/A    if (present)
817039SN/A        assert(entry.m_marked.isSubset(entry.m_starving));
827039SN/A}
837039SN/A
847039SN/Avoid
8511025Snilay@cs.wisc.eduPersistentTable::persistentRequestUnlock(Addr address,
867039SN/A                                         MachineID unlocker)
877039SN/A{
887039SN/A#if 0
897039SN/A    if (unlocker == m_chip_ptr->getID())
907039SN/A        cout << "Chip " << m_chip_ptr->getID() << ": " << uunlocker
917039SN/A             << " requesting unlock for " << address << endl;
927039SN/A
937039SN/A    MachineID unlocker = (MachineID) persistent_randomize[uunlocker];
947039SN/A#endif
957039SN/A
9611025Snilay@cs.wisc.edu    assert(address == makeLineAddress(address));
977455SN/A    assert(m_map.count(address));
987455SN/A    PersistentTableEntry& entry = m_map[address];
996797SN/A
1006797SN/A    //
1017039SN/A    // Make sure we're in the locked set
1026797SN/A    //
1037039SN/A    assert(entry.m_starving.isElement(unlocker));
1047039SN/A    assert(entry.m_marked.isSubset(entry.m_starving));
1057039SN/A    entry.m_starving.remove(unlocker);
1067039SN/A    entry.m_marked.remove(unlocker);
1077039SN/A    entry.m_request_to_write.remove(unlocker);
1087039SN/A    assert(entry.m_marked.isSubset(entry.m_starving));
1096791SN/A
1107039SN/A    // Deallocate if empty
1117039SN/A    if (entry.m_starving.isEmpty()) {
1127039SN/A        assert(entry.m_marked.isEmpty());
1137455SN/A        m_map.erase(address);
1146791SN/A    }
1156791SN/A}
1166791SN/A
1177039SN/Abool
11811025Snilay@cs.wisc.eduPersistentTable::okToIssueStarving(Addr address,
1197039SN/A                                   MachineID machId) const
1206791SN/A{
12111025Snilay@cs.wisc.edu    assert(address == makeLineAddress(address));
1227455SN/A
1237455SN/A    AddressMap::const_iterator i = m_map.find(address);
1247455SN/A    if (i == m_map.end()) {
1257039SN/A        // No entry present
1267039SN/A        return true;
1277455SN/A    }
1287455SN/A
1297455SN/A    const PersistentTableEntry &entry = i->second;
1307455SN/A
1317455SN/A    if (entry.m_starving.isElement(machId)) {
1327039SN/A        // We can't issue another lockdown until are previous unlock
1337039SN/A        // has occurred
1347039SN/A        return false;
1357039SN/A    }
1367455SN/A
1377455SN/A    return entry.m_marked.isEmpty();
1386791SN/A}
1396791SN/A
1407039SN/AMachineID
14111025Snilay@cs.wisc.eduPersistentTable::findSmallest(Addr address) const
1426791SN/A{
14311025Snilay@cs.wisc.edu    assert(address == makeLineAddress(address));
1447455SN/A    AddressMap::const_iterator i = m_map.find(address);
1457455SN/A    assert(i != m_map.end());
1467455SN/A    const PersistentTableEntry& entry = i->second;
1477039SN/A    return entry.m_starving.smallestElement();
1486791SN/A}
1496791SN/A
1507039SN/AAccessType
15111025Snilay@cs.wisc.eduPersistentTable::typeOfSmallest(Addr address) const
1526791SN/A{
15311025Snilay@cs.wisc.edu    assert(address == makeLineAddress(address));
1547455SN/A    AddressMap::const_iterator i = m_map.find(address);
1557455SN/A    assert(i != m_map.end());
1567455SN/A    const PersistentTableEntry& entry = i->second;
1577039SN/A    if (entry.m_request_to_write.
1587039SN/A        isElement(entry.m_starving.smallestElement())) {
1597039SN/A        return AccessType_Write;
1607039SN/A    } else {
1617039SN/A        return AccessType_Read;
1627039SN/A    }
1636791SN/A}
1646791SN/A
1657039SN/Avoid
16611025Snilay@cs.wisc.eduPersistentTable::markEntries(Addr address)
1676791SN/A{
16811025Snilay@cs.wisc.edu    assert(address == makeLineAddress(address));
1697455SN/A    AddressMap::iterator i = m_map.find(address);
1707455SN/A    if (i == m_map.end())
1717455SN/A        return;
1727039SN/A
1737455SN/A    PersistentTableEntry& entry = i->second;
1747039SN/A
1757455SN/A    // None should be marked
1767455SN/A    assert(entry.m_marked.isEmpty());
1777455SN/A
1787455SN/A    // Mark all the nodes currently in the table
1797455SN/A    entry.m_marked = entry.m_starving;
1806791SN/A}
1816791SN/A
1827039SN/Abool
18311025Snilay@cs.wisc.eduPersistentTable::isLocked(Addr address) const
1846791SN/A{
18511025Snilay@cs.wisc.edu    assert(address == makeLineAddress(address));
1866797SN/A
1877039SN/A    // If an entry is present, it must be locked
1887455SN/A    return m_map.count(address) > 0;
1896791SN/A}
1906791SN/A
1917039SN/Aint
19211025Snilay@cs.wisc.eduPersistentTable::countStarvingForAddress(Addr address) const
1936791SN/A{
19411025Snilay@cs.wisc.edu    assert(address == makeLineAddress(address));
1957455SN/A    AddressMap::const_iterator i = m_map.find(address);
1967455SN/A    if (i == m_map.end())
1977039SN/A        return 0;
1987455SN/A
1997455SN/A    const PersistentTableEntry& entry = i->second;
2007455SN/A    return entry.m_starving.count();
2016791SN/A}
2026791SN/A
2037039SN/Aint
20411025Snilay@cs.wisc.eduPersistentTable::countReadStarvingForAddress(Addr address) const
2056791SN/A{
20611025Snilay@cs.wisc.edu    assert(address == makeLineAddress(address));
2077455SN/A    AddressMap::const_iterator i = m_map.find(address);
2087455SN/A    if (i == m_map.end())
2097039SN/A        return 0;
2107455SN/A
2117455SN/A    const PersistentTableEntry& entry = i->second;
2127455SN/A    return entry.m_starving.count() - entry.m_request_to_write.count();
2136791SN/A}
2146791SN/A
2157039SN/Avoid
2167039SN/APersistentTable::print(ostream& out) const
2176797SN/A{
2186797SN/A}
2196791SN/A
220