summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2019-02-13 22:30:02 -0800
committerGabe Black <gabeblack@google.com>2019-02-21 22:34:15 +0000
commita0c0ab8c0776902945e03299e14fdca74404cf39 (patch)
tree6face98339ff7d23439eea1f866be0b72a086b19 /src
parent53cbc6b9e3b90e5ca902a7da17b5d35f73f8f5d4 (diff)
downloadgem5-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')
-rw-r--r--src/systemc/core/kernel.cc6
-rw-r--r--src/systemc/core/process_types.hh2
-rw-r--r--src/systemc/core/scheduler.cc29
-rw-r--r--src/systemc/core/scheduler.hh8
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);