systemc: Fill out process handle kill and reset mechanisms.

Some flags were being updated too early, making the functions think
what they were about to do had already been done. Also, actually check
for and throw the exception installed in a process when it's next
supposed to run, and when injecting an exception schedule that other
process to run immediately.

Change-Id: I0856b69903699b2c66f9dc7f44942bbfe3cfdcc4
Reviewed-on: https://gem5-review.googlesource.com/12046
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
Gabe Black
2018-07-20 22:16:12 -07:00
parent e58072108f
commit e27712b2d9
2 changed files with 22 additions and 13 deletions

View File

@@ -108,15 +108,13 @@ SensitivityEventOrList::~SensitivityEventOrList()
class UnwindExceptionReset : public ::sc_core::sc_unwind_exception
{
public:
const char *what() const throw() override { return "RESET"; }
bool is_reset() const override { return true; }
UnwindExceptionReset() { _isReset = true; }
};
class UnwindExceptionKill : public ::sc_core::sc_unwind_exception
{
public:
const char *what() const throw() override { return "KILL"; }
bool is_reset() const override { return false; }
UnwindExceptionKill() {}
};
template <typename T>
@@ -194,10 +192,6 @@ Process::enable(bool inc_kids)
void
Process::kill(bool inc_kids)
{
// Update our state.
_terminated = true;
_isUnwinding = true;
// Propogate the kill to our children no matter what happens to us.
if (inc_kids)
forEachKid([](Process *p) { p->kill(true); });
@@ -206,6 +200,13 @@ Process::kill(bool inc_kids)
if (_isUnwinding)
return;
// Update our state.
_terminated = true;
_isUnwinding = true;
_suspendedReady = false;
_suspended = false;
_syncReset = false;
// Inject the kill exception into this process.
injectException(killException);
@@ -215,9 +216,6 @@ Process::kill(bool inc_kids)
void
Process::reset(bool inc_kids)
{
// Update our state.
_isUnwinding = true;
// Propogate the reset to our children no matter what happens to us.
if (inc_kids)
forEachKid([](Process *p) { p->reset(true); });
@@ -226,6 +224,9 @@ Process::reset(bool inc_kids)
if (_isUnwinding)
return;
// Update our state.
_isUnwinding = true;
// Inject the reset exception into this process.
injectException(resetException);
@@ -243,7 +244,7 @@ void
Process::injectException(ExceptionWrapperBase &exc)
{
excWrapper = &exc;
// Let this process preempt us.
scheduler.runNow(this);
};
void
@@ -289,8 +290,9 @@ Process::run()
reset = false;
try {
func->call();
} catch(::sc_core::sc_unwind_exception exc) {
} catch(const ::sc_core::sc_unwind_exception &exc) {
reset = exc.is_reset();
_isUnwinding = false;
}
} while (reset);
_terminated = true;

View File

@@ -117,6 +117,13 @@ Scheduler::yield()
if (_current && _current->needsStart())
_current->run();
}
if (_current && _current->excWrapper) {
// Make sure this isn't a method process.
assert(!_current->needsStart());
auto ew = _current->excWrapper;
_current->excWrapper = nullptr;
ew->throw_it();
}
}
void