2 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include "mem/ruby/system/PersistentTable.hh"
33 // randomize so that handoffs are not locality-aware
35 int persistent_randomize
[] = {0, 4, 8, 12, 1, 5, 9, 13, 2, 6,
36 10, 14, 3, 7, 11, 15};
37 int persistent_randomize
[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
38 10, 11, 12, 13, 14, 15};
41 PersistentTable::PersistentTable()
45 PersistentTable::~PersistentTable()
50 PersistentTable::persistentRequestLock(const Address
& address
,
55 if (locker
== m_chip_ptr
->getID())
56 cout
<< "Chip " << m_chip_ptr
->getID() << ": " << llocker
57 << " requesting lock for " << address
<< endl
;
59 MachineID locker
= (MachineID
) persistent_randomize
[llocker
];
62 assert(address
== line_address(address
));
64 static const PersistentTableEntry dflt
;
65 pair
<AddressMap::iterator
, bool> r
=
66 m_map
.insert(AddressMap::value_type(address
, dflt
));
67 bool present
= !r
.second
;
68 AddressMap::iterator i
= r
.first
;
69 PersistentTableEntry
&entry
= i
->second
;
72 // Make sure we're not already in the locked set
73 assert(!(entry
.m_starving
.isElement(locker
)));
76 entry
.m_starving
.add(locker
);
77 if (type
== AccessType_Write
)
78 entry
.m_request_to_write
.add(locker
);
81 assert(entry
.m_marked
.isSubset(entry
.m_starving
));
85 PersistentTable::persistentRequestUnlock(const Address
& address
,
89 if (unlocker
== m_chip_ptr
->getID())
90 cout
<< "Chip " << m_chip_ptr
->getID() << ": " << uunlocker
91 << " requesting unlock for " << address
<< endl
;
93 MachineID unlocker
= (MachineID
) persistent_randomize
[uunlocker
];
96 assert(address
== line_address(address
));
97 assert(m_map
.count(address
));
98 PersistentTableEntry
& entry
= m_map
[address
];
101 // Make sure we're in the locked set
103 assert(entry
.m_starving
.isElement(unlocker
));
104 assert(entry
.m_marked
.isSubset(entry
.m_starving
));
105 entry
.m_starving
.remove(unlocker
);
106 entry
.m_marked
.remove(unlocker
);
107 entry
.m_request_to_write
.remove(unlocker
);
108 assert(entry
.m_marked
.isSubset(entry
.m_starving
));
110 // Deallocate if empty
111 if (entry
.m_starving
.isEmpty()) {
112 assert(entry
.m_marked
.isEmpty());
113 m_map
.erase(address
);
118 PersistentTable::okToIssueStarving(const Address
& address
,
119 MachineID machId
) const
121 assert(address
== line_address(address
));
123 AddressMap::const_iterator i
= m_map
.find(address
);
124 if (i
== m_map
.end()) {
129 const PersistentTableEntry
&entry
= i
->second
;
131 if (entry
.m_starving
.isElement(machId
)) {
132 // We can't issue another lockdown until are previous unlock
137 return entry
.m_marked
.isEmpty();
141 PersistentTable::findSmallest(const Address
& address
) const
143 assert(address
== line_address(address
));
144 AddressMap::const_iterator i
= m_map
.find(address
);
145 assert(i
!= m_map
.end());
146 const PersistentTableEntry
& entry
= i
->second
;
147 return entry
.m_starving
.smallestElement();
151 PersistentTable::typeOfSmallest(const Address
& address
) const
153 assert(address
== line_address(address
));
154 AddressMap::const_iterator i
= m_map
.find(address
);
155 assert(i
!= m_map
.end());
156 const PersistentTableEntry
& entry
= i
->second
;
157 if (entry
.m_request_to_write
.
158 isElement(entry
.m_starving
.smallestElement())) {
159 return AccessType_Write
;
161 return AccessType_Read
;
166 PersistentTable::markEntries(const Address
& address
)
168 assert(address
== line_address(address
));
169 AddressMap::iterator i
= m_map
.find(address
);
170 if (i
== m_map
.end())
173 PersistentTableEntry
& entry
= i
->second
;
175 // None should be marked
176 assert(entry
.m_marked
.isEmpty());
178 // Mark all the nodes currently in the table
179 entry
.m_marked
= entry
.m_starving
;
183 PersistentTable::isLocked(const Address
& address
) const
185 assert(address
== line_address(address
));
187 // If an entry is present, it must be locked
188 return m_map
.count(address
) > 0;
192 PersistentTable::countStarvingForAddress(const Address
& address
) const
194 assert(address
== line_address(address
));
195 AddressMap::const_iterator i
= m_map
.find(address
);
196 if (i
== m_map
.end())
199 const PersistentTableEntry
& entry
= i
->second
;
200 return entry
.m_starving
.count();
204 PersistentTable::countReadStarvingForAddress(const Address
& address
) const
206 assert(address
== line_address(address
));
207 AddressMap::const_iterator i
= m_map
.find(address
);
208 if (i
== m_map
.end())
211 const PersistentTableEntry
& entry
= i
->second
;
212 return entry
.m_starving
.count() - entry
.m_request_to_write
.count();
216 PersistentTable::print(ostream
& out
) const