gem5 v24.0.0.0
Loading...
Searching...
No Matches
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 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
33
34#include <fstream>
35#include <unordered_set>
36
37#include "base/random.hh"
40
41namespace gem5
42{
43
44Episode::Episode(ProtocolTester* _tester, TesterThread* _thread, int num_loads,
45 int num_stores)
46 : tester(_tester),
47 thread(_thread),
48 numLoads(num_loads),
49 numStores(num_stores),
50 nextActionIdx(0)
51{
52 assert(tester && thread);
53
56 assert(numLanes > 0);
57
59 assert(addrManager);
60
62 // generate a sequence of actions
64 isActive = true;
65
66 DPRINTFN("Episode %d\n", episodeId);
67}
68
70{
71 for (Episode::Action* action : actions) {
72 assert(action);
73 delete action;
74 }
75}
76
77const Episode::Action*
79{
80 if (nextActionIdx < actions.size())
81 return actions[nextActionIdx];
82 else
83 return nullptr;
84}
85
86void
88{
89 assert(nextActionIdx < actions.size());
91}
92
93void
95{
96 // first, push Atomic & then Acquire action
99
100 // second, push a number of LD/ST actions
101 int num_loads = numLoads;
102 int num_stores = numStores;
103 while ((num_loads + num_stores) > 0) {
104 switch (random_mt.random<unsigned int>() % 2) {
105 case 0: // Load
106 if (num_loads > 0) {
107 actions.push_back(new Action(Action::Type::LOAD,
108 numLanes));
109 num_loads--;
110 }
111 break;
112 case 1: // Store
113 if (num_stores > 0) {
114 actions.push_back(new Action(Action::Type::STORE,
115 numLanes));
116 num_stores--;
117 }
118 break;
119 default:
120 assert(false);
121 }
122 }
123
124 // last, push an Release & then Atomic action
127
128 // for each lane, pick a list of locations
129 Location normal_loc;
130
131 for (int lane = 0; lane < numLanes; ++lane) {
133
134 // first, we select atomic loc for this lane
135 // atomic loc for this lane should not have been picked yet
137 // pick randomly an atomic location
139 assert(atomicLocs[lane] >= 0);
140
141 // go through each action in this lane and set its location
142 for (Action* action : actions) {
143 assert(action);
144
145 switch (action->getType()) {
147 action->setLocation(lane, atomicLocs[lane]);
148 break;
150 // pick randomly a normal location
151 normal_loc = addrManager->
152 getLoadLoc(atomicLocs[lane]);
153 assert(normal_loc >= AddressManager::INVALID_LOCATION);
154
155 if (normal_loc != AddressManager::INVALID_LOCATION) {
156 // check DRF
157 if (!tester->checkDRF(atomicLocs[lane],
158 normal_loc, false) ||
159 !this->checkDRF(atomicLocs[lane], normal_loc,
160 false, lane)) {
161 panic("TestTh %d - Data race detected. STOPPED!\n",
163 }
164 }
165
166 action->setLocation(lane, normal_loc);
167 break;
169 // pick randomly a normal location
170 normal_loc = addrManager->
171 getStoreLoc(atomicLocs[lane]);
172 assert(normal_loc >= AddressManager::INVALID_LOCATION);
173
174 if (normal_loc != AddressManager::INVALID_LOCATION) {
175 // check DRF
176 if (!tester->checkDRF(atomicLocs[lane],
177 normal_loc, true) ||
178 !this->checkDRF(atomicLocs[lane], normal_loc,
179 true, lane)) {
180 panic("TestTh %d - Data race detected. STOPPED!\n",
182 }
183 }
184
185 action->setLocation(lane, normal_loc);
186 break;
189 // no op
190 break;
191 default:
192 panic("Invalid action type\n");
193 }
194 }
195
197 }
198}
199
200void
202{
203 // release all locations this episode has picked and used
204 Location atomic_loc, normal_loc;
205 for (int lane = 0; lane < numLanes; ++lane) {
208
209 std::unordered_set<Location> unique_loc_set;
210
211 for (Action* action : actions) {
212 assert(action);
213
214 if (action->isAtomicAction()) {
215 if (atomic_loc == AddressManager::INVALID_LOCATION) {
216 atomic_loc = action->getLocation(lane);
217 } else {
218 // both atomic ops in the same lane must be
219 // at the same location
220 assert(atomic_loc == action->getLocation(lane));
221 }
222 } else if (!action->isMemFenceAction()) {
223 assert(atomic_loc >= 0);
224 normal_loc = action->getLocation(lane);
225
226 if (normal_loc >= 0)
227 unique_loc_set.insert(normal_loc);
228 }
229 }
230
231 // each unique loc can be released only once
232 for (Location loc : unique_loc_set)
233 addrManager->releaseLocation(atomic_loc, loc);
234 }
235
236 // this episode is no longer active
237 isActive = false;
238}
239
240bool
241Episode::checkDRF(Location atomic_loc, Location loc, bool isStore,
242 int max_lane) const
243{
244 assert(atomic_loc != AddressManager::INVALID_LOCATION);
246 assert(max_lane <= numLanes);
247
248 for (int lane = 0; lane < max_lane; ++lane) {
249 if (atomic_loc == atomicLocs[lane]) {
250 for (const Action* action : actions) {
251 if (!action->isAtomicAction() &&
252 !action->isMemFenceAction()) {
253 if (isStore && loc == action->getLocation(lane)) {
254 warn("ST at location %d races against thread %d\n",
255 loc, thread->getTesterThreadId());
256 return false;
257 } else if (!isStore &&
258 action->getType() == Action::Type::STORE &&
259 loc == action->getLocation(lane)) {
260 warn("LD at location %d races against thread %d\n",
261 loc, thread->getTesterThreadId());
262 return false;
263 }
264 }
265 }
266 }
267 }
268
269 return true;
270}
271
272// -------------------- Action class ----------------------------
274 : type(t),
275 numLanes(num_lanes)
276{
277 assert(numLanes > 0);
278 locations.resize(numLanes);
280}
281
282void
284{
285 assert(lane >= 0 && lane < numLanes);
286 locations[lane] = loc;
287}
288
291{
292 assert(lane >= 0 && lane < numLanes);
293 return locations[lane];
294}
295
296bool
298{
299 return (type == Type::ATOMIC);
300}
301
302bool
304{
305 return (type == Type::ACQUIRE || type == Type::RELEASE);
306}
307
308const std::string
310{
311 if (type == Type::ACQUIRE)
312 return "ACQUIRE";
313 else if (type == Type::RELEASE)
314 return "RELEASE";
315 else if (type == Type::ATOMIC)
316 return "ATOMIC";
317 else if (type == Type::LOAD)
318 return "LOAD";
319 else if (type == Type::STORE)
320 return "STORE";
321 else
322 panic("Invalid action type\n");
323}
324
325} // namespace gem5
#define DPRINTFN(...)
Definition trace.hh:238
static const int INVALID_LOCATION
void finishLocSelection(Location atomic_loc)
void releaseLocation(Location atomic_loc, Location loc)
Action(Type t, int num_lanes)
Definition episode.cc:273
Location getLocation(int lane) const
Definition episode.cc:290
const std::string printType() const
Definition episode.cc:309
bool isMemFenceAction() const
Definition episode.cc:303
bool isAtomicAction() const
Definition episode.cc:297
void setLocation(int lane, Location loc)
Definition episode.cc:283
LocationList locations
Definition episode.hh:77
ActionList actions
Definition episode.hh:110
void completeEpisode()
Definition episode.cc:201
Episode(ProtocolTester *tester, TesterThread *thread, int num_loads, int num_stores)
Definition episode.cc:44
TesterThread * thread
Definition episode.hh:103
AddressManager::Location Location
Definition episode.hh:48
bool checkDRF(Location atomic_loc, Location loc, bool isStore, int max_lane) const
Definition episode.cc:241
void popAction()
Definition episode.cc:87
int nextActionIdx
Definition episode.hh:121
AddressManager * addrManager
Definition episode.hh:104
const Action * peekCurAction() const
Definition episode.cc:78
AtomicLocationList atomicLocs
Definition episode.hh:113
void initActions()
Definition episode.cc:94
ProtocolTester * tester
Definition episode.hh:102
bool checkDRF(Location atomic_loc, Location loc, bool isStore) const
AddressManager * getAddressManager() const
int getNumLanes() const
int getTesterThreadId() const
Random random_mt
Definition random.cc:99
std::enable_if_t< std::is_integral_v< T >, T > random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
Definition random.hh:90
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define warn(...)
Definition logging.hh:256
Bitfield< 5 > t
Definition misc_types.hh:71
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36

Generated on Tue Jun 18 2024 16:24:02 for gem5 by doxygen 1.11.0