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
346797SN/APersistentTable::PersistentTable()
356791SN/A{
366791SN/A}
376791SN/A
386791SN/APersistentTable::~PersistentTable()
396791SN/A{
407054SN/A}
416791SN/A
427039SN/Avoid
4311025Snilay@cs.wisc.eduPersistentTable::persistentRequestLock(Addr address,
447039SN/A                                       MachineID locker,
457039SN/A                                       AccessType type)
466791SN/A{
4711025Snilay@cs.wisc.edu    assert(address == makeLineAddress(address));
487039SN/A
497455SN/A    static const PersistentTableEntry dflt;
507455SN/A    pair<AddressMap::iterator, bool> r =
517455SN/A        m_map.insert(AddressMap::value_type(address, dflt));
527455SN/A    bool present = !r.second;
537455SN/A    AddressMap::iterator i = r.first;
547455SN/A    PersistentTableEntry &entry = i->second;
557455SN/A
567455SN/A    if (present) {
577039SN/A        // Make sure we're not already in the locked set
587039SN/A        assert(!(entry.m_starving.isElement(locker)));
597455SN/A    }
607039SN/A
617455SN/A    entry.m_starving.add(locker);
627455SN/A    if (type == AccessType_Write)
637455SN/A        entry.m_request_to_write.add(locker);
647455SN/A
657455SN/A    if (present)
667039SN/A        assert(entry.m_marked.isSubset(entry.m_starving));
677039SN/A}
687039SN/A
697039SN/Avoid
7011025Snilay@cs.wisc.eduPersistentTable::persistentRequestUnlock(Addr address,
717039SN/A                                         MachineID unlocker)
727039SN/A{
7311025Snilay@cs.wisc.edu    assert(address == makeLineAddress(address));
747455SN/A    assert(m_map.count(address));
757455SN/A    PersistentTableEntry& entry = m_map[address];
766797SN/A
776797SN/A    //
787039SN/A    // Make sure we're in the locked set
796797SN/A    //
807039SN/A    assert(entry.m_starving.isElement(unlocker));
817039SN/A    assert(entry.m_marked.isSubset(entry.m_starving));
827039SN/A    entry.m_starving.remove(unlocker);
837039SN/A    entry.m_marked.remove(unlocker);
847039SN/A    entry.m_request_to_write.remove(unlocker);
857039SN/A    assert(entry.m_marked.isSubset(entry.m_starving));
866791SN/A
877039SN/A    // Deallocate if empty
887039SN/A    if (entry.m_starving.isEmpty()) {
897039SN/A        assert(entry.m_marked.isEmpty());
907455SN/A        m_map.erase(address);
916791SN/A    }
926791SN/A}
936791SN/A
947039SN/Abool
9511025Snilay@cs.wisc.eduPersistentTable::okToIssueStarving(Addr address,
967039SN/A                                   MachineID machId) const
976791SN/A{
9811025Snilay@cs.wisc.edu    assert(address == makeLineAddress(address));
997455SN/A
1007455SN/A    AddressMap::const_iterator i = m_map.find(address);
1017455SN/A    if (i == m_map.end()) {
1027039SN/A        // No entry present
1037039SN/A        return true;
1047455SN/A    }
1057455SN/A
1067455SN/A    const PersistentTableEntry &entry = i->second;
1077455SN/A
1087455SN/A    if (entry.m_starving.isElement(machId)) {
1097039SN/A        // We can't issue another lockdown until are previous unlock
1107039SN/A        // has occurred
1117039SN/A        return false;
1127039SN/A    }
1137455SN/A
1147455SN/A    return entry.m_marked.isEmpty();
1156791SN/A}
1166791SN/A
1177039SN/AMachineID
11811025Snilay@cs.wisc.eduPersistentTable::findSmallest(Addr address) const
1196791SN/A{
12011025Snilay@cs.wisc.edu    assert(address == makeLineAddress(address));
1217455SN/A    AddressMap::const_iterator i = m_map.find(address);
1227455SN/A    assert(i != m_map.end());
1237455SN/A    const PersistentTableEntry& entry = i->second;
1247039SN/A    return entry.m_starving.smallestElement();
1256791SN/A}
1266791SN/A
1277039SN/AAccessType
12811025Snilay@cs.wisc.eduPersistentTable::typeOfSmallest(Addr address) const
1296791SN/A{
13011025Snilay@cs.wisc.edu    assert(address == makeLineAddress(address));
1317455SN/A    AddressMap::const_iterator i = m_map.find(address);
1327455SN/A    assert(i != m_map.end());
1337455SN/A    const PersistentTableEntry& entry = i->second;
1347039SN/A    if (entry.m_request_to_write.
1357039SN/A        isElement(entry.m_starving.smallestElement())) {
1367039SN/A        return AccessType_Write;
1377039SN/A    } else {
1387039SN/A        return AccessType_Read;
1397039SN/A    }
1406791SN/A}
1416791SN/A
1427039SN/Avoid
14311025Snilay@cs.wisc.eduPersistentTable::markEntries(Addr address)
1446791SN/A{
14511025Snilay@cs.wisc.edu    assert(address == makeLineAddress(address));
1467455SN/A    AddressMap::iterator i = m_map.find(address);
1477455SN/A    if (i == m_map.end())
1487455SN/A        return;
1497039SN/A
1507455SN/A    PersistentTableEntry& entry = i->second;
1517039SN/A
1527455SN/A    // None should be marked
1537455SN/A    assert(entry.m_marked.isEmpty());
1547455SN/A
1557455SN/A    // Mark all the nodes currently in the table
1567455SN/A    entry.m_marked = entry.m_starving;
1576791SN/A}
1586791SN/A
1597039SN/Abool
16011025Snilay@cs.wisc.eduPersistentTable::isLocked(Addr address) const
1616791SN/A{
16211025Snilay@cs.wisc.edu    assert(address == makeLineAddress(address));
1636797SN/A
1647039SN/A    // If an entry is present, it must be locked
1657455SN/A    return m_map.count(address) > 0;
1666791SN/A}
1676791SN/A
1687039SN/Aint
16911025Snilay@cs.wisc.eduPersistentTable::countStarvingForAddress(Addr address) const
1706791SN/A{
17111025Snilay@cs.wisc.edu    assert(address == makeLineAddress(address));
1727455SN/A    AddressMap::const_iterator i = m_map.find(address);
1737455SN/A    if (i == m_map.end())
1747039SN/A        return 0;
1757455SN/A
1767455SN/A    const PersistentTableEntry& entry = i->second;
1777455SN/A    return entry.m_starving.count();
1786791SN/A}
1796791SN/A
1807039SN/Aint
18111025Snilay@cs.wisc.eduPersistentTable::countReadStarvingForAddress(Addr address) const
1826791SN/A{
18311025Snilay@cs.wisc.edu    assert(address == makeLineAddress(address));
1847455SN/A    AddressMap::const_iterator i = m_map.find(address);
1857455SN/A    if (i == m_map.end())
1867039SN/A        return 0;
1877455SN/A
1887455SN/A    const PersistentTableEntry& entry = i->second;
1897455SN/A    return entry.m_starving.count() - entry.m_request_to_write.count();
1906791SN/A}
1916791SN/A
1927039SN/Avoid
1937039SN/APersistentTable::print(ostream& out) const
1946797SN/A{
1956797SN/A}
1966791SN/A
197