From d8eeff620eef8787539e5f918b14efa73134e331 Mon Sep 17 00:00:00 2001 From: Aiken Harris Date: Thu, 9 Jul 2026 14:51:24 +0200 Subject: [PATCH] Implement push lock blocking --- xtoskrnl/includes/ke/pushlock.hh | 2 ++ xtoskrnl/ke/pushlock.cc | 45 ++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/xtoskrnl/includes/ke/pushlock.hh b/xtoskrnl/includes/ke/pushlock.hh index 0a7d1da..91ed987 100644 --- a/xtoskrnl/includes/ke/pushlock.hh +++ b/xtoskrnl/includes/ke/pushlock.hh @@ -22,6 +22,8 @@ namespace KE STATIC XTFASTCALL VOID AcquireSharedPushLock(PKPUSH_LOCK PushLock); STATIC XTFASTCALL VOID AcquireWaitExclusivePushLock(IN PKPUSH_LOCK PushLock); STATIC XTFASTCALL VOID AcquireWaitSharedPushLock(IN OUT PKPUSH_LOCK PushLock); + STATIC XTFASTCALL VOID BlockPushLock(IN PKPUSH_LOCK PushLock, + IN PKPUSH_LOCK_WAIT_BLOCK WaitBlock); STATIC XTFASTCALL BOOLEAN ConvertSharedPushLockToExclusive(IN PKPUSH_LOCK PushLock); STATIC XTFASTCALL VOID InitializePushLock(IN PKPUSH_LOCK PushLock); STATIC XTFASTCALL VOID ReleaseExclusivePushLock(IN PKPUSH_LOCK PushLock); diff --git a/xtoskrnl/ke/pushlock.cc b/xtoskrnl/ke/pushlock.cc index 30480c3..cded91d 100644 --- a/xtoskrnl/ke/pushlock.cc +++ b/xtoskrnl/ke/pushlock.cc @@ -299,6 +299,51 @@ KE::PushLock::AcquireWaitSharedPushLock(IN PKPUSH_LOCK PushLock) } } + +/** + * Prepares a push lock wait block and enqueues it onto the lock's contention stack. + * + * @param PushLock + * Supplies a pointer to the push lock being contended. + * + * @param WaitBlock + * Supplies a pointer to the caller-allocated wait block to be enqueued. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTFASTCALL +VOID +KE::PushLock::BlockPushLock(IN PKPUSH_LOCK PushLock, + IN PKPUSH_LOCK_WAIT_BLOCK WaitBlock) +{ + PVOID OldValue; + + /* Initialize the synchronization event */ + KE::Event::InitializeEvent(&WaitBlock->WakeEvent, SynchronizationEvent, FALSE); + + /* Set the wait flag */ + WaitBlock->Flags = KPUSHLOCK_WAITING; + + /* Enter a retry loop */ + while(TRUE) + { + /* Capture the current head of the wait stack */ + OldValue = *(VOLATILE PVOID *)&PushLock->Ptr; + + /* Link new wait block to the captured head */ + WaitBlock->Next = (PKPUSH_LOCK_WAIT_BLOCK)OldValue; + + /* Attempt to swap the lock's head pointer*/ + if (RTL::Atomic::CompareExchangePointer((PVOID *)&PushLock->Ptr, (PVOID)WaitBlock, OldValue) == OldValue) + { + /* Successfully enqueued the wait block, return */ + return; + } + } +} + /** * Attempts to convert a push lock from shared to exclusive access. *