summaryrefslogtreecommitdiff
path: root/src/systemc/core/scheduler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemc/core/scheduler.cc')
-rw-r--r--src/systemc/core/scheduler.cc77
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;