diff options
author | Gabe Black <gabeblack@google.com> | 2018-07-04 22:41:29 -0700 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2018-09-05 06:04:19 +0000 |
commit | 7088d69ab5fc70fca4890e0d0169fadd2b19bab8 (patch) | |
tree | c74b56e47f903c7fb8e722393e86a28410ae2c21 /src/systemc/core/scheduler.cc | |
parent | 0aec777bf2fff0ac61cd36b7c0358dbe9350c784 (diff) | |
download | gem5-7088d69ab5fc70fca4890e0d0169fadd2b19bab8.tar.xz |
systemc: Implement channel updates and rework the scheduler.
This change implements channel updates, and also reworks the scheduler
to delegate more to the gem5 event queue by taking advantage of
event priorities to ensure things happen in the right order. There's
a lengthy comment in scheduler.hh describes how that all works.
Change-Id: I5dee71b86b2e612bb720a4429f3a72e4b7c6d01f
Reviewed-on: https://gem5-review.googlesource.com/11710
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/systemc/core/scheduler.cc')
-rw-r--r-- | src/systemc/core/scheduler.cc | 77 |
1 files changed, 53 insertions, 24 deletions
diff --git a/src/systemc/core/scheduler.cc b/src/systemc/core/scheduler.cc index 41c64f876..17e7dc43e 100644 --- a/src/systemc/core/scheduler.cc +++ b/src/systemc/core/scheduler.cc @@ -30,31 +30,22 @@ #include "systemc/core/scheduler.hh" #include "base/fiber.hh" +#include "base/logging.hh" +#include "sim/eventq.hh" namespace sc_gem5 { -Scheduler::Scheduler() : _numCycles(0), _current(nullptr) {} +Scheduler::Scheduler() : + eq(nullptr), readyEvent(this, false, EventBase::Default_Pri + 1), + _numCycles(0), _current(nullptr) +{} void -Scheduler::initialize() +Scheduler::initToReady() { - update(); - while (!initList.empty()) ready(initList.getNext()); - - delta(); -} - -void -Scheduler::runCycles() -{ - while (!readyList.empty()) { - evaluate(); - update(); - delta(); - } } void @@ -77,24 +68,62 @@ Scheduler::yield() } void -Scheduler::evaluate() +Scheduler::ready(Process *p) { - if (!readyList.empty()) - _numCycles++; + // Clump methods together to minimize context switching. + if (p->procKind() == ::sc_core::SC_METHOD_PROC_) + readyList.pushFirst(p); + else + readyList.pushLast(p); - do { - yield(); - } while (!readyList.empty()); + scheduleReadyEvent(); } void -Scheduler::update() +Scheduler::requestUpdate(Channel *c) { + updateList.pushLast(c); + scheduleReadyEvent(); } void -Scheduler::delta() +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()); + } +} + +void +Scheduler::runReady() +{ + bool empty = readyList.empty(); + + // The evaluation phase. + do { + yield(); + } while (!readyList.empty()); + + if (!empty) + _numCycles++; + + // The update phase. + update(); + + // The delta phase will happen naturally through the event queue. +} + +void +Scheduler::update() +{ + Channel *channel = updateList.getNext(); + while (channel) { + channel->popListNode(); + channel->update(); + channel = updateList.getNext(); + } } Scheduler scheduler; |