[NTOSKRNL:KE] Refactored Spinning Ring

*Refactored to comply more with C++ Type System 
*Added Idea of Ring Lock Chaining
This commit is contained in:
Dibyamartanda Samanta 2024-07-11 14:28:09 +02:00
parent 3eacac0223
commit 56e4dd1344

View File

@ -34,10 +34,20 @@ typedef struct _SRING_LOCK {
volatile PMCS_NODE HazardPointer; volatile PMCS_NODE HazardPointer;
} SRING_LOCK, *PSRING_LOCK; } SRING_LOCK, *PSRING_LOCK;
/* In Future if needed Size can be increased , but fallback to Dynamic Allocation is present*/ /* In Future if needed Size can be increased , but fallback to Dynamic Allocation is present
Chain Linking of Ring Buffer like a MCS Node is planned,
------------- ------------- -------------
| Buffer Ptr | | Buffer Ptr | | Buffer Ptr |
| Next Node |<-------- | Next Node |<-------- | Next Node | <-------- nullptr
------------- ------------- -------------
Dynamic Allocation is for now #hack to get Lock Going incase more than 256 Threads try to retrive the lock*/
#define RING_BUFFER_SIZE 256 #define RING_BUFFER_SIZE 256
/* Internal Function for MCS Node Allocation */ /* Internal Function for MCS Node Allocation */
PMCS_NODE PMCS_NODE
KiAllocateRingLockNode( KiAllocateRingLockNode(
@ -93,11 +103,10 @@ KeInitializeSpinningRingLock(
_Out_ PSRING_LOCK Lock _Out_ PSRING_LOCK Lock
) )
{ {
Lock->Tail = NULL;
RtlZeroMemory(Lock->RingBuffer, sizeof(Lock->RingBuffer)); RtlZeroMemory(Lock->RingBuffer, sizeof(Lock->RingBuffer));
Lock->Head = 0; Lock->Head = {0};
Lock->Tail = 0; Lock->Tail = {0};
Lock->HazardPointer = NULL; Lock->HazardPointer = nullptr;
} }
VOID VOID
@ -108,7 +117,7 @@ KeAcquireSpinningRingLock(
PMCS_NODE Node = KiAllocateRingLockNode(Lock); PMCS_NODE Node = KiAllocateRingLockNode(Lock);
PMCS_NODE Predecessor; PMCS_NODE Predecessor;
Node->Next = NULL; Node->Next = nullptr;
Node->Locked = 1; Node->Locked = 1;
// Set hazard pointer before we exchange // Set hazard pointer before we exchange
@ -117,7 +126,7 @@ KeAcquireSpinningRingLock(
Predecessor = (PMCS_NODE)InterlockedExchangePointer((PVOID*)&Lock->Tail, Node); Predecessor = (PMCS_NODE)InterlockedExchangePointer((PVOID*)&Lock->Tail, Node);
if (Predecessor != NULL) { if (Predecessor != nullptr) {
/*Set hazard pointer to predecessor*/ /*Set hazard pointer to predecessor*/
InterlockedExchangePointer((PVOID*)&Lock->HazardPointer, Predecessor); InterlockedExchangePointer((PVOID*)&Lock->HazardPointer, Predecessor);
KeMemoryBarrier(); KeMemoryBarrier();
@ -143,16 +152,16 @@ KeReleaseSpinningRingLock(
InterlockedExchangePointer((PVOID*)&Lock->HazardPointer, Node); InterlockedExchangePointer((PVOID*)&Lock->HazardPointer, Node);
KeMemoryBarrier(); KeMemoryBarrier();
if (Node->Next == NULL) { if (Node->Next == nullptr) {
if (InterlockedCompareExchangePointer((PVOID*)&Lock->Tail, NULL, Node) == Node) if (InterlockedCompareExchangePointer((PVOID*)&Lock->Tail, nullptr, Node) == Node)
{ {
/*Clear hazard pointer before returning*/ /*Clear hazard pointer before returning*/
InterlockedExchangePointer((PVOID*)&Lock->HazardPointer, NULL); InterlockedExchangePointer((PVOID*)&Lock->HazardPointer, nullptr);
KiFreeRingLockNode(Lock, Node); KiFreeRingLockNode(Lock, Node);
return; return;
} }
while (Node->Next == NULL) { while (Node->Next == nullptr) {
KeYieldProcessor(); KeYieldProcessor();
} }
} }