scheduler.cc (13180:79e680f62779) scheduler.cc (13182:9e030f636a8c)
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

--- 20 unchanged lines hidden (view full) ---

29
30#include "systemc/core/scheduler.hh"
31
32#include "base/fiber.hh"
33#include "base/logging.hh"
34#include "sim/eventq.hh"
35#include "systemc/core/kernel.hh"
36#include "systemc/ext/core/sc_main.hh"
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

--- 20 unchanged lines hidden (view full) ---

29
30#include "systemc/core/scheduler.hh"
31
32#include "base/fiber.hh"
33#include "base/logging.hh"
34#include "sim/eventq.hh"
35#include "systemc/core/kernel.hh"
36#include "systemc/ext/core/sc_main.hh"
37#include "systemc/ext/utils/sc_report.hh"
38#include "systemc/ext/utils/sc_report_handler.hh"
37
38namespace sc_gem5
39{
40
41Scheduler::Scheduler() :
42 eq(nullptr), readyEvent(this, false, ReadyPriority),
43 pauseEvent(this, false, PausePriority),
44 stopEvent(this, false, StopPriority),
39
40namespace sc_gem5
41{
42
43Scheduler::Scheduler() :
44 eq(nullptr), readyEvent(this, false, ReadyPriority),
45 pauseEvent(this, false, PausePriority),
46 stopEvent(this, false, StopPriority),
45 scMain(nullptr),
47 scMain(nullptr), _throwToScMain(nullptr),
46 starvationEvent(this, false, StarvationPriority),
47 _started(false), _paused(false), _stopped(false), _stopNow(false),
48 maxTickEvent(this, false, MaxTickPriority),
49 _numCycles(0), _changeStamp(0), _current(nullptr), initDone(false),
50 runOnce(false), readyList(nullptr)
51{}
52
53Scheduler::~Scheduler()

--- 125 unchanged lines hidden (view full) ---

179 } else {
180 _current->popListNode();
181 // Switch to whatever Fiber is supposed to run this process. All
182 // Fibers which aren't running should be parked at this line.
183 _current->fiber()->run();
184 // If the current process needs to be manually started, start it.
185 if (_current && _current->needsStart()) {
186 _current->needsStart(false);
48 starvationEvent(this, false, StarvationPriority),
49 _started(false), _paused(false), _stopped(false), _stopNow(false),
50 maxTickEvent(this, false, MaxTickPriority),
51 _numCycles(0), _changeStamp(0), _current(nullptr), initDone(false),
52 runOnce(false), readyList(nullptr)
53{}
54
55Scheduler::~Scheduler()

--- 125 unchanged lines hidden (view full) ---

181 } else {
182 _current->popListNode();
183 // Switch to whatever Fiber is supposed to run this process. All
184 // Fibers which aren't running should be parked at this line.
185 _current->fiber()->run();
186 // If the current process needs to be manually started, start it.
187 if (_current && _current->needsStart()) {
188 _current->needsStart(false);
187 _current->run();
189 try {
190 _current->run();
191 } catch (...) {
192 throwToScMain();
193 }
188 }
189 }
190 if (_current && _current->excWrapper) {
191 // Make sure this isn't a method process.
192 assert(!_current->needsStart());
193 auto ew = _current->excWrapper;
194 _current->excWrapper = nullptr;
195 ew->throw_it();

--- 135 unchanged lines hidden (view full) ---

331}
332
333void
334Scheduler::pause()
335{
336 _paused = true;
337 kernel->status(::sc_core::SC_PAUSED);
338 runOnce = false;
194 }
195 }
196 if (_current && _current->excWrapper) {
197 // Make sure this isn't a method process.
198 assert(!_current->needsStart());
199 auto ew = _current->excWrapper;
200 _current->excWrapper = nullptr;
201 ew->throw_it();

--- 135 unchanged lines hidden (view full) ---

337}
338
339void
340Scheduler::pause()
341{
342 _paused = true;
343 kernel->status(::sc_core::SC_PAUSED);
344 runOnce = false;
339 scMain->run();
345 if (scMain && !scMain->finished())
346 scMain->run();
340}
341
342void
343Scheduler::stop()
344{
345 _stopped = true;
346 kernel->stop();
347
348 clear();
349
350 runOnce = false;
347}
348
349void
350Scheduler::stop()
351{
352 _stopped = true;
353 kernel->stop();
354
355 clear();
356
357 runOnce = false;
351 scMain->run();
358 if (scMain && !scMain->finished())
359 scMain->run();
352}
353
354void
355Scheduler::start(Tick max_tick, bool run_to_time)
356{
357 // We should be running from sc_main. Keep track of that Fiber to return
358 // to later.
359 scMain = Fiber::currentFiber();

--- 20 unchanged lines hidden (view full) ---

380 if (pauseEvent.scheduled())
381 deschedule(&pauseEvent);
382 if (stopEvent.scheduled())
383 deschedule(&stopEvent);
384 if (maxTickEvent.scheduled())
385 deschedule(&maxTickEvent);
386 if (starvationEvent.scheduled())
387 deschedule(&starvationEvent);
360}
361
362void
363Scheduler::start(Tick max_tick, bool run_to_time)
364{
365 // We should be running from sc_main. Keep track of that Fiber to return
366 // to later.
367 scMain = Fiber::currentFiber();

--- 20 unchanged lines hidden (view full) ---

388 if (pauseEvent.scheduled())
389 deschedule(&pauseEvent);
390 if (stopEvent.scheduled())
391 deschedule(&stopEvent);
392 if (maxTickEvent.scheduled())
393 deschedule(&maxTickEvent);
394 if (starvationEvent.scheduled())
395 deschedule(&starvationEvent);
396
397 if (_throwToScMain) {
398 const ::sc_core::sc_report *to_throw = _throwToScMain;
399 _throwToScMain = nullptr;
400 throw *to_throw;
401 }
388}
389
390void
391Scheduler::oneCycle()
392{
393 runOnce = true;
394 scheduleReadyEvent();
395 start(::MaxTick, false);

--- 4 unchanged lines hidden (view full) ---

400{
401 if (pauseEvent.scheduled())
402 return;
403
404 schedule(&pauseEvent);
405}
406
407void
402}
403
404void
405Scheduler::oneCycle()
406{
407 runOnce = true;
408 scheduleReadyEvent();
409 start(::MaxTick, false);

--- 4 unchanged lines hidden (view full) ---

414{
415 if (pauseEvent.scheduled())
416 return;
417
418 schedule(&pauseEvent);
419}
420
421void
422Scheduler::throwToScMain(const ::sc_core::sc_report *r)
423{
424 if (!r)
425 r = reportifyException();
426 _throwToScMain = r;
427 scMain->run();
428}
429
430void
408Scheduler::scheduleStop(bool finish_delta)
409{
410 if (stopEvent.scheduled())
411 return;
412
413 if (!finish_delta) {
414 _stopNow = true;
415 // If we're not supposed to finish the delta cycle, flush all
416 // pending activity.
417 clear();
418 }
419 schedule(&stopEvent);
420}
421
422Scheduler scheduler;
423
431Scheduler::scheduleStop(bool finish_delta)
432{
433 if (stopEvent.scheduled())
434 return;
435
436 if (!finish_delta) {
437 _stopNow = true;
438 // If we're not supposed to finish the delta cycle, flush all
439 // pending activity.
440 clear();
441 }
442 schedule(&stopEvent);
443}
444
445Scheduler scheduler;
446
447namespace {
448
449void
450throwingReportHandler(const ::sc_core::sc_report &r,
451 const ::sc_core::sc_actions &)
452{
453 throw r;
454}
455
456} // anonymous namespace
457
458const ::sc_core::sc_report *
459reportifyException()
460{
461 ::sc_core::sc_report_handler_proc old_handler =
462 ::sc_core::sc_report_handler::get_handler();
463 ::sc_core::sc_report_handler::set_handler(&throwingReportHandler);
464
465 try {
466 try {
467 // Rethrow the current exception so we can catch it and throw an
468 // sc_report instead if it's not a type we recognize/can handle.
469 throw;
470 } catch (const ::sc_core::sc_report &) {
471 // It's already a sc_report, so nothing to do.
472 throw;
473 } catch (const ::sc_core::sc_unwind_exception &) {
474 panic("Kill/reset exception escaped a Process::run()");
475 } catch (const std::exception &e) {
476 SC_REPORT_ERROR("uncaught exception", e.what());
477 } catch (const char *msg) {
478 SC_REPORT_ERROR("uncaught exception", msg);
479 } catch (...) {
480 SC_REPORT_ERROR("uncaught exception", "UNKNOWN EXCEPTION");
481 }
482 } catch (const ::sc_core::sc_report &r) {
483 ::sc_core::sc_report_handler::set_handler(old_handler);
484 return &r;
485 }
486 panic("No exception thrown in reportifyException.");
487}
488
424} // namespace sc_gem5
489} // namespace sc_gem5