Kernel: Improve multithreading support

We can now use arbitary BAN::function<void(...)> as the Thread.
I also implemented multithreading for i386 since it was not done
on the initial multithreading commit.
This commit is contained in:
Bananymous
2023-02-02 23:24:12 +02:00
parent 777ede328e
commit 5b5e620d8a
8 changed files with 158 additions and 88 deletions

View File

@@ -13,16 +13,26 @@ namespace Kernel
BAN_NON_MOVABLE(Scheduler);
public:
static void Initialize();
static Scheduler& Get();
static void initialize();
static Scheduler& get();
const Thread& CurrentThread() const;
const Thread& current_thread() const;
void AddThread(void(*)());
void Switch();
void Start();
template<typename... Args>
void add_thread(const BAN::Function<void(Args...)>& func, Args... args)
{
uintptr_t flags;
asm volatile("pushf; pop %0" : "=r"(flags));
asm volatile("cli");
MUST(m_threads.emplace_back(func, BAN::forward<Args>(args)...));
if (flags & (1 << 9))
asm volatile("sti");
}
static constexpr size_t ms_between_switch = 4;
void switch_thread();
void start();
static constexpr size_t ms_between_switch = 1;
private:
Scheduler() {}

View File

@@ -1,6 +1,7 @@
#pragma once
#include <BAN/Memory.h>
#include <BAN/Function.h>
#include <BAN/NoCopyMove.h>
namespace Kernel
{
@@ -20,28 +21,45 @@ namespace Kernel
};
public:
Thread(void(*)());
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpmf-conversions"
template<typename... Args>
Thread(const BAN::Function<void(Args...)>& func, Args... args)
: Thread((uintptr_t)(void*)&BAN::Function<void(Args...)>::operator(), (uintptr_t)&func, ((uintptr_t)args)...)
{
static_assert(((BAN::is_integral_v<Args> || BAN::is_pointer_v<Args>) && ...));
}
#pragma GCC diagnostic pop
~Thread();
uint32_t id() const { return m_id; }
void set_rip(uintptr_t rip) { m_rip = rip; }
void set_rsp(uintptr_t rsp) { m_rsp = rsp; }
void set_rbp(uintptr_t rbp) { m_rbp = rbp; }
void set_rip(uintptr_t rip) { m_rip = rip; }
void set_state(State state) { m_state = state; }
uintptr_t rip() const { return m_rip; }
uintptr_t rsp() const { return m_rsp; }
uintptr_t rbp() const { return m_rbp; }
uintptr_t rip() const { return m_rip; }
State state() const { return m_state; }
const uintptr_t* args() const { return m_args; }
private:
static void on_exit();
Thread(uintptr_t rip, uintptr_t func, uintptr_t arg1 = 0, uintptr_t arg2 = 0, uintptr_t arg3 = 0);
void on_exit();
private:
void* m_stack_base = nullptr;
State m_state = State::NotStarted;
uintptr_t m_args[4] = {};
uintptr_t m_rip = 0;
uintptr_t m_rbp = 0;
uintptr_t m_rsp = 0;
const uint32_t m_id = 0;
alignas(max_align_t) uint8_t m_function[BAN::Function<void()>::size()] { 0 };
};
}