Kernel: Move interrupt status stuff to Processor.h
SpinLocks are now locked with processor id instead of thread id. This allows having multiple processors running while scheduler is not yet activated.
This commit is contained in:
parent
efd8203232
commit
1de9daa40f
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <BAN/Atomic.h>
|
||||
#include <BAN/NoCopyMove.h>
|
||||
#include <kernel/Interrupts.h>
|
||||
#include <kernel/Processor.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
|
@ -21,7 +21,7 @@ namespace Kernel
|
|||
void unlock(InterruptState state);
|
||||
|
||||
private:
|
||||
BAN::Atomic<pid_t> m_locker { -1 };
|
||||
BAN::Atomic<ProcessorID> m_locker { PROCESSOR_NONE };
|
||||
};
|
||||
|
||||
class RecursiveSpinLock
|
||||
|
@ -36,8 +36,8 @@ namespace Kernel
|
|||
void unlock(InterruptState state);
|
||||
|
||||
private:
|
||||
BAN::Atomic<pid_t> m_locker { -1 };
|
||||
uint32_t m_lock_depth { 0 };
|
||||
BAN::Atomic<ProcessorID> 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<bool> m_locked;
|
||||
BAN::Atomic<ProcessorID> m_locker { PROCESSOR_NONE };
|
||||
};
|
||||
|
||||
template<typename Lock>
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue