Introduce global spinlock initialization and RAII guard classes
This commit is contained in:
@@ -17,12 +17,61 @@ namespace KE
|
|||||||
{
|
{
|
||||||
class SpinLock
|
class SpinLock
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
STATIC KSPIN_LOCK DispatcherLockQueue;
|
||||||
|
STATIC KSPIN_LOCK PfnLockQueue;
|
||||||
|
STATIC KSPIN_LOCK SystemSpaceLockQueue;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STATIC XTFASTCALL VOID AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
|
STATIC XTFASTCALL VOID AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
|
||||||
STATIC XTFASTCALL VOID AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock);
|
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 XTAPI VOID InitializeSpinLock(IN PKSPIN_LOCK SpinLock);
|
||||||
STATIC XTFASTCALL VOID ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
|
STATIC XTFASTCALL VOID ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
|
||||||
STATIC XTFASTCALL VOID ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock);
|
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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,12 +12,6 @@
|
|||||||
/* Kernel initialization block passed by boot loader */
|
/* Kernel initialization block passed by boot loader */
|
||||||
PKERNEL_INITIALIZATION_BLOCK KE::BootInformation::InitializationBlock = {};
|
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 */
|
/* Kernel initial process */
|
||||||
EPROCESS KE::KProcess::InitialProcess;
|
EPROCESS KE::KProcess::InitialProcess;
|
||||||
|
|
||||||
@@ -26,3 +20,18 @@ ETHREAD KE::KThread::InitialThread = {};
|
|||||||
|
|
||||||
/* Kernel UBSAN active frame flag */
|
/* Kernel UBSAN active frame flag */
|
||||||
BOOLEAN KE::KUbsan::ActiveFrame = FALSE;
|
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;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
* FILE: xtoskrnl/ke/spinlock.cc
|
* FILE: xtoskrnl/ke/spinlock.cc
|
||||||
* DESCRIPTION: Spinlocks support
|
* DESCRIPTION: Spinlocks support
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
* Aiken Harris <harraiken91@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
@@ -56,6 +57,48 @@ KE::SpinLock::AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock)
|
|||||||
AR::CpuFunc::ReadWriteBarrier();
|
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.
|
* Initializes a kernel spinlock object.
|
||||||
*
|
*
|
||||||
@@ -112,3 +155,29 @@ KE::SpinLock::ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock)
|
|||||||
/* Add an explicit memory barrier */
|
/* Add an explicit memory barrier */
|
||||||
AR::CpuFunc::ReadWriteBarrier();
|
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;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user