gem5  v20.1.0.0
simulate.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2006 The Regents of The University of Michigan
3  * Copyright (c) 2013 Advanced Micro Devices, Inc.
4  * Copyright (c) 2013 Mark D. Hill and David A. Wood
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are
9  * met: redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer;
11  * redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution;
14  * neither the name of the copyright holders nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "sim/simulate.hh"
32 
33 #include <mutex>
34 #include <thread>
35 
36 #include "base/logging.hh"
37 #include "base/pollevent.hh"
38 #include "base/types.hh"
39 #include "sim/async.hh"
40 #include "sim/eventq.hh"
41 #include "sim/sim_events.hh"
42 #include "sim/sim_exit.hh"
43 #include "sim/stat_control.hh"
44 
46 std::mutex asyncEventMutex;
47 
51 
54 
63 static void
65 {
66  while (true) {
68  doSimLoop(queue);
69  }
70 }
71 
73 
80 simulate(Tick num_cycles)
81 {
82  // The first time simulate() is called from the Python code, we need to
83  // create a thread for each of event queues referenced by the
84  // instantiated sim objects.
85  static bool threads_initialized = false;
86  static std::vector<std::thread *> threads;
87 
88  if (!threads_initialized) {
90 
91  // the main thread (the one we're currently running on)
92  // handles queue 0, so we only need to allocate new threads
93  // for queues 1..N-1. We'll call these the "subordinate" threads.
94  for (uint32_t i = 1; i < numMainEventQueues; i++) {
95  threads.push_back(new std::thread(thread_loop, mainEventQueue[i]));
96  }
97 
98  threads_initialized = true;
100  new GlobalSimLoopExitEvent(mainEventQueue[0]->getCurTick(),
101  "simulate() limit reached", 0);
102  }
103 
104  inform("Entering event queue @ %d. Starting simulation...\n", curTick());
105 
106  if (num_cycles < MaxTick - curTick())
107  num_cycles = curTick() + num_cycles;
108  else // counter would roll over or be set to MaxTick anyhow
109  num_cycles = MaxTick;
110 
111  simulate_limit_event->reschedule(num_cycles);
112 
113  GlobalSyncEvent *quantum_event = NULL;
114  if (numMainEventQueues > 1) {
115  if (simQuantum == 0) {
116  fatal("Quantum for multi-eventq simulation not specified");
117  }
118 
119  quantum_event = new GlobalSyncEvent(curTick() + simQuantum, simQuantum,
121 
122  inParallelMode = true;
123  }
124 
125  // all subordinate (created) threads should be waiting on the
126  // barrier; the arrival of the main thread here will satisfy the
127  // barrier, and all threads will enter doSimLoop in parallel
128  threadBarrier->wait();
129  Event *local_event = doSimLoop(mainEventQueue[0]);
130  assert(local_event != NULL);
131 
132  inParallelMode = false;
133 
134  // locate the global exit event and return it to Python
135  BaseGlobalEvent *global_event = local_event->globalEvent();
136  assert(global_event != NULL);
137 
138  GlobalSimLoopExitEvent *global_exit_event =
139  dynamic_cast<GlobalSimLoopExitEvent *>(global_event);
140  assert(global_exit_event != NULL);
141 
143  if (quantum_event != NULL) {
144  quantum_event->deschedule();
145  delete quantum_event;
146  }
147 
148  return global_exit_event;
149 }
150 
156 static bool
158 {
159  bool was_set = false;
160  asyncEventMutex.lock();
161 
162  if (async_event) {
163  was_set = true;
164  async_event = false;
165  }
166 
167  asyncEventMutex.unlock();
168  return was_set;
169 }
170 
176 Event *
178 {
179  // set the per thread current eventq pointer
180  curEventQueue(eventq);
181  eventq->handleAsyncInsertions();
182 
183  while (1) {
184  // there should always be at least one event (the SimLoopExitEvent
185  // we just scheduled) in the queue
186  assert(!eventq->empty());
187  assert(curTick() <= eventq->nextTick() &&
188  "event scheduled in the past");
189 
191  // Take the event queue lock in case any of the service
192  // routines want to schedule new events.
193  std::lock_guard<EventQueue> lock(*eventq);
196  async_statdump = false;
197  async_statreset = false;
198  }
199 
200  if (async_io) {
201  async_io = false;
202  pollQueue.service();
203  }
204 
205  if (async_exit) {
206  async_exit = false;
207  exitSimLoop("user interrupt received");
208  }
209 
210  if (async_exception) {
211  async_exception = false;
212  return NULL;
213  }
214  }
215 
216  Event *exit_event = eventq->serviceOne();
217  if (exit_event != NULL) {
218  return exit_event;
219  }
220  }
221 
222  // not reached... only exit is return on SimLoopExitEvent
223 }
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:183
async_event
volatile bool async_event
Some asynchronous event has happened.
Definition: async.cc:29
async_io
volatile bool async_io
Async I/O request (SIGIO).
Definition: async.cc:33
EventQueue::serviceOne
Event * serviceOne()
Definition: eventq.cc:197
sim_events.hh
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
async_statdump
volatile bool async_statdump
Async request to dump stats.
Definition: async.cc:30
async_exit
volatile bool async_exit
Async request to exit simulator.
Definition: async.cc:32
simulate.hh
inParallelMode
bool inParallelMode
Current mode of execution: parallel / serial.
Definition: eventq.cc:58
X86ISA::lock
Bitfield< 5 > lock
Definition: types.hh:77
async_exception
volatile bool async_exception
Python exception.
Definition: async.cc:34
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:63
asyncEventMutex
std::mutex asyncEventMutex
Mutex for handling async events.
Definition: simulate.cc:46
std::vector
STL vector class.
Definition: stl.hh:37
BaseGlobalEvent::deschedule
void deschedule()
Definition: global_event.cc:84
sim_exit.hh
GlobalSyncEvent
A special global event that synchronizes all threads and forces them to process asynchronously enqueu...
Definition: global_event.hh:205
EventQueue::nextTick
Tick nextTick() const
Definition: eventq.hh:836
async_statreset
volatile bool async_statreset
Async request to reset stats.
Definition: async.cc:31
mainEventQueue
vector< EventQueue * > mainEventQueue
Array for main event queues.
Definition: eventq.cc:56
pollQueue
PollQueue pollQueue
Definition: pollevent.cc:55
simulate_limit_event
GlobalSimLoopExitEvent * simulate_limit_event
Definition: simulate.cc:72
BaseGlobalEvent::reschedule
void reschedule(Tick when)
Definition: global_event.cc:97
Event
Definition: eventq.hh:246
GlobalSimLoopExitEvent
Definition: sim_events.hh:52
pollevent.hh
EventQueue::empty
bool empty() const
Returns true if no events are queued.
Definition: eventq.hh:891
EventQueue::handleAsyncInsertions
void handleAsyncInsertions()
Function for moving events from the async_queue to the main queue.
Definition: eventq.cc:435
exitSimLoop
void exitSimLoop(const std::string &message, int exit_code, Tick when, Tick repeat, bool serialize)
Schedule an event to exit the simulation loop (returning to Python) at the end of the current cycle (...
Definition: sim_events.cc:88
curEventQueue
EventQueue * curEventQueue()
Definition: eventq.hh:83
simulate
GlobalSimLoopExitEvent * simulate(Tick num_cycles)
Simulate for num_cycles additional cycles.
Definition: simulate.cc:80
thread_loop
static void thread_loop(EventQueue *queue)
The main function for all subordinate threads (i.e., all threads other than the main thread).
Definition: simulate.cc:64
Event::globalEvent
virtual BaseGlobalEvent * globalEvent()
If this is part of a GlobalEvent, return the pointer to the Global Event.
Definition: eventq.hh:515
Stats::schedStatEvent
void schedStatEvent(bool dump, bool reset, Tick when, Tick repeat)
Schedule statistics dumping.
Definition: stat_control.cc:237
async.hh
stat_control.hh
inform
#define inform(...)
Definition: logging.hh:240
types.hh
logging.hh
simQuantum
Tick simQuantum
Simulation Quantum for multiple eventq simulation.
Definition: eventq.cc:47
doSimLoop
Event * doSimLoop(EventQueue *)
forward declaration
Definition: simulate.cc:177
EventQueue
Queue of events sorted in time order.
Definition: eventq.hh:617
PollQueue::service
void service()
Definition: pollevent.cc:186
EventBase::Progress_Event_Pri
static const Priority Progress_Event_Pri
Progress events come at the end.
Definition: eventq.hh:221
testAndClearAsyncEvent
static bool testAndClearAsyncEvent()
Test and clear the global async_event flag, such that each time the flag is cleared,...
Definition: simulate.cc:157
numMainEventQueues
uint32_t numMainEventQueues
Current number of allocated main event queues.
Definition: eventq.cc:55
BaseGlobalEvent
Common base class for GlobalEvent and GlobalSyncEvent.
Definition: global_event.hh:60
Barrier::wait
bool wait()
Definition: barrier.hh:63
MaxTick
const Tick MaxTick
Definition: types.hh:65
Barrier
Definition: barrier.hh:43
threadBarrier
Barrier * threadBarrier
Global barrier for synchronizing threads entering/exiting the simulation loop.
Definition: simulate.cc:50
curTick
Tick curTick()
The current simulated tick.
Definition: core.hh:45
eventq.hh

Generated on Wed Sep 30 2020 14:02:14 for gem5 by doxygen 1.8.17