From c524f21396457c55435f852bcf0bb4befb91ddba Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 7 Sep 2018 15:42:51 -0700 Subject: systemc: Catch exceptions during updates, notifications, and callbacks. Change-Id: I6005c12ce32d24413618e3955625432985f99f69 Reviewed-on: https://gem5-review.googlesource.com/c/12607 Reviewed-by: Gabe Black Maintainer: Gabe Black --- src/systemc/core/kernel.cc | 80 ++++++++++++++++++++++++++----------------- src/systemc/core/scheduler.cc | 24 +++++++++---- src/systemc/core/scheduler.hh | 12 +++++-- 3 files changed, 75 insertions(+), 41 deletions(-) (limited to 'src/systemc') diff --git a/src/systemc/core/kernel.cc b/src/systemc/core/kernel.cc index 08ccf0767..dc5a86148 100644 --- a/src/systemc/core/kernel.cc +++ b/src/systemc/core/kernel.cc @@ -94,22 +94,28 @@ Kernel::regStats() if (scMainDone || stopAfterCallbacks) return; - for (auto m: sc_gem5::allModules) - for (auto p: m->ports) - p->_gem5Finalize(); - - status(::sc_core::SC_END_OF_ELABORATION); - for (auto m: sc_gem5::allModules) { - callbackModule(m); - m->sc_mod()->end_of_elaboration(); - for (auto p: m->ports) - p->end_of_elaboration(); - for (auto e: m->exports) - e->end_of_elaboration(); + try { + for (auto m: sc_gem5::allModules) + for (auto p: m->ports) + p->_gem5Finalize(); + + status(::sc_core::SC_END_OF_ELABORATION); + for (auto m: sc_gem5::allModules) { + callbackModule(m); + m->sc_mod()->end_of_elaboration(); + for (auto p: m->ports) + p->end_of_elaboration(); + for (auto e: m->exports) + e->end_of_elaboration(); + } + callbackModule(nullptr); + for (auto c: sc_gem5::allChannels) + c->sc_chan()->end_of_elaboration(); + } catch (...) { + ::sc_gem5::scheduler.throwToScMain(); } - callbackModule(nullptr); - for (auto c: sc_gem5::allChannels) - c->sc_chan()->end_of_elaboration(); + + ::sc_gem5::scheduler.elaborationDone(true); } void @@ -123,16 +129,21 @@ Kernel::startup() if (stopAfterCallbacks) return; - status(::sc_core::SC_START_OF_SIMULATION); - for (auto m: sc_gem5::allModules) { - m->sc_mod()->start_of_simulation(); - for (auto p: m->ports) - p->start_of_simulation(); - for (auto e: m->exports) - e->start_of_simulation(); + try { + status(::sc_core::SC_START_OF_SIMULATION); + for (auto m: sc_gem5::allModules) { + m->sc_mod()->start_of_simulation(); + for (auto p: m->ports) + p->start_of_simulation(); + for (auto e: m->exports) + e->start_of_simulation(); + } + callbackModule(nullptr); + for (auto c: sc_gem5::allChannels) + c->sc_chan()->start_of_simulation(); + } catch (...) { + ::sc_gem5::scheduler.throwToScMain(); } - for (auto c: sc_gem5::allChannels) - c->sc_chan()->start_of_simulation(); startComplete = true; @@ -155,15 +166,20 @@ void Kernel::stopWork() { status(::sc_core::SC_END_OF_SIMULATION); - for (auto m: sc_gem5::allModules) { - m->sc_mod()->end_of_simulation(); - for (auto p: m->ports) - p->end_of_simulation(); - for (auto e: m->exports) - e->end_of_simulation(); + try { + for (auto m: sc_gem5::allModules) { + m->sc_mod()->end_of_simulation(); + for (auto p: m->ports) + p->end_of_simulation(); + for (auto e: m->exports) + e->end_of_simulation(); + } + callbackModule(nullptr); + for (auto c: sc_gem5::allChannels) + c->sc_chan()->end_of_simulation(); + } catch (...) { + ::sc_gem5::scheduler.throwToScMain(); } - for (auto c: sc_gem5::allChannels) - c->sc_chan()->end_of_simulation(); endComplete = true; diff --git a/src/systemc/core/scheduler.cc b/src/systemc/core/scheduler.cc index beec87d9d..801580947 100644 --- a/src/systemc/core/scheduler.cc +++ b/src/systemc/core/scheduler.cc @@ -328,11 +328,15 @@ Scheduler::runUpdate() { status(StatusUpdate); - Channel *channel = updateList.getNext(); - while (channel) { - channel->popListNode(); - channel->update(); - channel = updateList.getNext(); + try { + Channel *channel = updateList.getNext(); + while (channel) { + channel->popListNode(); + channel->update(); + channel = updateList.getNext(); + } + } catch (...) { + throwToScMain(); } } @@ -340,8 +344,13 @@ void Scheduler::runDelta() { status(StatusDelta); - while (!deltas.empty()) - deltas.front()->run(); + + try { + while (!deltas.empty()) + deltas.front()->run(); + } catch (...) { + throwToScMain(); + } } void @@ -431,6 +440,7 @@ Scheduler::throwToScMain(const ::sc_core::sc_report *r) if (!r) r = reportifyException(); _throwToScMain = r; + status(StatusOther); scMain->run(); } diff --git a/src/systemc/core/scheduler.hh b/src/systemc/core/scheduler.hh index 7b6238843..052be08c3 100644 --- a/src/systemc/core/scheduler.hh +++ b/src/systemc/core/scheduler.hh @@ -457,8 +457,16 @@ Scheduler::TimeSlot::process() { scheduler.status(StatusTiming); - while (!events.empty()) - events.front()->run(); + try { + while (!events.empty()) + events.front()->run(); + } catch (...) { + if (events.empty()) + scheduler.completeTimeSlot(this); + else + scheduler.schedule(this); + scheduler.throwToScMain(); + } scheduler.status(StatusOther); scheduler.completeTimeSlot(this); -- cgit v1.2.3