diff --git a/kernel/include/kernel/Lock/SpinLock.h b/kernel/include/kernel/Lock/SpinLock.h index 0974a682..5e91e704 100644 --- a/kernel/include/kernel/Lock/SpinLock.h +++ b/kernel/include/kernel/Lock/SpinLock.h @@ -2,7 +2,7 @@ #include #include -#include +#include #include @@ -21,7 +21,7 @@ namespace Kernel void unlock(InterruptState state); private: - BAN::Atomic m_locker { -1 }; + BAN::Atomic m_locker { PROCESSOR_NONE }; }; class RecursiveSpinLock @@ -36,8 +36,8 @@ namespace Kernel void unlock(InterruptState state); private: - BAN::Atomic m_locker { -1 }; - uint32_t m_lock_depth { 0 }; + BAN::Atomic m_locker { PROCESSOR_NONE }; + uint32_t m_lock_depth { 0 }; }; class SpinLockUnsafe @@ -50,10 +50,12 @@ namespace Kernel InterruptState lock() { + auto id = get_processor_id(); + auto state = get_interrupt_state(); set_interrupt_state(InterruptState::Disabled); - while (!m_locked.compare_exchange(false, true)) + while (!m_locker.compare_exchange(PROCESSOR_NONE, id, BAN::MemoryOrder::memory_order_acquire)) __builtin_ia32_pause(); return state; @@ -61,14 +63,14 @@ namespace Kernel void unlock(InterruptState state) { - m_locked.store(false); + m_locker.store(PROCESSOR_NONE, BAN::MemoryOrder::memory_order_release); set_interrupt_state(state); } - bool is_locked() const { return m_locked; } + bool is_locked() const { return m_locker != PROCESSOR_NONE; } private: - BAN::Atomic m_locked; + BAN::Atomic m_locker { PROCESSOR_NONE }; }; template diff --git a/kernel/include/kernel/Interrupts.h b/kernel/include/kernel/Processor.h similarity index 74% rename from kernel/include/kernel/Interrupts.h rename to kernel/include/kernel/Processor.h index c5285ef5..6a9fa620 100644 --- a/kernel/include/kernel/Interrupts.h +++ b/kernel/include/kernel/Processor.h @@ -30,6 +30,15 @@ namespace Kernel return InterruptState::Disabled; } + using ProcessorID = uint8_t; + constexpr ProcessorID PROCESSOR_NONE = 0xFF; + inline ProcessorID get_processor_id() + { + uint16_t id; + asm volatile("movw %%gs, %0" : "=rm"(id)); + return id; + } + #else #error "Unknown architecure" #endif diff --git a/kernel/kernel/Lock/SpinLock.cpp b/kernel/kernel/Lock/SpinLock.cpp index aaf12742..8b613a63 100644 --- a/kernel/kernel/Lock/SpinLock.cpp +++ b/kernel/kernel/Lock/SpinLock.cpp @@ -9,38 +9,38 @@ namespace Kernel InterruptState SpinLock::lock() { - auto tid = Scheduler::current_tid(); - ASSERT_NEQ(m_locker.load(), tid); + auto id = get_processor_id(); + ASSERT_NEQ(m_locker.load(), id); auto state = get_interrupt_state(); set_interrupt_state(InterruptState::Disabled); - if (!m_locker.compare_exchange(-1, tid)) - ASSERT_NOT_REACHED(); + while (!m_locker.compare_exchange(PROCESSOR_NONE, id, BAN::MemoryOrder::memory_order_acquire)) + __builtin_ia32_pause(); return state; } void SpinLock::unlock(InterruptState state) { - ASSERT_EQ(m_locker.load(), Scheduler::current_tid()); - m_locker.store(-1); + ASSERT_EQ(m_locker.load(), get_processor_id()); + m_locker.store(PROCESSOR_NONE, BAN::MemoryOrder::memory_order_release); set_interrupt_state(state); } InterruptState RecursiveSpinLock::lock() { - auto tid = Scheduler::current_tid(); + auto id = get_processor_id(); auto state = get_interrupt_state(); set_interrupt_state(InterruptState::Disabled); - if (tid == m_locker) + if (id == m_locker) ASSERT_GT(m_lock_depth, 0); else { - if (!m_locker.compare_exchange(-1, tid)) - ASSERT_NOT_REACHED(); + while (!m_locker.compare_exchange(PROCESSOR_NONE, id, BAN::MemoryOrder::memory_order_acquire)) + __builtin_ia32_pause(); ASSERT_EQ(m_lock_depth, 0); } @@ -51,11 +51,10 @@ namespace Kernel void RecursiveSpinLock::unlock(InterruptState state) { - auto tid = Scheduler::current_tid(); - ASSERT_EQ(m_locker.load(), tid); + ASSERT_EQ(m_locker.load(), get_processor_id()); ASSERT_GT(m_lock_depth, 0); if (--m_lock_depth == 0) - m_locker = -1; + m_locker.store(PROCESSOR_NONE, BAN::MemoryOrder::memory_order_release); set_interrupt_state(state); }