[NTOSKRNL:KE] Refactored Spinning Ring
*Refactored to comply more with C++ Type System *Added Idea of Ring Lock Chaining
This commit is contained in:
parent
3eacac0223
commit
56e4dd1344
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user