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/Atomic.h>
|
||||||
#include <BAN/NoCopyMove.h>
|
#include <BAN/NoCopyMove.h>
|
||||||
#include <kernel/Interrupts.h>
|
#include <kernel/Processor.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ namespace Kernel
|
||||||
void unlock(InterruptState state);
|
void unlock(InterruptState state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BAN::Atomic<pid_t> m_locker { -1 };
|
BAN::Atomic<ProcessorID> m_locker { PROCESSOR_NONE };
|
||||||
};
|
};
|
||||||
|
|
||||||
class RecursiveSpinLock
|
class RecursiveSpinLock
|
||||||
|
@ -36,8 +36,8 @@ namespace Kernel
|
||||||
void unlock(InterruptState state);
|
void unlock(InterruptState state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BAN::Atomic<pid_t> m_locker { -1 };
|
BAN::Atomic<ProcessorID> m_locker { PROCESSOR_NONE };
|
||||||
uint32_t m_lock_depth { 0 };
|
uint32_t m_lock_depth { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
class SpinLockUnsafe
|
class SpinLockUnsafe
|
||||||
|
@ -50,10 +50,12 @@ namespace Kernel
|
||||||
|
|
||||||
InterruptState lock()
|
InterruptState lock()
|
||||||
{
|
{
|
||||||
|
auto id = get_processor_id();
|
||||||
|
|
||||||
auto state = get_interrupt_state();
|
auto state = get_interrupt_state();
|
||||||
set_interrupt_state(InterruptState::Disabled);
|
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();
|
__builtin_ia32_pause();
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
|
@ -61,14 +63,14 @@ namespace Kernel
|
||||||
|
|
||||||
void unlock(InterruptState state)
|
void unlock(InterruptState state)
|
||||||
{
|
{
|
||||||
m_locked.store(false);
|
m_locker.store(PROCESSOR_NONE, BAN::MemoryOrder::memory_order_release);
|
||||||
set_interrupt_state(state);
|
set_interrupt_state(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_locked() const { return m_locked; }
|
bool is_locked() const { return m_locker != PROCESSOR_NONE; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BAN::Atomic<bool> m_locked;
|
BAN::Atomic<ProcessorID> m_locker { PROCESSOR_NONE };
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Lock>
|
template<typename Lock>
|
||||||
|
|
|
@ -30,6 +30,15 @@ namespace Kernel
|
||||||
return InterruptState::Disabled;
|
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
|
#else
|
||||||
#error "Unknown architecure"
|
#error "Unknown architecure"
|
||||||
#endif
|
#endif
|
|
@ -9,38 +9,38 @@ namespace Kernel
|
||||||
|
|
||||||
InterruptState SpinLock::lock()
|
InterruptState SpinLock::lock()
|
||||||
{
|
{
|
||||||
auto tid = Scheduler::current_tid();
|
auto id = get_processor_id();
|
||||||
ASSERT_NEQ(m_locker.load(), tid);
|
ASSERT_NEQ(m_locker.load(), id);
|
||||||
|
|
||||||
auto state = get_interrupt_state();
|
auto state = get_interrupt_state();
|
||||||
set_interrupt_state(InterruptState::Disabled);
|
set_interrupt_state(InterruptState::Disabled);
|
||||||
|
|
||||||
if (!m_locker.compare_exchange(-1, tid))
|
while (!m_locker.compare_exchange(PROCESSOR_NONE, id, BAN::MemoryOrder::memory_order_acquire))
|
||||||
ASSERT_NOT_REACHED();
|
__builtin_ia32_pause();
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpinLock::unlock(InterruptState state)
|
void SpinLock::unlock(InterruptState state)
|
||||||
{
|
{
|
||||||
ASSERT_EQ(m_locker.load(), Scheduler::current_tid());
|
ASSERT_EQ(m_locker.load(), get_processor_id());
|
||||||
m_locker.store(-1);
|
m_locker.store(PROCESSOR_NONE, BAN::MemoryOrder::memory_order_release);
|
||||||
set_interrupt_state(state);
|
set_interrupt_state(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
InterruptState RecursiveSpinLock::lock()
|
InterruptState RecursiveSpinLock::lock()
|
||||||
{
|
{
|
||||||
auto tid = Scheduler::current_tid();
|
auto id = get_processor_id();
|
||||||
|
|
||||||
auto state = get_interrupt_state();
|
auto state = get_interrupt_state();
|
||||||
set_interrupt_state(InterruptState::Disabled);
|
set_interrupt_state(InterruptState::Disabled);
|
||||||
|
|
||||||
if (tid == m_locker)
|
if (id == m_locker)
|
||||||
ASSERT_GT(m_lock_depth, 0);
|
ASSERT_GT(m_lock_depth, 0);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!m_locker.compare_exchange(-1, tid))
|
while (!m_locker.compare_exchange(PROCESSOR_NONE, id, BAN::MemoryOrder::memory_order_acquire))
|
||||||
ASSERT_NOT_REACHED();
|
__builtin_ia32_pause();
|
||||||
ASSERT_EQ(m_lock_depth, 0);
|
ASSERT_EQ(m_lock_depth, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,11 +51,10 @@ namespace Kernel
|
||||||
|
|
||||||
void RecursiveSpinLock::unlock(InterruptState state)
|
void RecursiveSpinLock::unlock(InterruptState state)
|
||||||
{
|
{
|
||||||
auto tid = Scheduler::current_tid();
|
ASSERT_EQ(m_locker.load(), get_processor_id());
|
||||||
ASSERT_EQ(m_locker.load(), tid);
|
|
||||||
ASSERT_GT(m_lock_depth, 0);
|
ASSERT_GT(m_lock_depth, 0);
|
||||||
if (--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);
|
set_interrupt_state(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue