gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PersistentTable.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
3  * All rights reserved.
4  *
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.
15  *
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.
27  */
28 
30 
31 using namespace std;
32 
33 // randomize so that handoffs are not locality-aware
34 #if 0
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};
39 #endif
40 
42 {
43 }
44 
46 {
47 }
48 
49 void
51  MachineID locker,
52  AccessType type)
53 {
54 #if 0
55  if (locker == m_chip_ptr->getID())
56  cout << "Chip " << m_chip_ptr->getID() << ": " << llocker
57  << " requesting lock for " << address << endl;
58 
59  MachineID locker = (MachineID) persistent_randomize[llocker];
60 #endif
61 
62  assert(address == makeLineAddress(address));
63 
64  static const PersistentTableEntry dflt;
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;
70 
71  if (present) {
72  // Make sure we're not already in the locked set
73  assert(!(entry.m_starving.isElement(locker)));
74  }
75 
76  entry.m_starving.add(locker);
77  if (type == AccessType_Write)
78  entry.m_request_to_write.add(locker);
79 
80  if (present)
81  assert(entry.m_marked.isSubset(entry.m_starving));
82 }
83 
84 void
86  MachineID unlocker)
87 {
88 #if 0
89  if (unlocker == m_chip_ptr->getID())
90  cout << "Chip " << m_chip_ptr->getID() << ": " << uunlocker
91  << " requesting unlock for " << address << endl;
92 
93  MachineID unlocker = (MachineID) persistent_randomize[uunlocker];
94 #endif
95 
96  assert(address == makeLineAddress(address));
97  assert(m_map.count(address));
98  PersistentTableEntry& entry = m_map[address];
99 
100  //
101  // Make sure we're in the locked set
102  //
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));
109 
110  // Deallocate if empty
111  if (entry.m_starving.isEmpty()) {
112  assert(entry.m_marked.isEmpty());
113  m_map.erase(address);
114  }
115 }
116 
117 bool
119  MachineID machId) const
120 {
121  assert(address == makeLineAddress(address));
122 
123  AddressMap::const_iterator i = m_map.find(address);
124  if (i == m_map.end()) {
125  // No entry present
126  return true;
127  }
128 
129  const PersistentTableEntry &entry = i->second;
130 
131  if (entry.m_starving.isElement(machId)) {
132  // We can't issue another lockdown until are previous unlock
133  // has occurred
134  return false;
135  }
136 
137  return entry.m_marked.isEmpty();
138 }
139 
140 MachineID
142 {
143  assert(address == makeLineAddress(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();
148 }
149 
150 AccessType
152 {
153  assert(address == makeLineAddress(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;
160  } else {
161  return AccessType_Read;
162  }
163 }
164 
165 void
167 {
168  assert(address == makeLineAddress(address));
169  AddressMap::iterator i = m_map.find(address);
170  if (i == m_map.end())
171  return;
172 
173  PersistentTableEntry& entry = i->second;
174 
175  // None should be marked
176  assert(entry.m_marked.isEmpty());
177 
178  // Mark all the nodes currently in the table
179  entry.m_marked = entry.m_starving;
180 }
181 
182 bool
184 {
185  assert(address == makeLineAddress(address));
186 
187  // If an entry is present, it must be locked
188  return m_map.count(address) > 0;
189 }
190 
191 int
193 {
194  assert(address == makeLineAddress(address));
195  AddressMap::const_iterator i = m_map.find(address);
196  if (i == m_map.end())
197  return 0;
198 
199  const PersistentTableEntry& entry = i->second;
200  return entry.m_starving.count();
201 }
202 
203 int
205 {
206  assert(address == makeLineAddress(address));
207  AddressMap::const_iterator i = m_map.find(address);
208  if (i == m_map.end())
209  return 0;
210 
211  const PersistentTableEntry& entry = i->second;
212  return entry.m_starving.count() - entry.m_request_to_write.count();
213 }
214 
215 void
216 PersistentTable::print(ostream& out) const
217 {
218 }
219 
AccessType typeOfSmallest(Addr address) const
Bitfield< 7 > i
Definition: miscregs.hh:1378
STL pair class.
Definition: stl.hh:61
void persistentRequestUnlock(Addr address, MachineID unlocker)
Bitfield< 7 > present
Definition: misc.hh:945
void add(MachineID newElement)
Definition: NetDest.cc:39
bool isElement(MachineID element) const
Definition: NetDest.cc:241
int count() const
Definition: NetDest.cc:122
void print(std::ostream &out) const
void remove(MachineID oldElement)
Definition: NetDest.cc:64
MachineID findSmallest(Addr address) const
bool isLocked(Addr addr) const
bool okToIssueStarving(Addr address, MachineID machID) const
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Addr makeLineAddress(Addr addr)
Definition: Address.cc:112
bool isSubset(const NetDest &test) const
Definition: NetDest.hh:76
MachineID smallestElement() const
Definition: NetDest.cc:138
type
Definition: misc.hh:728
void markEntries(Addr address)
int countStarvingForAddress(Addr addr) const
bool isEmpty() const
Definition: NetDest.cc:180
int countReadStarvingForAddress(Addr addr) const
void persistentRequestLock(Addr address, MachineID locker, AccessType type)

Generated on Fri Jun 9 2017 13:03:50 for gem5 by doxygen 1.8.6