From dcee92a6bcf0f05f37cd5cec9144002ddb5b07d7 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Thu, 30 Mar 2023 19:13:28 +0300 Subject: [PATCH] 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. --- kernel/include/kernel/Process.h | 4 ++-- kernel/include/kernel/Scheduler.h | 20 +++++++++---------- kernel/include/kernel/Thread.h | 11 ++++++----- kernel/kernel/Process.cpp | 5 ++--- kernel/kernel/Scheduler.cpp | 32 +++++++++++++------------------ kernel/kernel/SpinLock.cpp | 4 ++-- kernel/kernel/Thread.cpp | 9 ++++++--- 7 files changed, 41 insertions(+), 44 deletions(-) diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index ccb1e245..5d4facf7 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -44,7 +44,7 @@ namespace Kernel BAN::String working_directory() const; BAN::ErrorOr set_working_directory(BAN::StringView); - static BAN::RefPtr current() { return Thread::current()->process(); } + static BAN::RefPtr current() { return Thread::current().process(); } private: Process(pid_t pid) : m_pid(pid) {} @@ -70,7 +70,7 @@ namespace Kernel const pid_t m_pid = 0; BAN::String m_working_directory; - BAN::Vector> m_threads; + BAN::Vector m_threads; friend class BAN::RefPtr; }; diff --git a/kernel/include/kernel/Scheduler.h b/kernel/include/kernel/Scheduler.h index 655c7818..61dffeb7 100644 --- a/kernel/include/kernel/Scheduler.h +++ b/kernel/include/kernel/Scheduler.h @@ -17,7 +17,7 @@ namespace Kernel void start(); void reschedule(); - BAN::ErrorOr add_thread(BAN::RefPtr); + BAN::ErrorOr add_thread(Thread*); void set_current_thread_sleeping(uint64_t); [[noreturn]] void set_current_thread_done(); @@ -25,7 +25,7 @@ namespace Kernel void block_current_thread(Semaphore*); void unblock_threads(Semaphore*); - BAN::RefPtr current_thread(); + Thread& current_thread(); private: Scheduler() = default; @@ -39,27 +39,27 @@ namespace Kernel private: struct ActiveThread { - ActiveThread(const BAN::RefPtr& thread) : thread(thread) {} - BAN::RefPtr thread; - uint64_t padding = 0; + ActiveThread(Thread* thread) : thread(thread) {} + Thread* thread; + uint64_t padding; }; struct SleepingThread { - SleepingThread(const BAN::RefPtr& thread, uint64_t wake_time) : thread(thread), wake_time(wake_time) {} - BAN::RefPtr thread; + SleepingThread(Thread* thread, uint64_t wake_time) : thread(thread), wake_time(wake_time) {} + Thread* thread; uint64_t wake_time; }; struct BlockingThread { - BlockingThread(const BAN::RefPtr& thread, Semaphore* semaphore) : thread(thread), semaphore(semaphore) {} - BAN::RefPtr thread; + BlockingThread(Thread* thread, Semaphore* semaphore) : thread(thread), semaphore(semaphore) {} + Thread* thread; Semaphore* semaphore; uint8_t padding[sizeof(uint64_t) - sizeof(Semaphore*)]; }; - BAN::RefPtr m_idle_thread; + Thread* m_idle_thread { nullptr }; BAN::LinkedList m_active_threads; BAN::LinkedList m_sleeping_threads; BAN::LinkedList m_blocking_threads; diff --git a/kernel/include/kernel/Thread.h b/kernel/include/kernel/Thread.h index a2eebc09..5821fd42 100644 --- a/kernel/include/kernel/Thread.h +++ b/kernel/include/kernel/Thread.h @@ -10,13 +10,16 @@ namespace Kernel class Process; - class Thread : public BAN::RefCounted + class Thread { + BAN_NON_COPYABLE(Thread); + BAN_NON_MOVABLE(Thread); + public: using entry_t = void(*)(void*); public: - static BAN::ErrorOr> create(entry_t, void* = nullptr, BAN::RefPtr = nullptr); + static BAN::ErrorOr create(entry_t, void* = nullptr, BAN::RefPtr = nullptr); ~Thread(); pid_t tid() const { return m_tid; } @@ -29,7 +32,7 @@ namespace Kernel void set_started() { m_started = true; } bool started() const { return m_started; } - static BAN::RefPtr current() ; + static Thread& current() ; BAN::RefPtr process(); private: @@ -45,8 +48,6 @@ namespace Kernel const pid_t m_tid = 0; bool m_started = false; BAN::RefPtr m_process; - - friend class BAN::RefPtr; }; } \ No newline at end of file diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 9cbcff94..efbe7b6f 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -22,7 +22,7 @@ namespace Kernel { 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)); if (auto res = Scheduler::get().add_thread(thread); res.is_error()) { @@ -36,9 +36,8 @@ namespace Kernel void Process::on_thread_exit(Thread& thread) { LockGuard _(m_lock); - dprintln("thread {} exit", thread.tid()); 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); } diff --git a/kernel/kernel/Scheduler.cpp b/kernel/kernel/Scheduler.cpp index 7686e3df..7b65c2f9 100644 --- a/kernel/kernel/Scheduler.cpp +++ b/kernel/kernel/Scheduler.cpp @@ -46,9 +46,9 @@ namespace Kernel ASSERT_NOT_REACHED(); } - BAN::RefPtr 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() @@ -77,17 +77,16 @@ namespace Kernel uint64_t current_time = PIT::ms_since_boot(); 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()); // This should work as we released enough memory from sleeping thread static_assert(sizeof(ActiveThread) == sizeof(SleepingThread)); MUST(m_active_threads.emplace_back(thread)); - thread.clear(); } } - BAN::ErrorOr Scheduler::add_thread(BAN::RefPtr thread) + BAN::ErrorOr Scheduler::add_thread(Thread* thread) { Kernel::CriticalScope critical; TRY(m_active_threads.emplace_back(thread)); @@ -141,9 +140,9 @@ namespace Kernel } read_rsp(rsp); - auto current = current_thread(); - current->set_rip(rip); - current->set_rsp(rsp); + Thread& current = current_thread(); + current.set_rip(rip); + current.set_rsp(rsp); return false; } @@ -151,7 +150,7 @@ namespace Kernel { VERIFY_CLI(); - auto& current = *current_thread(); + Thread& current = current_thread(); if (current.started()) { @@ -166,8 +165,6 @@ namespace Kernel ASSERT_NOT_REACHED(); } -#pragma GCC push_options -#pragma GCC optimize("O0") void Scheduler::set_current_thread_sleeping(uint64_t wake_time) { VERIFY_STI(); @@ -175,7 +172,7 @@ namespace Kernel ASSERT(m_current_thread); - auto sleeping = m_current_thread->thread; + Thread* sleeping = m_current_thread->thread; if (save_current_thread()) { @@ -192,12 +189,10 @@ namespace Kernel // This should work as we released enough memory from active thread static_assert(sizeof(ActiveThread) == sizeof(SleepingThread)); MUST(m_sleeping_threads.emplace(it, sleeping, wake_time)); - sleeping.clear(); execute_current_thread(); ASSERT_NOT_REACHED(); } -#pragma GCC pop_options void Scheduler::set_current_thread_done() { @@ -205,14 +200,15 @@ namespace Kernel DISABLE_INTERRUPTS(); ASSERT(m_current_thread); + + Thread* thread = m_current_thread->thread; remove_and_advance_current_thread(); + delete thread; execute_current_thread(); ASSERT_NOT_REACHED(); } -#pragma GCC push_options -#pragma GCC optimize("O0") void Scheduler::block_current_thread(Semaphore* semaphore) { VERIFY_STI(); @@ -220,7 +216,7 @@ namespace Kernel ASSERT(m_current_thread); - auto blocking = m_current_thread->thread; + Thread* blocking = m_current_thread->thread; if (save_current_thread()) { @@ -232,14 +228,12 @@ namespace Kernel // This should work as we released enough memory from active thread static_assert(sizeof(ActiveThread) == sizeof(BlockingThread)); MUST(m_blocking_threads.emplace_back(blocking, semaphore)); - blocking.clear(); semaphore->m_blocked = true; execute_current_thread(); ASSERT_NOT_REACHED(); } -#pragma GCC pop_options void Scheduler::unblock_threads(Semaphore* semaphore) { diff --git a/kernel/kernel/SpinLock.cpp b/kernel/kernel/SpinLock.cpp index 9ddffa98..3d77e4c7 100644 --- a/kernel/kernel/SpinLock.cpp +++ b/kernel/kernel/SpinLock.cpp @@ -25,7 +25,7 @@ namespace Kernel void RecursiveSpinLock::lock() { // FIXME: is this thread safe? - if (m_locker == Thread::current()->tid()) + if (m_locker == Thread::current().tid()) { m_lock_depth++; } @@ -33,7 +33,7 @@ namespace Kernel { m_lock.lock(); ASSERT(m_locker == 0); - m_locker = Thread::current()->tid(); + m_locker = Thread::current().tid(); m_lock_depth = 1; } } diff --git a/kernel/kernel/Thread.cpp b/kernel/kernel/Thread.cpp index 2107a6c0..db7cd34c 100644 --- a/kernel/kernel/Thread.cpp +++ b/kernel/kernel/Thread.cpp @@ -19,10 +19,12 @@ namespace Kernel memcpy((void*)rsp, (void*)&value, size); } - BAN::ErrorOr> Thread::create(entry_t entry, void* data, BAN::RefPtr process) + BAN::ErrorOr Thread::create(entry_t entry, void* data, BAN::RefPtr process) { static pid_t next_tid = 1; - auto thread = TRY(BAN::RefPtr::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)); return thread; } @@ -31,7 +33,7 @@ namespace Kernel : m_tid(tid), m_process(process) {} - BAN::RefPtr Thread::current() + Thread& Thread::current() { return Scheduler::get().current_thread(); } @@ -58,6 +60,7 @@ namespace Kernel Thread::~Thread() { + dprintln("thread {} exit", tid()); kfree(m_stack_base); }