#include "sched.hh" #include <list> #include "mutex.hh" #include <mutex> #include "debug.hh" namespace sched { std::list<thread*> runqueue; thread __thread * s_current; elf::tls_data tls; } #include "arch-switch.hh" namespace sched { void schedule() { thread* p = thread::current(); if (!p->_waiting) { return; } assert(!runqueue.empty()); thread* n = runqueue.front(); runqueue.pop_front(); assert(!n->_waiting); n->_on_runqueue = false; n->switch_to(); } thread::thread(std::function<void ()> func, bool main) : _func(func) , _on_runqueue(true) , _waiting(false) { if (!main) { setup_tcb(); init_stack(); runqueue.push_back(this); } else { setup_tcb_main(); s_current = this; func(); abort(); } } thread::~thread() { debug("thread dtor"); } void thread::prepare_wait() { _waiting = true; } void thread::wake() { if (!_waiting) { return; } _waiting = false; if (!_on_runqueue) { _on_runqueue = true; runqueue.push_back(this); schedule(); } } void thread::main() { _func(); } thread* thread::current() { return sched::s_current; } void thread::wait() { if (!_waiting) { return; } schedule(); } void thread::stop_wait() { _waiting = false; } void init(elf::program& prog) { tls = prog.tls(); } }