diff --git a/kernel/include/kernel/CriticalScope.h b/kernel/include/kernel/CriticalScope.h new file mode 100644 index 00000000..c84dacac --- /dev/null +++ b/kernel/include/kernel/CriticalScope.h @@ -0,0 +1,30 @@ +#pragma once + +#include + +#include + +namespace Kernel +{ + + class CriticalScope + { + BAN_NON_COPYABLE(CriticalScope); + BAN_NON_MOVABLE(CriticalScope); + + public: + CriticalScope() + { + asm volatile("pushf; cli; pop %0" : "=r"(m_flags) :: "memory"); + } + + ~CriticalScope() + { + asm volatile("push %0; popf" :: "rm"(m_flags) : "memory", "cc"); + } + + private: + size_t m_flags; + }; + +} \ No newline at end of file diff --git a/kernel/include/kernel/InterruptController.h b/kernel/include/kernel/InterruptController.h index 9ea6cd20..40514f0d 100644 --- a/kernel/include/kernel/InterruptController.h +++ b/kernel/include/kernel/InterruptController.h @@ -18,6 +18,4 @@ public: static InterruptController& get(); }; -uintptr_t disable_interrupts_and_get_flags(); -void restore_flags(uintptr_t); bool interrupts_enabled(); \ No newline at end of file diff --git a/kernel/kernel/InterruptController.cpp b/kernel/kernel/InterruptController.cpp index fadff7ec..7dc1206a 100644 --- a/kernel/kernel/InterruptController.cpp +++ b/kernel/kernel/InterruptController.cpp @@ -26,18 +26,6 @@ void InterruptController::initialize(bool force_pic) s_instance = PIC::create(); } -uintptr_t disable_interrupts_and_get_flags() -{ - uintptr_t flags; - asm volatile("pushf; cli; pop %0" : "=r"(flags) :: "memory"); - return flags; -} - -void restore_flags(uintptr_t flags) -{ - asm volatile("push %0; popf" :: "rm"(flags) : "memory", "cc"); -} - bool interrupts_enabled() { uintptr_t flags; diff --git a/kernel/kernel/Scheduler.cpp b/kernel/kernel/Scheduler.cpp index fd232ded..c702cec3 100644 --- a/kernel/kernel/Scheduler.cpp +++ b/kernel/kernel/Scheduler.cpp @@ -1,10 +1,9 @@ #include #include +#include #include #include -#include - #if 1 #define VERIFY_STI() ASSERT(interrupts_enabled()) #define VERIFY_CLI() ASSERT(!interrupts_enabled()) @@ -89,10 +88,9 @@ namespace Kernel BAN::ErrorOr Scheduler::add_thread(BAN::RefPtr thread) { - auto flags = disable_interrupts_and_get_flags(); - BAN::ErrorOr result = m_active_threads.emplace_back(thread); - restore_flags(flags); - return result; + Kernel::CriticalScope critical; + TRY(m_active_threads.emplace_back(thread)); + return {}; } void Scheduler::advance_current_thread() diff --git a/kernel/kernel/Shell.cpp b/kernel/kernel/Shell.cpp index d477b2ef..fabc0560 100644 --- a/kernel/kernel/Shell.cpp +++ b/kernel/kernel/Shell.cpp @@ -195,7 +195,7 @@ argument_done: if (thread_or_error.is_error()) return TTY_PRINTLN("{}", thread_or_error.error()); - MUST(Scheduler::get().add_thread(thread)); + MUST(Scheduler::get().add_thread(thread_or_error.release_value())); while (s_thread_spinlock.is_locked()); } diff --git a/kernel/kernel/Thread.cpp b/kernel/kernel/Thread.cpp index c3a70388..3b1d8d0d 100644 --- a/kernel/kernel/Thread.cpp +++ b/kernel/kernel/Thread.cpp @@ -47,6 +47,7 @@ namespace Kernel Thread::~Thread() { + dprintln("thread {} destruct", tid()); kfree(m_stack_base); } diff --git a/kernel/kernel/kernel.cpp b/kernel/kernel/kernel.cpp index 9b50c3d1..798409c5 100644 --- a/kernel/kernel/kernel.cpp +++ b/kernel/kernel/kernel.cpp @@ -103,7 +103,6 @@ extern "C" void kernel_main() MUST(Scheduler::initialize()); Scheduler& scheduler = Scheduler::get(); - #if 1 MUST(scheduler.add_thread(MUST(Thread::create( [terminal_driver] { @@ -120,7 +119,6 @@ extern "C" void kernel_main() terminal_driver->set_font(font_or_error.release_value()); } )))); - #endif MUST(scheduler.add_thread(MUST(Thread::create( [tty1] { diff --git a/kernel/kernel/kmalloc.cpp b/kernel/kernel/kmalloc.cpp index ba52e345..9ff7b129 100644 --- a/kernel/kernel/kmalloc.cpp +++ b/kernel/kernel/kmalloc.cpp @@ -1,21 +1,13 @@ #include -#include +#include #include #include #include -#include -#include - -#include - #define MB (1 << 20) static constexpr size_t s_kmalloc_min_align = alignof(max_align_t); -static Kernel::SpinLock s_general_lock; -static Kernel::SpinLock s_fixed_lock; - struct kmalloc_node { void set_align(ptrdiff_t align) { m_align = align; } @@ -192,8 +184,6 @@ void kmalloc_dump_info() static void* kmalloc_fixed() { - Kernel::LockGuard guard(s_fixed_lock); - auto& info = s_kmalloc_fixed_info; if (!info.free_list_head) @@ -233,8 +223,6 @@ static void* kmalloc_fixed() static void* kmalloc_impl(size_t size, size_t align) { - Kernel::LockGuard guard(s_general_lock); - ASSERT(align % s_kmalloc_min_align == 0); ASSERT(size % s_kmalloc_min_align == 0); @@ -309,12 +297,15 @@ static constexpr bool is_power_of_two(size_t value) void* kmalloc(size_t size, size_t align) { + const kmalloc_info& info = s_kmalloc_info; if (size == 0 || size >= info.size) return nullptr; ASSERT(is_power_of_two(align)); + + Kernel::CriticalScope critical; // if the size fits into fixed node, we will try to use that since it is faster if (align == s_kmalloc_min_align && size <= sizeof(kmalloc_fixed_info::node::data)) @@ -334,10 +325,10 @@ void kfree(void* address) uintptr_t address_uint = (uintptr_t)address; ASSERT(address_uint % s_kmalloc_min_align == 0); + Kernel::CriticalScope critical; + if (s_kmalloc_fixed_info.base <= address_uint && address_uint < s_kmalloc_fixed_info.end) { - Kernel::LockGuard guard(s_fixed_lock); - auto& info = s_kmalloc_fixed_info; ASSERT(info.used_list_head); @@ -369,8 +360,6 @@ void kfree(void* address) } else if (s_kmalloc_info.base <= address_uint && address_uint < s_kmalloc_info.end) { - Kernel::LockGuard guard(s_general_lock); - auto& info = s_kmalloc_info; auto* node = info.from_address(address);