gem5 v24.0.0.0
Loading...
Searching...
No Matches
scheduler.cc
Go to the documentation of this file.
1/*
2 * Copyright 2018 Google, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution;
11 * neither the name of the copyright holders nor the names of its
12 * contributors may be used to endorse or promote products derived from
13 * this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
29
30#include "base/fiber.hh"
31#include "base/logging.hh"
32#include "sim/eventq.hh"
33#include "sim/sim_exit.hh"
42
43namespace sc_gem5
44{
45
47 eq(nullptr), readyEvent(*this, false, ReadyPriority),
48 pauseEvent(*this, false, PausePriority),
49 stopEvent(*this, false, StopPriority), _throwUp(nullptr),
50 starvationEvent(*this, false, StarvationPriority),
51 _elaborationDone(false), _started(false), _stopNow(false),
52 _status(StatusOther), maxTick(gem5::MaxTick),
53 maxTickEvent(*this, false, MaxTickPriority),
54 timeAdvancesEvent(*this, false, TimeAdvancesPriority), _numCycles(0),
55 _changeStamp(0), _current(nullptr), initDone(false), runToTime(true),
56 runOnce(false)
57{}
58
60{
61 // Clear out everything that belongs to us to make sure nobody tries to
62 // clear themselves out after the scheduler goes away.
63 clear();
64}
65
66void
68{
69 // Delta notifications.
70 while (!deltas.empty())
71 deltas.front()->deschedule();
72
73 // Timed notifications.
74 for (auto &ts: timeSlots) {
75 while (!ts->events.empty())
76 ts->events.front()->deschedule();
77 deschedule(ts);
78 }
79 timeSlots.clear();
80
81 // gem5 events.
86 if (stopEvent.scheduled())
94
95 Process *p;
96 while ((p = initList.getNext()))
97 p->popListNode();
98 while ((p = readyListMethods.getNext()))
99 p->popListNode();
100 while ((p = readyListThreads.getNext()))
101 p->popListNode();
102
103 Channel *c;
104 while ((c = updateList.getNext()))
105 c->popListNode();
106}
107
108void
110{
111 runUpdate();
112
113 for (Process *p = initList.getNext(); p; p = initList.getNext()) {
114 p->popListNode();
115
116 if (p->dontInitialize()) {
117 if (!p->hasStaticSensitivities() && !p->internal()) {
119 p->name());
120 }
121 } else {
122 p->ready();
123 }
124 }
125
126 runDelta();
127
128 for (auto ets: eventsToSchedule)
129 eq->schedule(ets.first, ets.second);
130 eventsToSchedule.clear();
131
132 if (_started) {
133 if (!runToTime && starved())
136 }
137
138 initDone = true;
139
141
143}
144
145void
147{
148 if (initDone) {
149 // If not marked as dontInitialize, mark as ready.
150 if (!p->dontInitialize())
151 p->ready();
152 } else {
153 // Otherwise, record that this process should be initialized once we
154 // get there.
156 }
157}
158
159void
161{
162 // Pull a process from the active list.
164 if (!_current) {
165 // There are no more processes, so return control to evaluate.
167 } else {
169 _current->scheduled(false);
170 // Switch to whatever Fiber is supposed to run this process. All
171 // Fibers which aren't running should be parked at this line.
172 _current->fiber()->run();
173 // If the current process needs to be manually started, start it.
174 if (_current && _current->needsStart()) {
175 _current->needsStart(false);
176 // If a process hasn't started yet, "resetting" it just starts it
177 // and signals its reset event.
178 if (_current->inReset())
180 try {
181 _current->run();
182 } catch (...) {
183 throwUp();
184 }
185 }
186 }
187 if (_current && !_current->needsStart()) {
188 if (_current->excWrapper) {
189 auto ew = _current->excWrapper;
190 _current->excWrapper = nullptr;
191 ew->throw_it();
192 } else if (_current->inReset()) {
193 _current->reset(false);
194 }
195 }
196}
197
198void
200{
201 if (_stopNow)
202 return;
203
204 p->scheduled(true);
205
206 if (p->procKind() == ::sc_core::SC_METHOD_PROC_)
208 else
210
211 if (!inEvaluate())
213}
214
215void
217{
218 if (initDone)
219 ready(p);
220 else
222}
223
224bool
226{
227 ListNode *n = list->nextListNode;
228 while (n != list)
229 if (n == target)
230 return true;
231 return false;
232}
233
234bool
236{
237 bool was_ready;
238 if (initDone) {
239 // After initialization, check if we're on a ready list.
240 was_ready = (p->nextListNode != nullptr);
241 p->popListNode();
242 } else {
243 // Nothing is ready before init.
244 was_ready = false;
245 }
246 return was_ready;
247}
248
249void
256
257void
259{
260 std::lock_guard<std::mutex> lock(asyncListMutex);
262 hasAsyncUpdate = true;
263}
264
265void
267{
268 // Schedule the evaluate and update phases.
269 if (!readyEvent.scheduled()) {
273 }
274}
275
276void
285
286void
288{
290
291 bool empty = readyListMethods.empty() && readyListThreads.empty();
293
294 // The evaluation phase.
296 do {
297 yield();
298 } while (getNextReady());
299 _current = nullptr;
300
301 if (!empty) {
302 _numCycles++;
303 _changeStamp++;
304 }
305
306 if (_stopNow) {
308 return;
309 }
310
311 runUpdate();
312 if (!traceFiles.empty())
313 trace(true);
314 runDelta();
315
316 if (!runToTime && starved())
318
319 if (runOnce)
321
323}
324
325void
327{
329 if (hasAsyncUpdate) {
330 std::lock_guard<std::mutex> lock(asyncListMutex);
331 Channel *channel;
332 while ((channel = asyncUpdateList.getNext()) != nullptr)
333 updateList.pushLast(channel);
334 hasAsyncUpdate = false;
335 }
336
337 try {
338 Channel *channel = updateList.getNext();
339 while (channel) {
340 channel->popListNode();
341 channel->update();
342 channel = updateList.getNext();
343 }
344 } catch (...) {
345 throwUp();
346 }
347}
348
349void
351{
353
354 try {
355 while (!deltas.empty())
356 deltas.back()->run();
357 } catch (...) {
358 throwUp();
359 }
360}
361
362void
364{
365 using namespace gem5;
366
369 runOnce = false;
370 if (scMainFiber.called()) {
371 if (!scMainFiber.finished())
373 } else {
374 if (scMainFiber.finished())
375 fatal("Pausing systemc after sc_main completed.");
376 else
377 gem5::exitSimLoopNow("systemc pause");
378 }
379}
380
381void
383{
384 using namespace gem5;
385
387 kernel->stop();
388
389 clear();
390
391 runOnce = false;
392 if (scMainFiber.called()) {
393 if (!scMainFiber.finished())
395 } else {
396 if (scMainFiber.finished())
397 fatal("Stopping systemc after sc_main completed.");
398 else
399 gem5::exitSimLoopNow("systemc stop");
400 }
401}
402
403void
404Scheduler::start(gem5::Tick max_tick, bool run_to_time)
405{
406 _started = true;
408 runToTime = run_to_time;
409
410 maxTick = max_tick;
412
413 if (initDone) {
414 if (!runToTime && starved())
417 }
418
421
422 // Return to gem5 to let it run events, etc.
424
425 if (pauseEvent.scheduled())
427 if (stopEvent.scheduled())
433
434 if (_throwUp) {
435 const ::sc_core::sc_report *to_throw = _throwUp;
436 _throwUp = nullptr;
437 throw *to_throw;
438 }
439}
440
441void
443{
444 runOnce = true;
446 start(gem5::MaxTick, false);
447}
448
449void
451{
452 if (pauseEvent.scheduled())
453 return;
454
456}
457
458void
471
472void
473Scheduler::scheduleStop(bool finish_delta)
474{
475 if (stopEvent.scheduled())
476 return;
477
478 if (!finish_delta) {
479 _stopNow = true;
480 // If we're not supposed to finish the delta cycle, flush all
481 // pending activity.
482 clear();
483 }
485}
486
487void
489{
490 for (auto tf: traceFiles)
491 tf->trace(delta);
492}
493
496
497namespace {
498
499void
500throwingReportHandler(const ::sc_core::sc_report &r,
501 const ::sc_core::sc_actions &)
502{
503 throw r;
504}
505
506} // anonymous namespace
507
508const ::sc_core::sc_report
510{
512 ::sc_core::sc_report_handler::set_handler(&throwingReportHandler);
513
514 try {
515 try {
516 // Rethrow the current exception so we can catch it and throw an
517 // sc_report instead if it's not a type we recognize/can handle.
518 throw;
519 } catch (const ::sc_core::sc_report &) {
520 // It's already a sc_report, so nothing to do.
521 throw;
522 } catch (const ::sc_core::sc_unwind_exception &) {
523 panic("Kill/reset exception escaped a Process::run()");
524 } catch (const std::exception &e) {
527 } catch (const char *msg) {
530 } catch (...) {
533 "UNKNOWN EXCEPTION");
534 }
535 } catch (const ::sc_core::sc_report &r) {
537 return r;
538 }
539 panic("No exception thrown in reportifyException.");
540}
541
542} // namespace sc_gem5
static sc_actions get_catch_actions()
static void set_handler(sc_report_handler_proc)
static sc_core::sc_status status()
Definition kernel.cc:54
static void stop()
Definition kernel.cc:143
::sc_core::sc_event & resetEvent()
Definition process.hh:101
virtual gem5::Fiber * fiber()
Definition process.hh:121
bool scheduled() const
Definition process.hh:73
void reset(bool inc_kids)
Definition process.cc:169
ExceptionWrapperBase * excWrapper
Definition process.hh:91
bool needsStart() const
Definition process.hh:66
gem5::Tick getCurTick()
Definition scheduler.hh:243
std::set< TraceFile * > traceFiles
Definition scheduler.hh:538
void resume(Process *p)
Definition scheduler.cc:216
ProcessList readyListMethods
Definition scheduler.hh:527
uint64_t _changeStamp
Definition scheduler.hh:517
bool suspend(Process *p)
Definition scheduler.cc:235
void trace(bool delta)
Definition scheduler.cc:488
void start(gem5::Tick max_tick, bool run_to_time)
Definition scheduler.cc:404
gem5::Tick lastReadyTick
Definition scheduler.hh:497
void deschedule(ScEvent *event)
Definition scheduler.hh:280
const ::sc_core::sc_report * _throwUp
Definition scheduler.hh:476
std::mutex asyncListMutex
Definition scheduler.hh:533
void scheduleStop(bool finish_delta)
Definition scheduler.cc:473
ProcessList readyListThreads
Definition scheduler.hh:528
std::map< gem5::Event *, gem5::Tick > eventsToSchedule
Definition scheduler.hh:536
ChannelList asyncUpdateList
Definition scheduler.hh:532
void asyncRequestUpdate(Channel *c)
Definition scheduler.cc:258
gem5::MemberEventWrapper<&Scheduler::timeAdvances > timeAdvancesEvent
Definition scheduler.hh:508
void schedule(ScEvent *event, const ::sc_core::sc_time &delay)
Definition scheduler.hh:253
gem5::MemberEventWrapper<&Scheduler::pause > starvationEvent
Definition scheduler.hh:487
std::atomic< bool > hasAsyncUpdate
Definition scheduler.hh:534
void ready(Process *p)
Definition scheduler.cc:199
TimeSlots timeSlots
Definition scheduler.hh:457
Process * current()
Definition scheduler.hh:185
void reg(Process *p)
Definition scheduler.cc:146
gem5::MemberEventWrapper<&Scheduler::maxTickFunc > maxTickEvent
Definition scheduler.hh:505
gem5::MemberEventWrapper<&Scheduler::stop > stopEvent
Definition scheduler.hh:474
gem5::MemberEventWrapper<&Scheduler::runReady > readyEvent
Definition scheduler.hh:468
void scheduleStarvationEvent()
Definition scheduler.cc:277
void requestUpdate(Channel *c)
Definition scheduler.cc:250
void scheduleTimeAdvancesEvent()
Definition scheduler.hh:510
Process * getNextReady()
Definition scheduler.hh:461
gem5::EventQueue * eq
Definition scheduler.hh:433
gem5::Tick maxTick
Definition scheduler.hh:496
ChannelList updateList
Definition scheduler.hh:530
void scheduleReadyEvent()
Definition scheduler.cc:266
ProcessList initList
Definition scheduler.hh:525
gem5::MemberEventWrapper<&Scheduler::pause > pauseEvent
Definition scheduler.hh:473
SwitchingFiber c
void schedule(Event *event, Tick when, bool global=false)
Schedule the given event on this queue.
Definition eventq.hh:757
bool scheduled() const
Determine if the current event is scheduled.
Definition eventq.hh:458
static Fiber * primaryFiber()
Get a pointer to the primary Fiber.
Definition fiber.cc:186
bool finished() const
Returns whether the "main" function of this fiber has finished.
Definition fiber.hh:109
void run()
Start executing the fiber represented by this object.
Definition fiber.cc:166
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:200
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
uint64_t Tick
Tick count type.
Definition types.hh:58
const Tick MaxTick
Definition types.hh:60
void exitSimLoopNow(const std::string &message, int exit_code, Tick repeat, bool serialize)
Schedule an event as above, but make it high priority so it runs before any normal events which are s...
Definition sim_events.cc:99
const char SC_ID_SIMULATION_UNCAUGHT_EXCEPTION_[]
Definition messages.cc:117
const char SC_ID_DISABLE_WILL_ORPHAN_PROCESS_[]
Definition messages.cc:132
@ SC_RUNNING
Definition sc_main.hh:87
@ SC_PAUSED
Definition sc_main.hh:88
void(* sc_report_handler_proc)(const sc_report &, const sc_actions &)
sc_core::sc_report_handler_proc reportHandlerProc
Definition report.cc:68
const ::sc_core::sc_report reportifyException()
Definition scheduler.cc:509
ScMainFiber scMainFiber
Scheduler scheduler
Definition scheduler.cc:494
Kernel * kernel
Definition kernel.cc:184
Process * getCurrentProcess()
Definition scheduler.cc:495
bool listContains(ListNode *list, ListNode *target)
Definition scheduler.cc:225
#define SC_REPORT_WARNING(msg_type, msg)
#define SC_REPORT_ERROR(msg_type, msg)
ListNode * nextListNode
Definition list.hh:47
void popListNode()
Definition list.hh:51
void pushLast(T *t)
Definition list.hh:89

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