gem5  v21.1.0.2
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 
45 namespace gem5
46 {
47 
49 std::mutex asyncEventMutex;
50 
54 
57 
66 static void
68 {
69  while (true) {
71  doSimLoop(queue);
72  }
73 }
74 
76 
83 simulate(Tick num_cycles)
84 {
85  // The first time simulate() is called from the Python code, we need to
86  // create a thread for each of event queues referenced by the
87  // instantiated sim objects.
88  static bool threads_initialized = false;
89  static std::vector<std::thread *> threads;
90 
91  if (!threads_initialized) {
93 
94  // the main thread (the one we're currently running on)
95  // handles queue 0, so we only need to allocate new threads
96  // for queues 1..N-1. We'll call these the "subordinate" threads.
97  for (uint32_t i = 1; i < numMainEventQueues; i++) {
98  threads.push_back(new std::thread(thread_loop, mainEventQueue[i]));
99  }
100 
101  threads_initialized = true;
103  new GlobalSimLoopExitEvent(mainEventQueue[0]->getCurTick(),
104  "simulate() limit reached", 0);
105  }
106 
107  inform("Entering event queue @ %d. Starting simulation...\n", curTick());
108 
109  if (num_cycles < MaxTick - curTick())
110  num_cycles = curTick() + num_cycles;
111  else // counter would roll over or be set to MaxTick anyhow
112  num_cycles = MaxTick;
113 
114  simulate_limit_event->reschedule(num_cycles);
115 
116  GlobalSyncEvent *quantum_event = NULL;
117  if (numMainEventQueues > 1) {
118  if (simQuantum == 0) {
119  fatal("Quantum for multi-eventq simulation not specified");
120  }
121 
122  quantum_event = new GlobalSyncEvent(curTick() + simQuantum, simQuantum,
124 
125  inParallelMode = true;
126  }
127 
128  // all subordinate (created) threads should be waiting on the
129  // barrier; the arrival of the main thread here will satisfy the
130  // barrier, and all threads will enter doSimLoop in parallel
131  threadBarrier->wait();
132  Event *local_event = doSimLoop(mainEventQueue[0]);
133  assert(local_event != NULL);
134 
135  inParallelMode = false;
136 
137  // locate the global exit event and return it to Python
138  BaseGlobalEvent *global_event = local_event->globalEvent();
139  assert(global_event != NULL);
140 
141  GlobalSimLoopExitEvent *global_exit_event =
142  dynamic_cast<GlobalSimLoopExitEvent *>(global_event);
143  assert(global_exit_event != NULL);
144 
146  if (quantum_event != NULL) {
147  quantum_event->deschedule();
148  delete quantum_event;
149  }
150 
151  return global_exit_event;
152 }
153 
159 static bool
161 {
162  bool was_set = false;
163  asyncEventMutex.lock();
164 
165  if (async_event) {
166  was_set = true;
167  async_event = false;
168  }
169 
170  asyncEventMutex.unlock();
171  return was_set;
172 }
173 
179 Event *
181 {
182  // set the per thread current eventq pointer
183  curEventQueue(eventq);
184  eventq->handleAsyncInsertions();
185 
186  while (1) {
187  // there should always be at least one event (the SimLoopExitEvent
188  // we just scheduled) in the queue
189  assert(!eventq->empty());
190  assert(curTick() <= eventq->nextTick() &&
191  "event scheduled in the past");
192 
194  // Take the event queue lock in case any of the service
195  // routines want to schedule new events.
196  std::lock_guard<EventQueue> lock(*eventq);
199  async_statdump = false;
200  async_statreset = false;
201  }
202 
203  if (async_io) {
204  async_io = false;
205  pollQueue.service();
206  }
207 
208  if (async_exit) {
209  async_exit = false;
210  exitSimLoop("user interrupt received");
211  }
212 
213  if (async_exception) {
214  async_exception = false;
215  return NULL;
216  }
217  }
218 
219  Event *exit_event = eventq->serviceOne();
220  if (exit_event != NULL) {
221  return exit_event;
222  }
223  }
224 
225  // not reached... only exit is return on SimLoopExitEvent
226 }
227 
228 } // namespace gem5
gem5::GlobalSyncEvent
A special global event that synchronizes all threads and forces them to process asynchronously enqueu...
Definition: global_event.hh:208
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:189
gem5::Barrier::wait
bool wait()
Definition: barrier.hh:66
gem5::mainEventQueue
std::vector< EventQueue * > mainEventQueue
Array for main event queues.
Definition: eventq.cc:57
sim_events.hh
gem5::pollQueue
PollQueue pollQueue
Definition: pollevent.cc:55
gem5::async_exit
volatile bool async_exit
Async request to exit simulator.
Definition: async.cc:35
simulate.hh
gem5::testAndClearAsyncEvent
static bool testAndClearAsyncEvent()
Test and clear the global async_event flag, such that each time the flag is cleared,...
Definition: simulate.cc:160
gem5::BaseGlobalEvent::reschedule
void reschedule(Tick when)
Definition: global_event.cc:100
gem5::X86ISA::lock
Bitfield< 5 > lock
Definition: types.hh:82
gem5::async_statreset
volatile bool async_statreset
Async request to reset stats.
Definition: async.cc:34
gem5::inParallelMode
bool inParallelMode
Current mode of execution: parallel / serial.
Definition: eventq.cc:59
gem5::MaxTick
const Tick MaxTick
Definition: types.hh:60
gem5::GlobalSimLoopExitEvent
Definition: sim_events.hh:55
std::vector
STL vector class.
Definition: stl.hh:37
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:66
gem5::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:67
sim_exit.hh
gem5::EventBase::Progress_Event_Pri
static const Priority Progress_Event_Pri
Progress events come at the end.
Definition: eventq.hh:226
gem5::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
gem5::async_statdump
volatile bool async_statdump
Async request to dump stats.
Definition: async.cc:33
gem5::doSimLoop
Event * doSimLoop(EventQueue *)
forward declaration
Definition: simulate.cc:180
gem5::EventQueue::handleAsyncInsertions
void handleAsyncInsertions()
Function for moving events from the async_queue to the main queue.
Definition: eventq.cc:432
gem5::BaseGlobalEvent
Common base class for GlobalEvent and GlobalSyncEvent.
Definition: global_event.hh:63
gem5::async_exception
volatile bool async_exception
Python exception.
Definition: async.cc:37
gem5::Event
Definition: eventq.hh:251
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
pollevent.hh
gem5::EventQueue::nextTick
Tick nextTick() const
Definition: eventq.hh:843
gem5::EventQueue
Queue of events sorted in time order.
Definition: eventq.hh:622
gem5::asyncEventMutex
std::mutex asyncEventMutex
Mutex for handling async events.
Definition: simulate.cc:49
gem5::Event::globalEvent
virtual BaseGlobalEvent * globalEvent()
If this is part of a GlobalEvent, return the pointer to the Global Event.
Definition: eventq.hh:520
gem5::simQuantum
Tick simQuantum
Simulation Quantum for multiple eventq simulation.
Definition: eventq.cc:48
gem5::EventQueue::empty
bool empty() const
Returns true if no events are queued.
Definition: eventq.hh:898
gem5::async_io
volatile bool async_io
Async I/O request (SIGIO).
Definition: async.cc:36
gem5::Barrier
Definition: barrier.hh:46
async.hh
gem5::BaseGlobalEvent::deschedule
void deschedule()
Definition: global_event.cc:87
stat_control.hh
gem5::simulate
GlobalSimLoopExitEvent * simulate(Tick num_cycles)
Simulate for num_cycles additional cycles.
Definition: simulate.cc:83
inform
#define inform(...)
Definition: logging.hh:246
gem5::curEventQueue
EventQueue * curEventQueue()
Definition: eventq.hh:88
types.hh
gem5::numMainEventQueues
uint32_t numMainEventQueues
Current number of allocated main event queues.
Definition: eventq.cc:56
logging.hh
gem5::PollQueue::service
void service()
Definition: pollevent.cc:186
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::EventQueue::serviceOne
Event * serviceOne()
Definition: eventq.cc:198
gem5::threadBarrier
Barrier * threadBarrier
Global barrier for synchronizing threads entering/exiting the simulation loop.
Definition: simulate.cc:53
gem5::statistics::schedStatEvent
void schedStatEvent(bool dump, bool reset, Tick when, Tick repeat)
Schedule statistics dumping.
Definition: stat_control.cc:107
gem5::async_event
volatile bool async_event
Some asynchronous event has happened.
Definition: async.cc:32
gem5::simulate_limit_event
GlobalSimLoopExitEvent * simulate_limit_event
Definition: simulate.cc:75
eventq.hh

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