gem5  v21.1.0.2
episode.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2021 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 <fstream>
37 #include <unordered_set>
38 
41 
42 namespace gem5
43 {
44 
45 Episode::Episode(ProtocolTester* _tester, TesterThread* _thread, int num_loads,
46  int num_stores)
47  : tester(_tester),
48  thread(_thread),
49  numLoads(num_loads),
50  numStores(num_stores),
51  nextActionIdx(0)
52 {
53  assert(tester && thread);
54 
57  assert(numLanes > 0);
58 
60  assert(addrManager);
61 
63  // generate a sequence of actions
64  initActions();
65  isActive = true;
66 
67  DPRINTFN("Episode %d\n", episodeId);
68 }
69 
71 {
72  for (Episode::Action* action : actions) {
73  assert(action);
74  delete action;
75  }
76 }
77 
78 const Episode::Action*
80 {
81  if (nextActionIdx < actions.size())
82  return actions[nextActionIdx];
83  else
84  return nullptr;
85 }
86 
87 void
89 {
90  assert(nextActionIdx < actions.size());
91  nextActionIdx++;
92 }
93 
94 void
96 {
97  // first, push Atomic & then Acquire action
100 
101  // second, push a number of LD/ST actions
102  int num_loads = numLoads;
103  int num_stores = numStores;
104  while ((num_loads + num_stores) > 0) {
105  switch (random() % 2) {
106  case 0: // Load
107  if (num_loads > 0) {
108  actions.push_back(new Action(Action::Type::LOAD,
109  numLanes));
110  num_loads--;
111  }
112  break;
113  case 1: // Store
114  if (num_stores > 0) {
115  actions.push_back(new Action(Action::Type::STORE,
116  numLanes));
117  num_stores--;
118  }
119  break;
120  default:
121  assert(false);
122  }
123  }
124 
125  // last, push an Release & then Atomic action
126  actions.push_back(new Action(Action::Type::RELEASE, numLanes));
127  actions.push_back(new Action(Action::Type::ATOMIC, numLanes));
128 
129  // for each lane, pick a list of locations
130  Location normal_loc;
131 
132  for (int lane = 0; lane < numLanes; ++lane) {
134 
135  // first, we select atomic loc for this lane
136  // atomic loc for this lane should not have been picked yet
138  // pick randomly an atomic location
140  assert(atomicLocs[lane] >= 0);
141 
142  // go through each action in this lane and set its location
143  for (Action* action : actions) {
144  assert(action);
145 
146  switch (action->getType()) {
148  action->setLocation(lane, atomicLocs[lane]);
149  break;
150  case Action::Type::LOAD:
151  // pick randomly a normal location
152  normal_loc = addrManager->
153  getLoadLoc(atomicLocs[lane]);
154  assert(normal_loc >= AddressManager::INVALID_LOCATION);
155 
156  if (normal_loc != AddressManager::INVALID_LOCATION) {
157  // check DRF
158  if (!tester->checkDRF(atomicLocs[lane],
159  normal_loc, false) ||
160  !this->checkDRF(atomicLocs[lane], normal_loc,
161  false, lane)) {
162  panic("TestTh %d - Data race detected. STOPPED!\n",
164  }
165  }
166 
167  action->setLocation(lane, normal_loc);
168  break;
169  case Action::Type::STORE:
170  // pick randomly a normal location
171  normal_loc = addrManager->
172  getStoreLoc(atomicLocs[lane]);
173  assert(normal_loc >= AddressManager::INVALID_LOCATION);
174 
175  if (normal_loc != AddressManager::INVALID_LOCATION) {
176  // check DRF
177  if (!tester->checkDRF(atomicLocs[lane],
178  normal_loc, true) ||
179  !this->checkDRF(atomicLocs[lane], normal_loc,
180  true, lane)) {
181  panic("TestTh %d - Data race detected. STOPPED!\n",
183  }
184  }
185 
186  action->setLocation(lane, normal_loc);
187  break;
190  // no op
191  break;
192  default:
193  panic("Invalid action type\n");
194  }
195  }
196 
198  }
199 }
200 
201 void
203 {
204  // release all locations this episode has picked and used
205  Location atomic_loc, normal_loc;
206  for (int lane = 0; lane < numLanes; ++lane) {
209 
210  std::unordered_set<Location> unique_loc_set;
211 
212  for (Action* action : actions) {
213  assert(action);
214 
215  if (action->isAtomicAction()) {
216  if (atomic_loc == AddressManager::INVALID_LOCATION) {
217  atomic_loc = action->getLocation(lane);
218  } else {
219  // both atomic ops in the same lane must be
220  // at the same location
221  assert(atomic_loc == action->getLocation(lane));
222  }
223  } else if (!action->isMemFenceAction()) {
224  assert(atomic_loc >= 0);
225  normal_loc = action->getLocation(lane);
226 
227  if (normal_loc >= 0)
228  unique_loc_set.insert(normal_loc);
229  }
230  }
231 
232  // each unique loc can be released only once
233  for (Location loc : unique_loc_set)
234  addrManager->releaseLocation(atomic_loc, loc);
235  }
236 
237  // this episode is no longer active
238  isActive = false;
239 }
240 
241 bool
242 Episode::checkDRF(Location atomic_loc, Location loc, bool isStore,
243  int max_lane) const
244 {
245  assert(atomic_loc != AddressManager::INVALID_LOCATION);
246  assert(loc != AddressManager::INVALID_LOCATION);
247  assert(max_lane <= numLanes);
248 
249  for (int lane = 0; lane < max_lane; ++lane) {
250  if (atomic_loc == atomicLocs[lane]) {
251  for (const Action* action : actions) {
252  if (!action->isAtomicAction() &&
253  !action->isMemFenceAction()) {
254  if (isStore && loc == action->getLocation(lane)) {
255  warn("ST at location %d races against thread %d\n",
256  loc, thread->getTesterThreadId());
257  return false;
258  } else if (!isStore &&
259  action->getType() == Action::Type::STORE &&
260  loc == action->getLocation(lane)) {
261  warn("LD at location %d races against thread %d\n",
262  loc, thread->getTesterThreadId());
263  return false;
264  }
265  }
266  }
267  }
268  }
269 
270  return true;
271 }
272 
273 // -------------------- Action class ----------------------------
275  : type(t),
276  numLanes(num_lanes)
277 {
278  assert(numLanes > 0);
279  locations.resize(numLanes);
281 }
282 
283 void
285 {
286  assert(lane >= 0 && lane < numLanes);
287  locations[lane] = loc;
288 }
289 
292 {
293  assert(lane >= 0 && lane < numLanes);
294  return locations[lane];
295 }
296 
297 bool
299 {
300  return (type == Type::ATOMIC);
301 }
302 
303 bool
305 {
306  return (type == Type::ACQUIRE || type == Type::RELEASE);
307 }
308 
309 const std::string
311 {
312  if (type == Type::ACQUIRE)
313  return "ACQUIRE";
314  else if (type == Type::RELEASE)
315  return "RELEASE";
316  else if (type == Type::ATOMIC)
317  return "ATOMIC";
318  else if (type == Type::LOAD)
319  return "LOAD";
320  else if (type == Type::STORE)
321  return "STORE";
322  else
323  panic("Invalid action type\n");
324 }
325 
326 } // namespace gem5
episode.hh
warn
#define warn(...)
Definition: logging.hh:245
gem5::AddressManager::finishLocSelection
void finishLocSelection(Location atomic_loc)
Definition: address_manager.cc:119
gem5::Episode::Episode
Episode(ProtocolTester *tester, TesterThread *thread, int num_loads, int num_stores)
Definition: episode.cc:45
gem5::Episode::Action::Type::STORE
@ STORE
gem5::Episode::numLoads
int numLoads
Definition: episode.hh:120
gem5::Episode::nextActionIdx
int nextActionIdx
Definition: episode.hh:123
gem5::TesterThread::getNumLanes
int getNumLanes() const
Definition: tester_thread.hh:78
gem5::Episode::Action::locations
LocationList locations
Definition: episode.hh:79
gem5::Episode::Action::printType
const std::string printType() const
Definition: episode.cc:310
gem5::MipsISA::random
random
Definition: pra_constants.hh:53
gem5::Episode::numLanes
int numLanes
Definition: episode.hh:125
gem5::Episode::actions
ActionList actions
Definition: episode.hh:112
gem5::TesterThread
Definition: tester_thread.hh:51
gem5::Episode::completeEpisode
void completeEpisode()
Definition: episode.cc:202
gem5::Episode::Action::setLocation
void setLocation(int lane, Location loc)
Definition: episode.cc:284
gem5::Episode::atomicLocs
AtomicLocationList atomicLocs
Definition: episode.hh:115
gem5::Episode::Action::isAtomicAction
bool isAtomicAction() const
Definition: episode.cc:298
gem5::Episode::addrManager
AddressManager * addrManager
Definition: episode.hh:106
gem5::Episode::peekCurAction
const Action * peekCurAction() const
Definition: episode.cc:79
gem5::Episode::Action::numLanes
int numLanes
Definition: episode.hh:77
gem5::Episode::~Episode
~Episode()
Definition: episode.cc:70
gem5::ProtocolTester
Definition: protocol_tester.hh:71
gem5::X86ISA::type
type
Definition: misc.hh:733
tester_thread.hh
gem5::Episode::Action::Type
Type
Definition: episode.hh:56
gem5::AddressManager::getAtomicLoc
Location getAtomicLoc()
Definition: address_manager.cc:97
gem5::Episode::Action::Action
Action(Type t, int num_lanes)
Definition: episode.cc:274
gem5::Episode::Action::Type::ATOMIC
@ ATOMIC
gem5::Episode::Action::Type::RELEASE
@ RELEASE
gem5::AddressManager::Location
int32_t Location
Definition: address_manager.hh:129
gem5::Episode::Location
AddressManager::Location Location
Definition: episode.hh:50
gem5::Episode::tester
ProtocolTester * tester
Definition: episode.hh:104
gem5::TesterThread::getTesterThreadId
int getTesterThreadId() const
Definition: tester_thread.hh:77
gem5::ArmISA::t
Bitfield< 5 > t
Definition: misc_types.hh:70
gem5::Episode::Action::getLocation
Location getLocation(int lane) const
Definition: episode.cc:291
gem5::ProtocolTester::checkDRF
bool checkDRF(Location atomic_loc, Location loc, bool isStore) const
Definition: protocol_tester.cc:299
gem5::Episode::Action::isMemFenceAction
bool isMemFenceAction() const
Definition: episode.cc:304
gem5::AddressManager::INVALID_LOCATION
static const int INVALID_LOCATION
Definition: address_manager.hh:154
gem5::Episode::Action::Type::ACQUIRE
@ ACQUIRE
gem5::Episode::numStores
int numStores
Definition: episode.hh:121
protocol_tester.hh
gem5::ProtocolTester::getNextEpisodeID
int getNextEpisodeID()
Definition: protocol_tester.hh:137
gem5::Episode::checkDRF
bool checkDRF(Location atomic_loc, Location loc, bool isStore, int max_lane) const
Definition: episode.cc:242
gem5::ProtocolTester::getAddressManager
AddressManager * getAddressManager() const
Definition: protocol_tester.hh:130
DPRINTFN
#define DPRINTFN(...)
Definition: trace.hh:214
gem5::Episode::initActions
void initActions()
Definition: episode.cc:95
gem5::Episode::episodeId
int episodeId
Definition: episode.hh:109
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::Episode::popAction
void popAction()
Definition: episode.cc:88
gem5::Episode::Action::Type::LOAD
@ LOAD
gem5::Episode::Action
Definition: episode.hh:53
gem5::Episode::isActive
bool isActive
Definition: episode.hh:118
gem5::AddressManager::releaseLocation
void releaseLocation(Location atomic_loc, Location loc)
Definition: address_manager.cc:126
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:177
gem5::Episode::thread
TesterThread * thread
Definition: episode.hh:105

Generated on Tue Sep 21 2021 12:25:09 for gem5 by doxygen 1.8.17