arch-arm,cpu: Introduce a getEMI virtual method on StaticInst.
[gem5.git] / src / sim / drain.hh
1 /*
2 * Copyright (c) 2012, 2015, 2017 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38 #ifndef __SIM_DRAIN_HH__
39 #define __SIM_DRAIN_HH__
40
41 #include <atomic>
42 #include <mutex>
43 #include <vector>
44
45 class Drainable;
46
47 /**
48 * Object drain/handover states
49 *
50 * An object starts out in the Running state. When the simulator
51 * prepares to take a snapshot or prepares a CPU for handover, it
52 * calls the drain() method to transfer the object into the Draining
53 * or Drained state. If any object enters the Draining state
54 * (Drainable::drain() returning >0), simulation continues until it
55 * all objects have entered the Drained state.
56 *
57 * Before resuming simulation, the simulator calls resume() to
58 * transfer the object to the Running state. This in turn results in a
59 * call to drainResume() for all Drainable objects in the
60 * simulator. New Drainable objects may be created while resuming. In
61 * such cases, the new objects will be created in the Resuming state
62 * and later resumed.
63 *
64 * \note Even though the state of an object (visible to the rest of
65 * the world through Drainable::getState()) could be used to determine
66 * if all objects have entered the Drained state, the protocol is
67 * actually a bit more elaborate. See Drainable::drain() for details.
68 *
69 * @ingroup api_drain
70 */
71 enum class DrainState {
72 Running, /**< Running normally */
73 Draining, /**< Draining buffers pending serialization/handover */
74 Drained, /**< Buffers drained, ready for serialization/handover */
75 Resuming, /**< Transient state while the simulator is resuming */
76 };
77
78 class DrainManager
79 {
80 private:
81 DrainManager();
82 DrainManager(DrainManager &) = delete;
83 ~DrainManager();
84
85 public:
86 /** Get the singleton DrainManager instance */
87 static DrainManager &instance() { return _instance; }
88
89 /**
90 * Try to drain the system.
91 *
92 * Try to drain the system and return true if all objects are in a
93 * the Drained state at which point the whole simulator is in a
94 * consistent state and ready for checkpointing or CPU
95 * handover. The simulation script must continue simulating until
96 * the simulation loop returns "Finished drain", at which point
97 * this method should be called again. This cycle should continue
98 * until this method returns true.
99 *
100 * @return true if all objects were drained successfully, false if
101 * more simulation is needed.
102 *
103 * @ingroup api_drain
104 */
105 bool tryDrain();
106
107 /**
108 * Resume normal simulation in a Drained system.
109 *
110 * @ingroup api_drain
111 */
112 void resume();
113
114 /**
115 * Run state fixups before a checkpoint restore operation.
116 *
117 * This is called before restoring the checkpoint and to make
118 * sure that everything has been set to drained.
119 *
120 * When restoring from a checkpoint, this function should be called
121 * first before calling the resume() function. And also before
122 * calling loadstate() on any object.
123 *
124 * The drain state of an object isn't stored in a checkpoint since
125 * the whole system is always going to be in the Drained state
126 * when the checkpoint is created. When the checkpoint is restored
127 * at a later stage, recreated objects will be in the Running
128 * state since the state isn't stored in checkpoints. This method
129 * performs state fixups on all Drainable objects and the
130 * DrainManager itself.
131 *
132 * @ingroup api_drain
133 */
134 void preCheckpointRestore();
135
136 /**
137 * Check if the system is drained
138 *
139 * @ingroup api_drain
140 */
141 bool isDrained() const { return _state == DrainState::Drained; }
142
143 /**
144 * Get the simulators global drain state
145 *
146 * @ingroup api_drain
147 */
148 DrainState state() const { return _state; }
149
150 /**
151 * Notify the DrainManager that a Drainable object has finished
152 * draining.
153 *
154 * @ingroup api_drain
155 */
156 void signalDrainDone();
157
158 public:
159 void registerDrainable(Drainable *obj);
160 void unregisterDrainable(Drainable *obj);
161
162 private:
163 /**
164 * Helper function to check if all Drainable objects are in a
165 * specific state.
166 */
167 bool allInState(DrainState state) const;
168
169 /**
170 * Thread-safe helper function to get the number of Drainable
171 * objects in a system.
172 */
173 size_t drainableCount() const;
174
175 /** Lock protecting the set of drainable objects */
176 mutable std::mutex globalLock;
177
178 /** Set of all drainable objects */
179 std::vector<Drainable *> _allDrainable;
180
181 /**
182 * Number of objects still draining. This is flagged atomic since
183 * it can be manipulated by SimObjects living in different
184 * threads.
185 */
186 std::atomic_uint _count;
187
188 /** Global simulator drain state */
189 DrainState _state;
190
191 /** Singleton instance of the drain manager */
192 static DrainManager _instance;
193 };
194
195 /**
196 * Interface for objects that might require draining before
197 * checkpointing.
198 *
199 * An object's internal state needs to be drained when creating a
200 * checkpoint, switching between CPU models, or switching between
201 * timing models. Once the internal state has been drained from
202 * <i>all</i> objects in the simulator, the objects are serialized to
203 * disc or the configuration change takes place. The process works as
204 * follows (see simulate.py for details):
205 *
206 * <ol>
207 * <li>DrainManager::tryDrain() calls Drainable::drain() for every
208 * object in the system. Draining has completed if all of them
209 * return true. Otherwise, the drain manager keeps track of the
210 * objects that requested draining and waits for them to signal
211 * that they are done draining using the signalDrainDone() method.
212 *
213 * <li>Continue simulation. When an object has finished draining its
214 * internal state, it calls DrainManager::signalDrainDone() on the
215 * manager. The drain manager keeps track of the objects that
216 * haven't drained yet, simulation stops when the set of
217 * non-drained objects becomes empty.
218 *
219 * <li>Check if any object still needs draining
220 * (DrainManager::tryDrain()), if so repeat the process above.
221 *
222 * <li>Serialize objects, switch CPU model, or change timing model.
223 *
224 * <li>Call DrainManager::resume(), which in turn calls
225 * Drainable::drainResume() for all objects, and then continue the
226 * simulation.
227 * </ol>
228 *
229 */
230 class Drainable
231 {
232 /**
233 * This class coordinates draining of a System.
234 *
235 * When draining the simulator, we need to make sure that all
236 * Drainable objects within the system have ended up in the drained
237 * state before declaring the operation to be successful. This class
238 * keeps track of how many objects are still in the process of
239 * draining. Once it determines that all objects have drained their
240 * state, it exits the simulation loop.
241 *
242 * @note A System might not be completely drained even though the
243 * DrainManager has caused the simulation loop to exit. Draining needs
244 * to be restarted until all Drainable objects declare that they don't
245 * need further simulation to be completely drained. See Drainable for
246 * more information.
247 */
248 friend class DrainManager;
249
250 protected:
251 Drainable();
252 virtual ~Drainable();
253
254 /**
255 * Draining is the process of clearing out the states of
256 * SimObjects.These are the SimObjects that are partially
257 * executed or are partially in flight. Draining is mostly
258 * used before forking and creating a check point.
259 *
260 * This function notifies an object that it needs to drain its state.
261 *
262 * If the object does not need further simulation to drain
263 * internal buffers, it returns DrainState::Drained and
264 * automatically switches to the Drained state. If the object
265 * needs more simulation, it returns DrainState::Draining and
266 * automatically enters the Draining state. Other return values
267 * are invalid.
268 *
269 * @note An object that has entered the Drained state can be
270 * disturbed by other objects in the system and consequently stop
271 * being drained. These perturbations are not visible in the drain
272 * state. The simulator therefore repeats the draining process
273 * until all objects return DrainState::Drained on the first call
274 * to drain().
275 *
276 * @return DrainState::Drained if the object is drained at this
277 * point in time, DrainState::Draining if it needs further
278 * simulation.
279 *
280 * @ingroup api_drain
281 */
282 virtual DrainState drain() = 0;
283
284 /**
285 * Resume execution after a successful drain.
286 *
287 * @ingroup api_drain
288 */
289 virtual void drainResume() {};
290
291 /**
292 * Signal that an object is drained
293 *
294 * This method is designed to be called whenever an object enters
295 * into a state where it is ready to be drained. The method is
296 * safe to call multiple times and there is no need to check that
297 * draining has been requested before calling this method.
298 *
299 * @ingroup api_drain
300 */
301 void signalDrainDone() const {
302 switch (_drainState) {
303 case DrainState::Running:
304 case DrainState::Drained:
305 case DrainState::Resuming:
306 return;
307 case DrainState::Draining:
308 _drainState = DrainState::Drained;
309 _drainManager.signalDrainDone();
310 return;
311 }
312 }
313
314 public:
315 /**
316 * Return the current drain state of an object.
317 *
318 * @ingroup api_drain
319 */
320 DrainState drainState() const { return _drainState; }
321
322 /**
323 * Notify a child process of a fork. SimObjects are told that the
324 * process is going to be forked.
325 *
326 * Forking is a process of splitting a process in to two
327 * processes, which is then used for multiprocessing.
328 *
329 * When calling fork in gem5, we need to ensure that resources
330 * shared between the parent and the child are consistent. This
331 * method is intended to be overloaded to handle that. For
332 * example, an object could use this method to re-open input files
333 * to get a separate file description with a private file offset.
334 *
335 * This method is only called in the child of the fork. The call
336 * takes place in a drained system.
337 *
338 * @ingroup api_drain
339 */
340 virtual void notifyFork() {};
341
342 private:
343 /** DrainManager interface to request a drain operation */
344 DrainState dmDrain();
345 /** DrainManager interface to request a resume operation */
346 void dmDrainResume();
347
348 /** Convenience reference to the drain manager */
349 DrainManager &_drainManager;
350
351 /**
352 * Current drain state of the object. Needs to be mutable since
353 * objects need to be able to signal that they have transitioned
354 * into a Drained state even if the calling method is const.
355 */
356 mutable DrainState _drainState;
357 };
358
359 #endif