[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;
} 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
/* Internal Function for MCS Node Allocation */
PMCS_NODE
KiAllocateRingLockNode(
@ -93,11 +103,10 @@ KeInitializeSpinningRingLock(
_Out_ PSRING_LOCK Lock
)
{
Lock->Tail = NULL;
RtlZeroMemory(Lock->RingBuffer, sizeof(Lock->RingBuffer));
Lock->Head = 0;
Lock->Tail = 0;
Lock->HazardPointer = NULL;
Lock->Head = {0};
Lock->Tail = {0};
Lock->HazardPointer = nullptr;
}
VOID
@ -108,7 +117,7 @@ KeAcquireSpinningRingLock(
PMCS_NODE Node = KiAllocateRingLockNode(Lock);
PMCS_NODE Predecessor;
Node->Next = NULL;
Node->Next = nullptr;
Node->Locked = 1;
// Set hazard pointer before we exchange
@ -117,7 +126,7 @@ KeAcquireSpinningRingLock(
Predecessor = (PMCS_NODE)InterlockedExchangePointer((PVOID*)&Lock->Tail, Node);
if (Predecessor != NULL) {
if (Predecessor != nullptr) {
/*Set hazard pointer to predecessor*/
InterlockedExchangePointer((PVOID*)&Lock->HazardPointer, Predecessor);
KeMemoryBarrier();
@ -143,16 +152,16 @@ KeReleaseSpinningRingLock(
InterlockedExchangePointer((PVOID*)&Lock->HazardPointer, Node);
KeMemoryBarrier();
if (Node->Next == NULL) {
if (InterlockedCompareExchangePointer((PVOID*)&Lock->Tail, NULL, Node) == Node)
if (Node->Next == nullptr) {
if (InterlockedCompareExchangePointer((PVOID*)&Lock->Tail, nullptr, Node) == Node)
{
/*Clear hazard pointer before returning*/
InterlockedExchangePointer((PVOID*)&Lock->HazardPointer, NULL);
InterlockedExchangePointer((PVOID*)&Lock->HazardPointer, nullptr);
KiFreeRingLockNode(Lock, Node);
return;
}
while (Node->Next == NULL) {
while (Node->Next == nullptr) {
KeYieldProcessor();
}
}