From 7088d69ab5fc70fca4890e0d0169fadd2b19bab8 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 4 Jul 2018 22:41:29 -0700 Subject: 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 Maintainer: Gabe Black --- src/systemc/core/scheduler.cc | 77 +++++++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 24 deletions(-) (limited to 'src/systemc/core/scheduler.cc') 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; -- cgit v1.2.3