Kernel: Thread is no longer RefCounted

This makes developement with Scheduler much easier against compiler
optimizations. I could now remove the pragma GCC optimize stuff.
This commit is contained in:
Bananymous 2023-03-30 19:13:28 +03:00
parent c8f05b4a7a
commit 88ee35165f
7 changed files with 41 additions and 44 deletions

View File

@ -44,7 +44,7 @@ namespace Kernel
BAN::String working_directory() const; BAN::String working_directory() const;
BAN::ErrorOr<void> set_working_directory(BAN::StringView); BAN::ErrorOr<void> set_working_directory(BAN::StringView);
static BAN::RefPtr<Process> current() { return Thread::current()->process(); } static BAN::RefPtr<Process> current() { return Thread::current().process(); }
private: private:
Process(pid_t pid) : m_pid(pid) {} Process(pid_t pid) : m_pid(pid) {}
@ -70,7 +70,7 @@ namespace Kernel
const pid_t m_pid = 0; const pid_t m_pid = 0;
BAN::String m_working_directory; BAN::String m_working_directory;
BAN::Vector<BAN::RefPtr<Thread>> m_threads; BAN::Vector<Thread*> m_threads;
friend class BAN::RefPtr<Process>; friend class BAN::RefPtr<Process>;
}; };

View File

@ -17,7 +17,7 @@ namespace Kernel
void start(); void start();
void reschedule(); void reschedule();
BAN::ErrorOr<void> add_thread(BAN::RefPtr<Thread>); BAN::ErrorOr<void> add_thread(Thread*);
void set_current_thread_sleeping(uint64_t); void set_current_thread_sleeping(uint64_t);
[[noreturn]] void set_current_thread_done(); [[noreturn]] void set_current_thread_done();
@ -25,7 +25,7 @@ namespace Kernel
void block_current_thread(Semaphore*); void block_current_thread(Semaphore*);
void unblock_threads(Semaphore*); void unblock_threads(Semaphore*);
BAN::RefPtr<Thread> current_thread(); Thread& current_thread();
private: private:
Scheduler() = default; Scheduler() = default;
@ -39,27 +39,27 @@ namespace Kernel
private: private:
struct ActiveThread struct ActiveThread
{ {
ActiveThread(const BAN::RefPtr<Thread>& thread) : thread(thread) {} ActiveThread(Thread* thread) : thread(thread) {}
BAN::RefPtr<Thread> thread; Thread* thread;
uint64_t padding = 0; uint64_t padding;
}; };
struct SleepingThread struct SleepingThread
{ {
SleepingThread(const BAN::RefPtr<Thread>& thread, uint64_t wake_time) : thread(thread), wake_time(wake_time) {} SleepingThread(Thread* thread, uint64_t wake_time) : thread(thread), wake_time(wake_time) {}
BAN::RefPtr<Thread> thread; Thread* thread;
uint64_t wake_time; uint64_t wake_time;
}; };
struct BlockingThread struct BlockingThread
{ {
BlockingThread(const BAN::RefPtr<Thread>& thread, Semaphore* semaphore) : thread(thread), semaphore(semaphore) {} BlockingThread(Thread* thread, Semaphore* semaphore) : thread(thread), semaphore(semaphore) {}
BAN::RefPtr<Thread> thread; Thread* thread;
Semaphore* semaphore; Semaphore* semaphore;
uint8_t padding[sizeof(uint64_t) - sizeof(Semaphore*)]; uint8_t padding[sizeof(uint64_t) - sizeof(Semaphore*)];
}; };
BAN::RefPtr<Thread> m_idle_thread; Thread* m_idle_thread { nullptr };
BAN::LinkedList<ActiveThread> m_active_threads; BAN::LinkedList<ActiveThread> m_active_threads;
BAN::LinkedList<SleepingThread> m_sleeping_threads; BAN::LinkedList<SleepingThread> m_sleeping_threads;
BAN::LinkedList<BlockingThread> m_blocking_threads; BAN::LinkedList<BlockingThread> m_blocking_threads;

View File

@ -10,13 +10,16 @@ namespace Kernel
class Process; class Process;
class Thread : public BAN::RefCounted<Thread> class Thread
{ {
BAN_NON_COPYABLE(Thread);
BAN_NON_MOVABLE(Thread);
public: public:
using entry_t = void(*)(void*); using entry_t = void(*)(void*);
public: public:
static BAN::ErrorOr<BAN::RefPtr<Thread>> create(entry_t, void* = nullptr, BAN::RefPtr<Process> = nullptr); static BAN::ErrorOr<Thread*> create(entry_t, void* = nullptr, BAN::RefPtr<Process> = nullptr);
~Thread(); ~Thread();
pid_t tid() const { return m_tid; } pid_t tid() const { return m_tid; }
@ -29,7 +32,7 @@ namespace Kernel
void set_started() { m_started = true; } void set_started() { m_started = true; }
bool started() const { return m_started; } bool started() const { return m_started; }
static BAN::RefPtr<Thread> current() ; static Thread& current() ;
BAN::RefPtr<Process> process(); BAN::RefPtr<Process> process();
private: private:
@ -45,8 +48,6 @@ namespace Kernel
const pid_t m_tid = 0; const pid_t m_tid = 0;
bool m_started = false; bool m_started = false;
BAN::RefPtr<Process> m_process; BAN::RefPtr<Process> m_process;
friend class BAN::RefPtr<Thread>;
}; };
} }

View File

@ -22,7 +22,7 @@ namespace Kernel
{ {
LockGuard _(m_lock); LockGuard _(m_lock);
auto thread = TRY(Thread::create(entry, data, this)); Thread* thread = TRY(Thread::create(entry, data, this));
TRY(m_threads.push_back(thread)); TRY(m_threads.push_back(thread));
if (auto res = Scheduler::get().add_thread(thread); res.is_error()) if (auto res = Scheduler::get().add_thread(thread); res.is_error())
{ {
@ -36,9 +36,8 @@ namespace Kernel
void Process::on_thread_exit(Thread& thread) void Process::on_thread_exit(Thread& thread)
{ {
LockGuard _(m_lock); LockGuard _(m_lock);
dprintln("thread {} exit", thread.tid());
for (size_t i = 0; i < m_threads.size(); i++) for (size_t i = 0; i < m_threads.size(); i++)
if (m_threads[i].ptr() == &thread) if (m_threads[i] == &thread)
m_threads.remove(i); m_threads.remove(i);
} }

View File

@ -46,9 +46,9 @@ namespace Kernel
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
BAN::RefPtr<Thread> Scheduler::current_thread() Thread& Scheduler::current_thread()
{ {
return m_current_thread ? m_current_thread->thread : m_idle_thread; return m_current_thread ? *m_current_thread->thread : *m_idle_thread;
} }
void Scheduler::reschedule() void Scheduler::reschedule()
@ -77,17 +77,16 @@ namespace Kernel
uint64_t current_time = PIT::ms_since_boot(); uint64_t current_time = PIT::ms_since_boot();
while (!m_sleeping_threads.empty() && m_sleeping_threads.front().wake_time <= current_time) while (!m_sleeping_threads.empty() && m_sleeping_threads.front().wake_time <= current_time)
{ {
auto thread = m_sleeping_threads.front().thread; Thread* thread = m_sleeping_threads.front().thread;
m_sleeping_threads.remove(m_sleeping_threads.begin()); m_sleeping_threads.remove(m_sleeping_threads.begin());
// This should work as we released enough memory from sleeping thread // This should work as we released enough memory from sleeping thread
static_assert(sizeof(ActiveThread) == sizeof(SleepingThread)); static_assert(sizeof(ActiveThread) == sizeof(SleepingThread));
MUST(m_active_threads.emplace_back(thread)); MUST(m_active_threads.emplace_back(thread));
thread.clear();
} }
} }
BAN::ErrorOr<void> Scheduler::add_thread(BAN::RefPtr<Thread> thread) BAN::ErrorOr<void> Scheduler::add_thread(Thread* thread)
{ {
Kernel::CriticalScope critical; Kernel::CriticalScope critical;
TRY(m_active_threads.emplace_back(thread)); TRY(m_active_threads.emplace_back(thread));
@ -141,9 +140,9 @@ namespace Kernel
} }
read_rsp(rsp); read_rsp(rsp);
auto current = current_thread(); Thread& current = current_thread();
current->set_rip(rip); current.set_rip(rip);
current->set_rsp(rsp); current.set_rsp(rsp);
return false; return false;
} }
@ -151,7 +150,7 @@ namespace Kernel
{ {
VERIFY_CLI(); VERIFY_CLI();
auto& current = *current_thread(); Thread& current = current_thread();
if (current.started()) if (current.started())
{ {
@ -166,8 +165,6 @@ namespace Kernel
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
#pragma GCC push_options
#pragma GCC optimize("O0")
void Scheduler::set_current_thread_sleeping(uint64_t wake_time) void Scheduler::set_current_thread_sleeping(uint64_t wake_time)
{ {
VERIFY_STI(); VERIFY_STI();
@ -175,7 +172,7 @@ namespace Kernel
ASSERT(m_current_thread); ASSERT(m_current_thread);
auto sleeping = m_current_thread->thread; Thread* sleeping = m_current_thread->thread;
if (save_current_thread()) if (save_current_thread())
{ {
@ -192,12 +189,10 @@ namespace Kernel
// This should work as we released enough memory from active thread // This should work as we released enough memory from active thread
static_assert(sizeof(ActiveThread) == sizeof(SleepingThread)); static_assert(sizeof(ActiveThread) == sizeof(SleepingThread));
MUST(m_sleeping_threads.emplace(it, sleeping, wake_time)); MUST(m_sleeping_threads.emplace(it, sleeping, wake_time));
sleeping.clear();
execute_current_thread(); execute_current_thread();
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
#pragma GCC pop_options
void Scheduler::set_current_thread_done() void Scheduler::set_current_thread_done()
{ {
@ -205,14 +200,15 @@ namespace Kernel
DISABLE_INTERRUPTS(); DISABLE_INTERRUPTS();
ASSERT(m_current_thread); ASSERT(m_current_thread);
Thread* thread = m_current_thread->thread;
remove_and_advance_current_thread(); remove_and_advance_current_thread();
delete thread;
execute_current_thread(); execute_current_thread();
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
#pragma GCC push_options
#pragma GCC optimize("O0")
void Scheduler::block_current_thread(Semaphore* semaphore) void Scheduler::block_current_thread(Semaphore* semaphore)
{ {
VERIFY_STI(); VERIFY_STI();
@ -220,7 +216,7 @@ namespace Kernel
ASSERT(m_current_thread); ASSERT(m_current_thread);
auto blocking = m_current_thread->thread; Thread* blocking = m_current_thread->thread;
if (save_current_thread()) if (save_current_thread())
{ {
@ -232,14 +228,12 @@ namespace Kernel
// This should work as we released enough memory from active thread // This should work as we released enough memory from active thread
static_assert(sizeof(ActiveThread) == sizeof(BlockingThread)); static_assert(sizeof(ActiveThread) == sizeof(BlockingThread));
MUST(m_blocking_threads.emplace_back(blocking, semaphore)); MUST(m_blocking_threads.emplace_back(blocking, semaphore));
blocking.clear();
semaphore->m_blocked = true; semaphore->m_blocked = true;
execute_current_thread(); execute_current_thread();
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
#pragma GCC pop_options
void Scheduler::unblock_threads(Semaphore* semaphore) void Scheduler::unblock_threads(Semaphore* semaphore)
{ {

View File

@ -25,7 +25,7 @@ namespace Kernel
void RecursiveSpinLock::lock() void RecursiveSpinLock::lock()
{ {
// FIXME: is this thread safe? // FIXME: is this thread safe?
if (m_locker == Thread::current()->tid()) if (m_locker == Thread::current().tid())
{ {
m_lock_depth++; m_lock_depth++;
} }
@ -33,7 +33,7 @@ namespace Kernel
{ {
m_lock.lock(); m_lock.lock();
ASSERT(m_locker == 0); ASSERT(m_locker == 0);
m_locker = Thread::current()->tid(); m_locker = Thread::current().tid();
m_lock_depth = 1; m_lock_depth = 1;
} }
} }

View File

@ -19,10 +19,12 @@ namespace Kernel
memcpy((void*)rsp, (void*)&value, size); memcpy((void*)rsp, (void*)&value, size);
} }
BAN::ErrorOr<BAN::RefPtr<Thread>> Thread::create(entry_t entry, void* data, BAN::RefPtr<Process> process) BAN::ErrorOr<Thread*> Thread::create(entry_t entry, void* data, BAN::RefPtr<Process> process)
{ {
static pid_t next_tid = 1; static pid_t next_tid = 1;
auto thread = TRY(BAN::RefPtr<Thread>::create(next_tid++, process)); auto* thread = new Thread(next_tid++, process);
if (thread == nullptr)
return BAN::Error::from_errno(ENOMEM);
TRY(thread->initialize(entry, data)); TRY(thread->initialize(entry, data));
return thread; return thread;
} }
@ -31,7 +33,7 @@ namespace Kernel
: m_tid(tid), m_process(process) : m_tid(tid), m_process(process)
{} {}
BAN::RefPtr<Thread> Thread::current() Thread& Thread::current()
{ {
return Scheduler::get().current_thread(); return Scheduler::get().current_thread();
} }
@ -58,6 +60,7 @@ namespace Kernel
Thread::~Thread() Thread::~Thread()
{ {
dprintln("thread {} exit", tid());
kfree(m_stack_base); kfree(m_stack_base);
} }