diff options
author | Gabe Black <gabeblack@google.com> | 2019-02-13 22:30:02 -0800 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2019-02-21 22:34:15 +0000 |
commit | a0c0ab8c0776902945e03299e14fdca74404cf39 (patch) | |
tree | 6face98339ff7d23439eea1f866be0b72a086b19 /src/systemc/core | |
parent | 53cbc6b9e3b90e5ca902a7da17b5d35f73f8f5d4 (diff) | |
download | gem5-a0c0ab8c0776902945e03299e14fdca74404cf39.tar.xz |
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 <andreas.sandberg@arm.com>
Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/systemc/core')
-rw-r--r-- | src/systemc/core/kernel.cc | 6 | ||||
-rw-r--r-- | src/systemc/core/process_types.hh | 2 | ||||
-rw-r--r-- | src/systemc/core/scheduler.cc | 29 | ||||
-rw-r--r-- | 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<Scheduler, &Scheduler::pause> pauseEvent; EventWrapper<Scheduler, &Scheduler::stop> 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); |