summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-09-14 20:20:54 -0700
committerGabe Black <gabeblack@google.com>2018-10-09 21:50:44 +0000
commit69a40e98d01bab5c520723f35398c29f739d226f (patch)
tree640aaca1f6f01ebf25462944fbb3e6d0d04afb39
parentf8126c66ce65a2770ce7c524d7eb0becfbb11d4b (diff)
downloadgem5-69a40e98d01bab5c520723f35398c29f739d226f.tar.xz
systemc: Change how the scheduler orders processes.
The Accellera implementation looks like it does all the methods, then all the threads, and then loops back and tries again, and there are even comments in the code that suggests that. What it actually does, however, is runs all the methods, then runs a single thread if one is waiting, and then starts over. The effect is that the scheduler will run any methods first, then run threads until a method might have become ready, and then repeat. This will actually result in more mixing of threads and methods, more context switches, and worse performance, but it makes the regressions pass more. Change-Id: I7cb0485e26eed79204ff2a3c3ded27b973e0b7b0 Reviewed-on: https://gem5-review.googlesource.com/c/12808 Reviewed-by: Gabe Black <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
-rw-r--r--src/systemc/core/scheduler.cc19
-rw-r--r--src/systemc/core/scheduler.hh20
2 files changed, 17 insertions, 22 deletions
diff --git a/src/systemc/core/scheduler.cc b/src/systemc/core/scheduler.cc
index 8a796bb5b..9deb07733 100644
--- a/src/systemc/core/scheduler.cc
+++ b/src/systemc/core/scheduler.cc
@@ -49,7 +49,7 @@ Scheduler::Scheduler() :
_elaborationDone(false), _started(false), _stopNow(false),
_status(StatusOther), maxTickEvent(this, false, MaxTickPriority),
_numCycles(0), _changeStamp(0), _current(nullptr), initDone(false),
- runOnce(false), readyList(nullptr)
+ runOnce(false)
{}
Scheduler::~Scheduler()
@@ -154,7 +154,7 @@ void
Scheduler::yield()
{
// Pull a process from the active list.
- _current = readyList->getNext();
+ _current = getNextReady();
if (!_current) {
// There are no more processes, so return control to evaluate.
Fiber::primaryFiber()->run();
@@ -266,19 +266,8 @@ Scheduler::runReady()
// The evaluation phase.
do {
- // We run methods and threads in two seperate passes to emulate how
- // Accellera orders things, but without having to scan through a
- // unified list to find the next process of the correct type.
- readyList = &readyListMethods;
- while (!readyListMethods.empty())
- yield();
-
- readyList = &readyListThreads;
- while (!readyListThreads.empty())
- yield();
-
- // We already know that readyListThreads is empty at this point.
- } while (!readyListMethods.empty());
+ yield();
+ } while (getNextReady());
if (!empty) {
_numCycles++;
diff --git a/src/systemc/core/scheduler.hh b/src/systemc/core/scheduler.hh
index 33515ea43..ad1467ea1 100644
--- a/src/systemc/core/scheduler.hh
+++ b/src/systemc/core/scheduler.hh
@@ -194,16 +194,16 @@ class Scheduler
void
runNow(Process *p)
{
- // This function may put a process on the wrong list, ie a method on
- // the process list or vice versa. That's fine since that's just a
- // performance optimization, and the important thing here is how the
- // processes are ordered.
+ // This function may put a process on the wrong list, ie a thread
+ // the method list. That's fine since that's just a performance
+ // optimization, and the important thing here is how the processes are
+ // ordered.
// If a process is running, schedule it/us to run again.
if (_current)
- readyList->pushFirst(_current);
+ readyListMethods.pushFirst(_current);
// Schedule p to run first.
- readyList->pushFirst(p);
+ readyListMethods.pushFirst(p);
yield();
}
@@ -390,6 +390,13 @@ class Scheduler
ScEvents deltas;
TimeSlots timeSlots;
+ Process *
+ getNextReady()
+ {
+ Process *p = readyListMethods.getNext();
+ return p ? p : readyListThreads.getNext();
+ }
+
void runReady();
EventWrapper<Scheduler, &Scheduler::runReady> readyEvent;
void scheduleReadyEvent();
@@ -441,7 +448,6 @@ class Scheduler
ProcessList initList;
- ProcessList *readyList;
ProcessList readyListMethods;
ProcessList readyListThreads;