gem5  v21.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
address_manager.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2020 Advanced Micro Devices, Inc.
3  * All rights reserved.
4  *
5  * For use for simulation and test purposes only
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived from this
19  * software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
35 
36 #include <algorithm>
37 
38 #include "base/intmath.hh"
39 #include "base/logging.hh"
40 #include "base/random.hh"
41 #include "base/trace.hh"
42 
43 const int AddressManager::INVALID_VALUE = -1;
45 
46 AddressManager::AddressManager(int n_atomic_locs, int n_normal_locs_per_atomic)
47  : numAtomicLocs(n_atomic_locs),
48  numLocsPerAtomic(n_normal_locs_per_atomic)
49 {
50  assert(numAtomicLocs > 0 && numLocsPerAtomic > 0);
52 
53  // generate random address map
55  for (Location i = 0; i < numAtomicLocs + numNormalLocs; ++i) {
56  // all addresses are sizeof(Value) (i.e., 4-byte) aligned
57  randAddressMap[i] = (Addr)((i + 128) << floorLog2(sizeof(Value)));
58  }
59 
60  // randomly shuffle randAddressMap
61  std::random_shuffle(randAddressMap.begin(), randAddressMap.end());
62 
63  // initialize atomic locations
64  // first and last normal location per atomic location
65  Location first, last;
66  for (Location atomic_loc = 0; atomic_loc < numAtomicLocs; ++atomic_loc) {
67  first = numAtomicLocs + numLocsPerAtomic * atomic_loc;
68  last = first + numLocsPerAtomic - 1;
69  atomicStructs.push_back(new AtomicStruct(atomic_loc, first, last));
70  }
71 
72  // initialize log table
73  for (Location loc = 0; loc < numAtomicLocs + numNormalLocs; ++loc) {
74  logTable.push_back(new LastWriter());
75  }
76 }
77 
79 {
80  for (AtomicStruct* atomic_struct : atomicStructs)
81  delete atomic_struct;
82  for (LastWriter* lw : logTable)
83  delete lw;
84 }
85 
86 Addr
88 {
89  assert(loc < numAtomicLocs + numNormalLocs && loc >= 0);
90  return randAddressMap[loc];
91 }
92 
95 {
96  Location ret_atomic_loc = random() % numAtomicLocs;
97  atomicStructs[ret_atomic_loc]->startLocSelection();
98  return ret_atomic_loc;
99 }
100 
103 {
104  assert(atomic_loc >= 0 && atomic_loc < numAtomicLocs);
105  return atomicStructs[atomic_loc]->getLoadLoc();
106 }
107 
110 {
111  assert(atomic_loc >= 0 && atomic_loc < numAtomicLocs);
112  return atomicStructs[atomic_loc]->getStoreLoc();
113 }
114 
115 void
117 {
118  assert(atomic_loc >= 0 && atomic_loc < numAtomicLocs);
119  atomicStructs[atomic_loc]->endLocSelection();
120 }
121 
122 void
124 {
125  assert(atomic_loc >= 0 && atomic_loc < numAtomicLocs);
126  atomicStructs[atomic_loc]->releaseLoc(loc);
127 }
128 
129 std::string
131 {
132  return logTable[loc]->print();
133 }
134 
135 // ------------------- AtomicStruct --------------------------
137  Location loc_begin,
138  Location loc_end)
139 {
140  // the location range must have at least 1 location
141  assert(loc_begin <= loc_end);
142 
143  atomicLoc = atomic_loc;
144  arraySize = loc_end - loc_begin + 1;
145  locationBase = loc_begin;
146 
147  // allocate an array of arrray_size
148  locArray = new Location[arraySize];
149 
150  // initialize locArray & locProps
151  Location loc;
152  for (int offset = 0; offset < arraySize; ++offset) {
153  loc = locationBase + offset;
154  locArray[offset] = loc;
155  locProps.push_back(LocProperty(offset, 0));
156  }
157 
158  // region (1) and (3) are initially empty
159  firstMark = 0;
161  // no request made at this location so far
162  requestCount = 0;
163 }
164 
166 {
167  delete[] locArray;
168 }
169 
170 void
172 {
173  assert(firstMark >= 0);
174  assert(firstMark <= secondMark);
175  assert(secondMark <= arraySize);
176  // make sure loadStoreMap has been cleared
177  assert(loadStoreMap.empty());
178 
179  // this atomic location is picked for Atomic_ACQ
180  // and Atomic_REL in an episode
181  requestCount += 2;
182  // add two expected values in expectedValues set
183  expectedValues.insert(requestCount - 1);
184  expectedValues.insert(requestCount - 2);
185 }
186 
189 {
190  assert(firstMark >= 0);
191  assert(firstMark <= secondMark);
192  assert(secondMark <= arraySize);
193 
194  if (firstMark == arraySize) {
195  // no location can be picked for a LD now, so return an empty location
196  return INVALID_LOCATION;
197  } else {
198  // we can pick any location btw
199  // locArray [firstMark : arraySize-1]
200  int range_size = arraySize - firstMark;
201  Location ret_loc = locArray[firstMark + random() % range_size];
202 
203  // update loadStoreMap
204  LdStMap::iterator it = loadStoreMap.find(ret_loc);
205 
206  if (it == loadStoreMap.end()) {
207  // insert a new entry to the map b/c the entry is not there yet
208  // to mark this location has been picked for a LD
209  loadStoreMap.insert(std::pair<Location, LdStBits>
210  (ret_loc, LdStBits(true,false)));
211  } else {
212  // otherwise, just update the LD bit
213  (it->second).first = true;
214  }
215 
216  return ret_loc;
217  }
218 }
219 
222 {
223  assert(firstMark >= 0);
224  assert(firstMark <= secondMark);
225  assert(secondMark <= arraySize);
226 
227  if (firstMark == secondMark) {
228  // no location can be picked for a ST now, return an invalid location
229  return INVALID_LOCATION;
230  } else {
231  // we can pick any location btw [firstMark : secondMark-1]
232  int range_size = secondMark - firstMark;
233  Location ret_loc = locArray[firstMark + random() % range_size];
234 
235  // update loadStoreMap
236  LdStMap::iterator it = loadStoreMap.find(ret_loc);
237 
238  if (it == loadStoreMap.end()) {
239  // insert a new entry to the map b/c the entry is not there yet
240  // to mark this location has been picked for a ST
241  loadStoreMap.insert(std::pair<Location, LdStBits>
242  (ret_loc, LdStBits(false,true)));
243  } else {
244  // otherwise, just update the ST bit
245  (it->second).second = true;
246  }
247 
248  return ret_loc;
249  }
250 }
251 
252 // for each entry in loadStoreMap,
253 // if <LD_bit, ST_bit> == <1,0>
254 // - if the location is in (2), then move it to (3)
255 // - if the location is in (3), no move
256 // - otherwise, throw an error
257 // if <LD_bit, ST_bit> == <0,1> or <1,1>
258 // - move it from (2) to (1)
259 void
261 {
262  assert(firstMark >= 0);
263  assert(firstMark <= secondMark);
264  assert(secondMark <= arraySize);
265 
266  for (auto& it : loadStoreMap) {
267  Location loc = it.first;
268  LdStBits p = it.second;
269 
270  assert(loc >= locationBase && loc < locationBase + arraySize);
271  LocProperty& loc_prop = locProps[loc - locationBase];
272 
273  if (p.first && !p.second) {
274  // this location has been picked for LD(s) but not ST
275  // it must be in either region (2) or (3)
276  assert(inSecondRegion(loc_prop.first) ||
277  inThirdRegion(loc_prop.first));
278 
279  if (inSecondRegion(loc_prop.first)) {
280  // there is no owner of this location yet
281  assert(loc_prop.second == 0);
282 
283  // pick the last location in (2) to swap
284  Location swapped_loc = locArray[secondMark - 1];
285  LocProperty& swapped_loc_prop =
286  locProps[swapped_loc - locationBase];
287 
288  // swap loc and swapped_loc
289  swap(loc_prop, swapped_loc_prop);
290 
291  // then, expand (3)
292  secondMark--;
293  }
294 
295  // increment the location's number of owners
296  loc_prop.second++;
297  } else if (p.second) {
298  // this location has been picked for ST(s) and/or LD(s)
299  // it must be in region (2)
300  assert(inSecondRegion(loc_prop.first) && loc_prop.second == 0);
301 
302  // pick the first location in (2) to swap
303  Location swapped_loc = locArray[firstMark];
304  LocProperty& swapped_loc_prop =
305  locProps[swapped_loc - locationBase];
306 
307  // swap loc and swapped_loc
308  swap(loc_prop, swapped_loc_prop);
309 
310  // then, expand (1)
311  firstMark++;
312 
313  // increment the location's number of owners
314  loc_prop.second++;
315  } else {
316  panic("Location in loadStoreMap but wasn't picked in any"
317  " action\n");
318  }
319  }
320 
321  // clear the ld_st_map
322  loadStoreMap.clear();
323 }
324 
325 void
327 {
328  assert(loc >= locationBase && loc < locationBase + arraySize);
329 
330  LocProperty& loc_prop = locProps[loc - locationBase];
331 
332  if (inFirstRegion(loc_prop.first)) {
333  // this location must have exactly 1 owner
334  assert(loc_prop.second == 1);
335 
336  // pick the last location in region 1 to swap
337  Location swapped_loc = locArray[firstMark - 1];
338  LocProperty& swapped_loc_prop = locProps[swapped_loc - locationBase];
339 
340  // swap loc and swapped_loc
341  swap(loc_prop, swapped_loc_prop);
342 
343  // then shrink (1)
344  firstMark--;
345 
346  // reset the location's number of owners
347  loc_prop.second = 0;
348  } else if (inThirdRegion(loc_prop.first)) {
349  // this location must have at least 1 owner
350  assert(loc_prop.second >= 1);
351 
352  if (loc_prop.second == 1) {
353  // pick the first location in region 3 to swap
354  Location swapped_loc = locArray[secondMark];
355  LocProperty& swapped_loc_prop =
356  locProps[swapped_loc - locationBase];
357 
358  // swap loc and swapped_loc
359  swap(loc_prop, swapped_loc_prop);
360 
361  // then shrink (3)
362  secondMark++;
363  }
364  // decrement the loc's number of owners
365  loc_prop.second--;
366  } else {
367  // some one else must already reset this counter
368  assert(inSecondRegion(loc_prop.first) && loc_prop.second == 0);
369  }
370 }
371 
372 bool
374 {
375  ExpectedValueSet::iterator it = expectedValues.find(val);
376 
377  if (it == expectedValues.end()) {
378  std::stringstream exp_val_ss;
379  for (auto& val : expectedValues) {
380  exp_val_ss << " " << val;
381  }
382 
383  warn("Expected return values are:\n\t%s\n", exp_val_ss.str());
384 
385  return false;
386  }
387 
388  // erase this value b/c it's done
389  expectedValues.erase(it);
390 
391  return true;
392 }
393 
394 void
396 {
397  int new_idx_1 = prop_2.first;
398  int new_idx_2 = prop_1.first;
399 
400  // swap the two locations in locArray
401  Location tmp = locArray[prop_1.first];
402  locArray[prop_1.first] = locArray[prop_2.first];
403  locArray[prop_2.first] = tmp;
404 
405  // update their new indices
406  prop_1.first = new_idx_1;
407  prop_2.first = new_idx_2;
408 }
409 
410 // ------------------ log table ---------------------
411 void
412 AddressManager::updateLogTable(Location loc, int thread_id, int episode_id,
413  Value new_value, Tick cur_tick, int cu_id)
414 {
415  assert(loc >= 0 && loc < numAtomicLocs + numNormalLocs);
416  logTable[loc]->update(thread_id, cu_id, episode_id, new_value, cur_tick);
417 }
418 
421 {
422  assert(loc >= 0 && loc < numAtomicLocs + numNormalLocs);
423  return logTable[loc]->getLastStoredValue();
424 }
425 
426 bool
428 {
429  assert(loc >= 0 && loc < numAtomicLocs);
430  return atomicStructs[loc]->isExpectedValue(ret_val);
431 }
AddressManager::validateAtomicResp
bool validateAtomicResp(Location loc, Value ret_val)
Definition: address_manager.cc:427
warn
#define warn(...)
Definition: logging.hh:239
AddressManager::AtomicStruct::swap
void swap(LocProperty &prop_1, LocProperty &prop_2)
Definition: address_manager.cc:395
AddressManager::Location
int32_t Location
Definition: address_manager.hh:126
AddressManager::getLoadLoc
Location getLoadLoc(Location atomic_loc)
Definition: address_manager.cc:102
AddressManager::AtomicStruct::getStoreLoc
Location getStoreLoc()
Definition: address_manager.cc:221
AddressManager::AtomicStruct::locArray
Location * locArray
Definition: address_manager.hh:215
AddressManager::Value
int32_t Value
Definition: address_manager.hh:125
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
AddressManager::atomicStructs
AtomicStructTable atomicStructs
Definition: address_manager.hh:267
AddressManager::getAddress
Addr getAddress(Location loc)
Definition: address_manager.cc:87
random.hh
AddressManager::AtomicStruct::locationBase
Location locationBase
Definition: address_manager.hh:212
AddressManager::AtomicStruct::firstMark
int firstMark
Definition: address_manager.hh:216
AddressManager::AtomicStruct::AtomicStruct
AtomicStruct(Location atom_loc, Location loc_begin, Location loc_end)
Definition: address_manager.cc:136
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:59
AddressManager::AtomicStruct::requestCount
int requestCount
Definition: address_manager.hh:230
AddressManager::AtomicStruct::arraySize
int arraySize
Definition: address_manager.hh:217
AddressManager::AtomicStruct::isExpectedValue
bool isExpectedValue(Value val)
Definition: address_manager.cc:373
AddressManager::AtomicStruct::startLocSelection
void startLocSelection()
Definition: address_manager.cc:171
AddressManager::getLoggedValue
Value getLoggedValue(Location loc) const
Definition: address_manager.cc:420
AddressManager::randAddressMap
AddressMap randAddressMap
Definition: address_manager.hh:263
AddressManager::AtomicStruct::endLocSelection
void endLocSelection()
Definition: address_manager.cc:260
AddressManager::AtomicStruct::LocProperty
std::pair< int, int > LocProperty
Definition: address_manager.hh:220
AddressManager::numLocsPerAtomic
int numLocsPerAtomic
Definition: address_manager.hh:257
AddressManager::finishLocSelection
void finishLocSelection(Location atomic_loc)
Definition: address_manager.cc:116
AddressManager::LastWriter
Definition: address_manager.hh:154
AddressManager::AtomicStruct::secondMark
int secondMark
Definition: address_manager.hh:216
AddressManager::releaseLocation
void releaseLocation(Location atomic_loc, Location loc)
Definition: address_manager.cc:123
AddressManager::logTable
LogTable logTable
Definition: address_manager.hh:271
std::pair
STL pair class.
Definition: stl.hh:58
AddressManager::~AddressManager
~AddressManager()
Definition: address_manager.cc:78
X86ISA::val
Bitfield< 63 > val
Definition: misc.hh:769
AddressManager::numNormalLocs
int numNormalLocs
Definition: address_manager.hh:259
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:148
AddressManager::AtomicStruct
Definition: address_manager.hh:192
floorLog2
std::enable_if_t< std::is_integral< T >::value, int > floorLog2(T x)
Definition: intmath.hh:63
AddressManager::AddressManager
AddressManager(int n_atomic_locs, int numNormalLocsPerAtomic)
Definition: address_manager.cc:46
AddressManager::AtomicStruct::~AtomicStruct
~AtomicStruct()
Definition: address_manager.cc:165
AddressManager::printLastWriter
std::string printLastWriter(Location loc) const
Definition: address_manager.cc:130
AddressManager::AtomicStruct::releaseLoc
void releaseLoc(Location loc)
Definition: address_manager.cc:326
address_manager.hh
AddressManager::getAtomicLoc
Location getAtomicLoc()
Definition: address_manager.cc:94
logging.hh
AddressManager::AtomicStruct::getLoadLoc
Location getLoadLoc()
Definition: address_manager.cc:188
AddressManager::AtomicStruct::atomicLoc
Location atomicLoc
Definition: address_manager.hh:211
MipsISA::random
random
Definition: pra_constants.hh:50
trace.hh
AddressManager::getStoreLoc
Location getStoreLoc(Location atomic_loc)
Definition: address_manager.cc:109
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
intmath.hh
AddressManager::updateLogTable
void updateLogTable(Location loc, int threadId, int episodeId, Value new_value, Tick curTick, int cuId=-1)
Definition: address_manager.cc:412
AddressManager::INVALID_LOCATION
static const int INVALID_LOCATION
Definition: address_manager.hh:151
AddressManager::numAtomicLocs
int numAtomicLocs
Definition: address_manager.hh:255
AddressManager::AtomicStruct::locProps
LocPropTable locProps
Definition: address_manager.hh:222
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
AddressManager::INVALID_VALUE
static const int INVALID_VALUE
Definition: address_manager.hh:150
ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:153

Generated on Tue Mar 23 2021 19:41:25 for gem5 by doxygen 1.8.17