62 lines
1.3 KiB
C++
62 lines
1.3 KiB
C++
// vim: set noet ts=4 sw=4:
|
|
|
|
#include "scheduler.h"
|
|
|
|
#include "../arch/core.h"
|
|
#include "../debug/assert.h" // IWYU pragma: keep
|
|
|
|
Scheduler::Scheduler() {}
|
|
|
|
Thread *Scheduler::getNext() {
|
|
Thread *next = readylist.dequeue();
|
|
if (next == nullptr) {
|
|
next = &idleThread;
|
|
}
|
|
|
|
assert(next != nullptr && "No thread available!");
|
|
return next;
|
|
}
|
|
|
|
void Scheduler::schedule() { dispatcher.go(getNext()); }
|
|
|
|
void Scheduler::ready(Thread *that) {
|
|
assert(that != nullptr && "nullptr pointer not allowed for ready list!");
|
|
|
|
assert(static_cast<Thread *>(&idleThread) != that &&
|
|
"IdleThread must not be placed in ready list!");
|
|
|
|
readylist.enqueue(*that);
|
|
}
|
|
|
|
void Scheduler::resume(bool ready) {
|
|
Thread *me = dispatcher.active();
|
|
assert(me != nullptr && "Pointer to active thread should never be nullptr");
|
|
|
|
if (true) {
|
|
// Be careful, never put the idle thread into the ready list
|
|
bool is_idle_thread = static_cast<Thread *>(&idleThread) == me;
|
|
|
|
if (ready && readylist.is_empty()) {
|
|
return;
|
|
} else if (!is_idle_thread) {
|
|
if (ready) readylist.enqueue(*me);
|
|
}
|
|
}
|
|
|
|
dispatcher.dispatch(getNext());
|
|
}
|
|
|
|
void Scheduler::exit() {
|
|
Thread *next = getNext();
|
|
|
|
dispatcher.dispatch(next);
|
|
}
|
|
|
|
void Scheduler::kill(Thread *that) {
|
|
if (dispatcher.active() == that) {
|
|
exit();
|
|
}
|
|
}
|
|
|
|
bool Scheduler::isEmpty() const { return readylist.is_empty(); }
|