systemc: Generalize gem5 style event scheduling.

These events are either scheduled directly, or if no event queue is
yet available they're recorded in a map to schedule later. Since this
was used in a few places (and should have been used for the ready
event), this change moves it into some common functions which remove
some duplication and abstract away this detail.

Change-Id: I4320d7296f4f72344539b2b4b2564a6a27576dd8
Reviewed-on: https://gem5-review.googlesource.com/12219
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
Gabe Black
2018-08-17 17:48:56 -07:00
parent a56dbe9338
commit e752df7015
2 changed files with 31 additions and 21 deletions

View File

@@ -77,7 +77,7 @@ Scheduler::initPhase()
if (_started) {
if (starved() && !runToTime)
scheduleStarvationEvent();
eq->schedule(&maxTickEvent, maxTick);
kernel->status(::sc_core::SC_RUNNING);
}
initDone = true;
@@ -153,8 +153,7 @@ void
Scheduler::requestUpdate(Channel *c)
{
updateList.pushLast(c);
if (eq)
scheduleReadyEvent();
scheduleReadyEvent();
}
void
@@ -162,10 +161,9 @@ Scheduler::scheduleReadyEvent()
{
// Schedule the evaluate and update phases.
if (!readyEvent.scheduled()) {
panic_if(!eq, "Need to schedule ready, but no event manager.\n");
eq->schedule(&readyEvent, eq->getCurTick());
schedule(&readyEvent);
if (starvationEvent.scheduled())
eq->deschedule(&starvationEvent);
deschedule(&starvationEvent);
}
}
@@ -173,13 +171,9 @@ void
Scheduler::scheduleStarvationEvent()
{
if (!starvationEvent.scheduled()) {
Tick now = getCurTick();
if (initDone)
eq->schedule(&starvationEvent, now);
else
eventsToSchedule[&starvationEvent] = now;
schedule(&starvationEvent);
if (readyEvent.scheduled())
eq->deschedule(&readyEvent);
deschedule(&readyEvent);
}
}
@@ -258,9 +252,10 @@ Scheduler::start(Tick max_tick, bool run_to_time)
if (starved() && !runToTime)
scheduleStarvationEvent();
kernel->status(::sc_core::SC_RUNNING);
eq->schedule(&maxTickEvent, maxTick);
}
schedule(&maxTickEvent, maxTick);
// Return to gem5 to let it run events, etc.
Fiber::primaryFiber()->run();

View File

@@ -225,10 +225,7 @@ class Scheduler
TimeSlot *&ts = timeSlots[tick];
if (!ts) {
ts = new TimeSlot;
if (initDone)
eq->schedule(ts, tick);
else
eventsToSchedule[ts] = tick;
schedule(ts, tick);
}
ts->events.insert(event);
}
@@ -255,10 +252,7 @@ class Scheduler
// If no more events are happening at this time slot, get rid of it.
if (events.empty()) {
if (initDone)
eq->deschedule(ts);
else
eventsToSchedule.erase(ts);
deschedule(ts);
timeSlots.erase(tsit);
}
}
@@ -328,6 +322,27 @@ class Scheduler
EventQueue *eq;
// For gem5 style events.
void
schedule(::Event *event, Tick tick)
{
if (initDone)
eq->schedule(event, tick);
else
eventsToSchedule[event] = tick;
}
void schedule(::Event *event) { schedule(event, getCurTick()); }
void
deschedule(::Event *event)
{
if (initDone)
eq->deschedule(event);
else
eventsToSchedule.erase(event);
}
ScEvents deltas;
TimeSlots timeSlots;