Skip to content
Snippets Groups Projects
sched.hh 2.37 KiB
Newer Older
  • Learn to ignore specific revisions
  • Avi Kivity's avatar
    Avi Kivity committed
    #ifndef SCHED_HH_
    #define SCHED_HH_
    
    #include "arch-thread-state.hh"
    #include <functional>
    #include "tls.hh"
    #include "elf.hh"
    
    Avi Kivity's avatar
    Avi Kivity committed
    #include "drivers/clockevent.hh"
    #include <boost/intrusive/set.hpp>
    
    #include <boost/intrusive/list.hpp>
    #include "mutex.hh"
    
    Avi Kivity's avatar
    Avi Kivity committed
    
    namespace sched {
    
    class thread;
    
    Avi Kivity's avatar
    Avi Kivity committed
    void schedule(bool yield = false);
    
    Avi Kivity's avatar
    Avi Kivity committed
    
    extern "C" {
        void thread_main_c(thread* t);
    };
    
    
    namespace bi = boost::intrusive;
    
    
    Avi Kivity's avatar
    Avi Kivity committed
    class thread {
    public:
    
        struct stack_info {
            stack_info(void* begin, size_t size);
            void* begin;
            size_t size;
        };
    public:
        explicit thread(std::function<void ()> func, stack_info stack,
                bool main = false);
    
    Avi Kivity's avatar
    Avi Kivity committed
        ~thread();
        template <class Pred>
        static void wait_until(Pred pred);
        void wake();
    
    Avi Kivity's avatar
    Avi Kivity committed
        static void sleep_until(u64 abstime);
    
    Avi Kivity's avatar
    Avi Kivity committed
        static void yield();
    
    Avi Kivity's avatar
    Avi Kivity committed
        static thread* current();
    
        stack_info get_stack_info();
    
    Avi Kivity's avatar
    Avi Kivity committed
    private:
        void main();
        void switch_to();
        void prepare_wait();
        void wait();
        void stop_wait();
        void init_stack();
        void setup_tcb();
        void setup_tcb_main();
    
        static void on_thread_stack(thread* t);
        void switch_to_thread_stack();
    
    Avi Kivity's avatar
    Avi Kivity committed
    private:
        std::function<void ()> _func;
        thread_state _state;
        thread_control_block* _tcb;
        bool _on_runqueue;
        bool _waiting;
    
    Avi Kivity's avatar
    Avi Kivity committed
        friend void thread_main_c(thread* t);
        friend class wait_guard;
    
    Avi Kivity's avatar
    Avi Kivity committed
        friend void schedule(bool yield);
    
    public:
        // for the debugger
        bi::list_member_hook<> _thread_list_link;
    
    Avi Kivity's avatar
    Avi Kivity committed
    };
    
    thread* current();
    
    
    Avi Kivity's avatar
    Avi Kivity committed
    class timer;
    
    class timer_list : private clock_event_callback {
    public:
        timer_list();
        virtual void fired();
    private:
        friend class timer;
        bi::set<timer, bi::base_hook<bi::set_base_hook<>>> _list;
    };
    
    class timer : public bi::set_base_hook<> {
    public:
        explicit timer(thread& t);
        ~timer();
        void set(u64 time);
        bool expired() const;
        void cancel();
        friend bool operator<(const timer& t1, const timer& t2);
    private:
        thread& _t;
        bool _expired;
        u64 _time;
        friend class timer_list;
    };
    
    
    Avi Kivity's avatar
    Avi Kivity committed
    class wait_guard {
    public:
        wait_guard(thread* t) : _t(t) { t->prepare_wait(); }
        ~wait_guard() { _t->stop_wait(); }
    private:
        thread* _t;
    };
    
    void init(elf::program& prog);
    
    template <class Pred>
    void thread::wait_until(Pred pred)
    {
        thread* me = current();
        wait_guard waiter(me);
        while (!pred()) {
            me->wait();
        }
    }
    
    }
    
    #endif /* SCHED_HH_ */