From f538d035e2c3656c600e8e5fdd8c267bc960bb99 Mon Sep 17 00:00:00 2001 From: Aiken Harris Date: Mon, 27 Oct 2025 20:48:44 +0100 Subject: [PATCH] Introduce global spinlock initialization and RAII guard classes --- xtoskrnl/includes/ke/spinlock.hh | 49 +++++++++++++++++++++++ xtoskrnl/ke/data.cc | 21 +++++++--- xtoskrnl/ke/spinlock.cc | 69 ++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+), 6 deletions(-) diff --git a/xtoskrnl/includes/ke/spinlock.hh b/xtoskrnl/includes/ke/spinlock.hh index 7efcbe2..5245140 100644 --- a/xtoskrnl/includes/ke/spinlock.hh +++ b/xtoskrnl/includes/ke/spinlock.hh @@ -17,12 +17,61 @@ namespace KE { class SpinLock { + private: + STATIC KSPIN_LOCK DispatcherLockQueue; + STATIC KSPIN_LOCK PfnLockQueue; + STATIC KSPIN_LOCK SystemSpaceLockQueue; + public: STATIC XTFASTCALL VOID AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel); STATIC XTFASTCALL VOID AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock); + STATIC XTAPI VOID InitializeAllLocks(); + STATIC XTAPI VOID InitializeLockQueues(); STATIC XTAPI VOID InitializeSpinLock(IN PKSPIN_LOCK SpinLock); STATIC XTFASTCALL VOID ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel); STATIC XTFASTCALL VOID ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock); + STATIC XTFASTCALL BOOLEAN TestSpinLock(IN PKSPIN_LOCK SpinLock); + }; + + class QueuedSpinLockGuard + { + private: + KSPIN_LOCK_QUEUE_LEVEL QueuedLockLevel; + + public: + QueuedSpinLockGuard(IN OUT KSPIN_LOCK_QUEUE_LEVEL LockLevel) + { + QueuedLockLevel = LockLevel; + KE::SpinLock::AcquireQueuedSpinLock(QueuedLockLevel); + } + + ~QueuedSpinLockGuard() + { + KE::SpinLock::ReleaseQueuedSpinLock(QueuedLockLevel); + } + + QueuedSpinLockGuard(const QueuedSpinLockGuard&) = delete; + QueuedSpinLockGuard& operator=(const QueuedSpinLockGuard&) = delete; + }; + + class SpinLockGuard + { + private: + PKSPIN_LOCK SpinLock; + + public: + SpinLockGuard(IN OUT PKSPIN_LOCK SpinLock) + { + KE::SpinLock::AcquireSpinLock(SpinLock); + } + + ~SpinLockGuard() + { + KE::SpinLock::ReleaseSpinLock(SpinLock); + } + + SpinLockGuard(const SpinLockGuard&) = delete; + SpinLockGuard& operator=(const SpinLockGuard&) = delete; }; } diff --git a/xtoskrnl/ke/data.cc b/xtoskrnl/ke/data.cc index 60722bf..88e594d 100644 --- a/xtoskrnl/ke/data.cc +++ b/xtoskrnl/ke/data.cc @@ -12,12 +12,6 @@ /* Kernel initialization block passed by boot loader */ PKERNEL_INITIALIZATION_BLOCK KE::BootInformation::InitializationBlock = {}; -/* Kernel boot resources list */ -LIST_ENTRY KE::SystemResources::ResourcesListHead; - -/* Kernel boot resources lock */ -KSPIN_LOCK KE::SystemResources::ResourcesLock; - /* Kernel initial process */ EPROCESS KE::KProcess::InitialProcess; @@ -26,3 +20,18 @@ ETHREAD KE::KThread::InitialThread = {}; /* Kernel UBSAN active frame flag */ BOOLEAN KE::KUbsan::ActiveFrame = FALSE; + +/* Kernel dispatcher lock queue */ +KSPIN_LOCK KE::SpinLock::DispatcherLockQueue; + +/* Kernel PFN lock queue */ +KSPIN_LOCK KE::SpinLock::PfnLockQueue; + +/* Kernel system space lock queue */ +KSPIN_LOCK KE::SpinLock::SystemSpaceLockQueue; + +/* Kernel boot resources list */ +LIST_ENTRY KE::SystemResources::ResourcesListHead; + +/* Kernel boot resources lock */ +KSPIN_LOCK KE::SystemResources::ResourcesLock; diff --git a/xtoskrnl/ke/spinlock.cc b/xtoskrnl/ke/spinlock.cc index bb72ba3..679ae24 100644 --- a/xtoskrnl/ke/spinlock.cc +++ b/xtoskrnl/ke/spinlock.cc @@ -4,6 +4,7 @@ * FILE: xtoskrnl/ke/spinlock.cc * DESCRIPTION: Spinlocks support * DEVELOPERS: Rafal Kupiec + * Aiken Harris */ #include @@ -56,6 +57,48 @@ KE::SpinLock::AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock) AR::CpuFunc::ReadWriteBarrier(); } +/** + * Initializes all kernel spinlocks. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KE::SpinLock::InitializeAllLocks() +{ + /* Initialize all spin locks */ + InitializeSpinLock(&DispatcherLockQueue); + InitializeSpinLock(&PfnLockQueue); + InitializeSpinLock(&SystemSpaceLockQueue); +} + +/** + * Initializes spinlock queues for current processor. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KE::SpinLock::InitializeLockQueues() +{ + PKPROCESSOR_CONTROL_BLOCK ControlBlock; + + /* Get current processor control block */ + ControlBlock = KE::Processor::GetCurrentProcessorControlBlock(); + + /* Initialize PCB lock queues */ + ControlBlock->LockQueue[DispatcherLock].Lock = &DispatcherLockQueue; + ControlBlock->LockQueue[DispatcherLock].Next = NULLPTR; + ControlBlock->LockQueue[PfnLock].Lock = &PfnLockQueue; + ControlBlock->LockQueue[PfnLock].Next = NULLPTR; + ControlBlock->LockQueue[SystemSpaceLock].Lock = &SystemSpaceLockQueue; + ControlBlock->LockQueue[SystemSpaceLock].Next = NULLPTR; +} + /** * Initializes a kernel spinlock object. * @@ -112,3 +155,29 @@ KE::SpinLock::ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock) /* Add an explicit memory barrier */ AR::CpuFunc::ReadWriteBarrier(); } + +/** + * Tests a kernel spin lock. + * + * @param SpinLock + * Supplies a pointer to the kernel spin lock. + * + * @return This routine returns TRUE if the lock is free, FALSE otherwise. + * + * @since XT 1.0 + */ +XTFASTCALL +BOOLEAN +TestSpinLock(IN PKSPIN_LOCK SpinLock) +{ + /* Check if the lock is free */ + if(*SpinLock) + { + /* Spinlock is busy, yield processor and return FALSE */ + AR::CpuFunc::YieldProcessor(); + return FALSE; + } + + /* Spinlock is free, return TRUE */ + return TRUE; +}