diff options
-rw-r--r-- | src/systemc/core/sched_event.hh | 29 | ||||
-rw-r--r-- | src/systemc/core/scheduler.cc | 19 | ||||
-rw-r--r-- | src/systemc/core/scheduler.hh | 25 |
3 files changed, 42 insertions, 31 deletions
diff --git a/src/systemc/core/sched_event.hh b/src/systemc/core/sched_event.hh index 9aefb7440..ca5521574 100644 --- a/src/systemc/core/sched_event.hh +++ b/src/systemc/core/sched_event.hh @@ -31,37 +31,54 @@ #define __SYSTEMC_CORE_SCHED_EVENT_HH__ #include <functional> +#include <list> #include "base/types.hh" namespace sc_gem5 { +class ScEvent; + +typedef std::list<ScEvent *> ScEvents; + class ScEvent { private: std::function<void()> work; Tick _when; - bool _scheduled; + ScEvents *_events; + ScEvents::iterator _it; friend class Scheduler; void - schedule(Tick w) + schedule(ScEvents &events, Tick w) { when(w); - _scheduled = true; + assert(!scheduled()); + _events = &events; + _events->push_back(this); + _it = _events->end(); + _it--; } - void deschedule() { _scheduled = false; } + void + deschedule() + { + assert(scheduled()); + _events->erase(_it); + _events = nullptr; + } public: ScEvent(std::function<void()> work) : - work(work), _when(MaxTick), _scheduled(false) + work(work), _when(MaxTick), _events(nullptr) {} ~ScEvent(); - bool scheduled() { return _scheduled; } + bool scheduled() { return _events != nullptr; } + ScEvents *scheduledOn() { return _events; } void when(Tick w) { _when = w; } Tick when() { return _when; } diff --git a/src/systemc/core/scheduler.cc b/src/systemc/core/scheduler.cc index e2d8e62f4..d5081c667 100644 --- a/src/systemc/core/scheduler.cc +++ b/src/systemc/core/scheduler.cc @@ -61,15 +61,14 @@ void Scheduler::clear() { // Delta notifications. - for (auto &e: deltas) - e->deschedule(); - deltas.clear(); + while (!deltas.empty()) + deltas.front()->deschedule(); // Timed notifications. for (auto &tsp: timeSlots) { TimeSlot *&ts = tsp.second; - for (auto &e: ts->events) - e->deschedule(); + while (!ts->events.empty()) + ts->events.front()->deschedule(); deschedule(ts); } timeSlots.clear(); @@ -115,9 +114,8 @@ Scheduler::initPhase() update(); - for (auto &e: deltas) - e->run(); - deltas.clear(); + while (!deltas.empty()) + deltas.front()->run(); for (auto ets: eventsToSchedule) eq->schedule(ets.first, ets.second); @@ -281,9 +279,8 @@ Scheduler::runReady() update(); // The delta phase. - for (auto &e: deltas) - e->run(); - deltas.clear(); + while (!deltas.empty()) + deltas.front()->run(); if (!runToTime && starved()) scheduleStarvationEvent(); diff --git a/src/systemc/core/scheduler.hh b/src/systemc/core/scheduler.hh index 2bee0b090..924cfb29e 100644 --- a/src/systemc/core/scheduler.hh +++ b/src/systemc/core/scheduler.hh @@ -145,7 +145,7 @@ typedef NodeList<Channel> ChannelList; class Scheduler { public: - typedef std::set<ScEvent *> ScEvents; + typedef std::list<ScEvent *> ScEvents; class TimeSlot : public ::Event { @@ -226,11 +226,9 @@ class Scheduler if (tick < getCurTick()) tick = getCurTick(); - event->schedule(tick); - // Delta notification/timeout. if (delay.value() == 0) { - deltas.insert(event); + event->schedule(deltas, tick); scheduleReadyEvent(); return; } @@ -241,19 +239,18 @@ class Scheduler ts = new TimeSlot; schedule(ts, tick); } - ts->events.insert(event); + event->schedule(ts->events, tick); } // For descheduling delayed/timed notifications/timeouts. void deschedule(ScEvent *event) { - if (event->when() == getCurTick()) { - // Attempt to remove from delta notifications. - if (deltas.erase(event) == 1) { - event->deschedule(); - return; - } + ScEvents *on = event->scheduledOn(); + + if (on == &deltas) { + event->deschedule(); + return; } // Timed notification/timeout. @@ -262,7 +259,7 @@ class Scheduler "Descheduling event at time with no events."); TimeSlot *ts = tsit->second; ScEvents &events = ts->events; - assert(events.erase(event)); + assert(on == &events); event->deschedule(); // If no more events are happening at this time slot, get rid of it. @@ -424,8 +421,8 @@ extern Scheduler scheduler; inline void Scheduler::TimeSlot::process() { - for (auto &e: events) - e->run(); + while (!events.empty()) + events.front()->run(); scheduler.completeTimeSlot(this); } |