From a0c0ab8c0776902945e03299e14fdca74404cf39 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 13 Feb 2019 22:30:02 -0800 Subject: [PATCH] systemc: Handle exceptions "correctly" even if sc_main hasn't been run. If sc_main hasn't run, for instance if there isn't an sc_main and gem5 is orchestrating the simulation directly, then exceptions shouldn't be thrown to the sc_main fiber since it isn't running and may not be able to run since sc_main may not even exist. Instead, we need to check whether it makes sense to throw to sc_main, and if not pass the exception directly to the report handler since there likely won't be anyone to catch it if we just throw it from the scheduler or into general purpose gem5. Since the name throwToScMain is no longer a complete description for what that function does, this change renames it to throwUp, since it will now throw exceptions up the stack, either to sc_main or to the conceptual top level by going directly to the report handler. Change-Id: Ibdc92c9cf213ec6aa15ad654862057b7bf2e1c8e Reviewed-on: https://gem5-review.googlesource.com/c/16442 Reviewed-by: Andreas Sandberg Maintainer: Gabe Black --- src/systemc/core/kernel.cc | 6 +++--- src/systemc/core/process_types.hh | 2 +- src/systemc/core/scheduler.cc | 29 +++++++++++++++++------------ src/systemc/core/scheduler.hh | 8 +++++--- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/systemc/core/kernel.cc b/src/systemc/core/kernel.cc index 2fd3027da..13e69d1f4 100644 --- a/src/systemc/core/kernel.cc +++ b/src/systemc/core/kernel.cc @@ -103,7 +103,7 @@ Kernel::regStats() for (auto c: sc_gem5::allChannels) c->sc_chan()->end_of_elaboration(); } catch (...) { - ::sc_gem5::scheduler.throwToScMain(); + ::sc_gem5::scheduler.throwUp(); } } @@ -127,7 +127,7 @@ Kernel::startup() for (auto c: sc_gem5::allChannels) c->sc_chan()->start_of_simulation(); } catch (...) { - ::sc_gem5::scheduler.throwToScMain(); + ::sc_gem5::scheduler.throwUp(); } startComplete = true; @@ -159,7 +159,7 @@ Kernel::stopWork() for (auto c: sc_gem5::allChannels) c->sc_chan()->end_of_simulation(); } catch (...) { - ::sc_gem5::scheduler.throwToScMain(); + ::sc_gem5::scheduler.throwUp(); } endComplete = true; diff --git a/src/systemc/core/process_types.hh b/src/systemc/core/process_types.hh index 1361e9745..c14ec1f4f 100644 --- a/src/systemc/core/process_types.hh +++ b/src/systemc/core/process_types.hh @@ -94,7 +94,7 @@ class Thread : public Process thread->run(); } catch (...) { thread->terminate(); - scheduler.throwToScMain(); + scheduler.throwUp(); return; } thread->terminate(); diff --git a/src/systemc/core/scheduler.cc b/src/systemc/core/scheduler.cc index 465da552f..4b566ca20 100644 --- a/src/systemc/core/scheduler.cc +++ b/src/systemc/core/scheduler.cc @@ -47,7 +47,7 @@ namespace sc_gem5 Scheduler::Scheduler() : eq(nullptr), readyEvent(this, false, ReadyPriority), pauseEvent(this, false, PausePriority), - stopEvent(this, false, StopPriority), _throwToScMain(nullptr), + stopEvent(this, false, StopPriority), _throwUp(nullptr), starvationEvent(this, false, StarvationPriority), _elaborationDone(false), _started(false), _stopNow(false), _status(StatusOther), maxTickEvent(this, false, MaxTickPriority), @@ -180,7 +180,7 @@ Scheduler::yield() try { _current->run(); } catch (...) { - throwToScMain(); + throwUp(); } } } @@ -327,7 +327,7 @@ Scheduler::runUpdate() channel = updateList.getNext(); } } catch (...) { - throwToScMain(); + throwUp(); } } @@ -340,7 +340,7 @@ Scheduler::runDelta() while (!deltas.empty()) deltas.back()->run(); } catch (...) { - throwToScMain(); + throwUp(); } } @@ -398,9 +398,9 @@ Scheduler::start(Tick max_tick, bool run_to_time) if (starvationEvent.scheduled()) deschedule(&starvationEvent); - if (_throwToScMain) { - const ::sc_core::sc_report *to_throw = _throwToScMain; - _throwToScMain = nullptr; + if (_throwUp) { + const ::sc_core::sc_report *to_throw = _throwUp; + _throwUp = nullptr; throw *to_throw; } } @@ -423,12 +423,17 @@ Scheduler::schedulePause() } void -Scheduler::throwToScMain() +Scheduler::throwUp() { - ::sc_core::sc_report report = reportifyException(); - _throwToScMain = &report; - status(StatusOther); - scMainFiber.run(); + if (scMainFiber.called() && !scMainFiber.finished()) { + ::sc_core::sc_report report = reportifyException(); + _throwUp = &report; + status(StatusOther); + scMainFiber.run(); + } else { + reportHandlerProc(reportifyException(), + ::sc_core::sc_report_handler::get_catch_actions()); + } } void diff --git a/src/systemc/core/scheduler.hh b/src/systemc/core/scheduler.hh index 64841086d..63f6ac35d 100644 --- a/src/systemc/core/scheduler.hh +++ b/src/systemc/core/scheduler.hh @@ -363,7 +363,9 @@ class Scheduler uint64_t changeStamp() { return _changeStamp; } void stepChangeStamp() { _changeStamp++; } - void throwToScMain(); + // Throw upwards, either to sc_main or to the report handler if sc_main + // isn't running. + void throwUp(); Status status() { return _status; } void status(Status s) { _status = s; } @@ -424,7 +426,7 @@ class Scheduler EventWrapper pauseEvent; EventWrapper stopEvent; - const ::sc_core::sc_report *_throwToScMain; + const ::sc_core::sc_report *_throwUp; bool starved() @@ -505,7 +507,7 @@ Scheduler::TimeSlot::process() scheduler.completeTimeSlot(this); else scheduler.schedule(this); - scheduler.throwToScMain(); + scheduler.throwUp(); } scheduler.status(StatusOther); -- 2.30.2