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

Generated on Mon Jan 13 2025 04:28:32 for gem5 by doxygen 1.9.8