systemc: Catch exceptions during updates, notifications, and callbacks.
Change-Id: I6005c12ce32d24413618e3955625432985f99f69 Reviewed-on: https://gem5-review.googlesource.com/c/12607 Reviewed-by: Gabe Black <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
@@ -94,22 +94,28 @@ Kernel::regStats()
|
||||
if (scMainDone || stopAfterCallbacks)
|
||||
return;
|
||||
|
||||
for (auto m: sc_gem5::allModules)
|
||||
for (auto p: m->ports)
|
||||
p->_gem5Finalize();
|
||||
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();
|
||||
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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user