Implement push lock unblocking
All checks were successful
Builds / ExectOS (amd64, release) (push) Successful in 36s
Builds / ExectOS (i686, release) (push) Successful in 35s
Builds / ExectOS (amd64, debug) (push) Successful in 45s
Builds / ExectOS (i686, debug) (push) Successful in 42s

This commit is contained in:
2026-07-09 12:05:52 +02:00
parent 5982403a79
commit f9a471633f
2 changed files with 57 additions and 0 deletions

View File

@@ -32,6 +32,8 @@ namespace KE
STATIC XTFASTCALL VOID ReleaseWaitPushLock(IN PKPUSH_LOCK PushLock); STATIC XTFASTCALL VOID ReleaseWaitPushLock(IN PKPUSH_LOCK PushLock);
STATIC XTFASTCALL BOOLEAN TryAcquireExclusivePushLock(PKPUSH_LOCK PushLock); STATIC XTFASTCALL BOOLEAN TryAcquireExclusivePushLock(PKPUSH_LOCK PushLock);
STATIC XTFASTCALL VOID TryWakePushLock(IN PKPUSH_LOCK PushLock); STATIC XTFASTCALL VOID TryWakePushLock(IN PKPUSH_LOCK PushLock);
STATIC XTFASTCALL VOID UnblockPushLock(IN PKPUSH_LOCK PushLock,
IN PKPUSH_LOCK_WAIT_BLOCK WaitBlock);
STATIC XTFASTCALL VOID WaitOnPushLock(IN PKPUSH_LOCK PushLock); STATIC XTFASTCALL VOID WaitOnPushLock(IN PKPUSH_LOCK PushLock);
STATIC XTFASTCALL VOID WakePushLockWaiters(IN PKPUSH_LOCK PushLock, IN KPUSH_LOCK OldState); STATIC XTFASTCALL VOID WakePushLockWaiters(IN PKPUSH_LOCK PushLock, IN KPUSH_LOCK OldState);

View File

@@ -864,6 +864,61 @@ KE::PushLock::TryWakePushLock(IN PKPUSH_LOCK PushLock)
} }
} }
/**
* Unblocks an executive push lock and wakes up any pending threads waiting on it.
*
* @param PushLock
* Supplies a pointer to the executive push lock being unblocked.
*
* @param CurrentWaitBlock
* Optionally supplies a pointer to the current thread's push lock wait block.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTFASTCALL
VOID
KE::PushLock::UnblockPushLock(IN PKPUSH_LOCK PushLock,
IN PKPUSH_LOCK_WAIT_BLOCK WaitBlock)
{
PKPUSH_LOCK_WAIT_BLOCK CurrentWaitBlock, NextWaitBlock;
/* Capture the entire chain of wait blocks and clear the push lock pointer */
CurrentWaitBlock = (PKPUSH_LOCK_WAIT_BLOCK)RTL::Atomic::ExchangePointer((PVOID *)&PushLock->Ptr, NULLPTR);
/* Check if any wait blocks are present */
if(CurrentWaitBlock)
{
/* Raise runlevel to DISPATCH level */
KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL, CurrentWaitBlock->Next);
/* Iterate through the captured chain of wait blocks */
while(CurrentWaitBlock)
{
/* Cache the next block pointer */
NextWaitBlock = CurrentWaitBlock->Next;
/* Test and clear the lock flag */
if(!RTL::Atomic::BitTestAndReset((VOLATILE PLONG)&CurrentWaitBlock->Flags, KPUSHLOCK_LOCK))
{
/* Boost priority and signal the wake event */
KE::Event::SetEventBoostPriority(&CurrentWaitBlock->WakeEvent, NULLPTR);
}
/* Advance to the next wait block */
CurrentWaitBlock = NextWaitBlock;
}
}
/* Check if a wait context was provided and its wait flag is pending */
if(WaitBlock && (WaitBlock->Flags & KPUSHLOCK_WAITING))
{
/* Suspend the thread until push lock wake event is signaled */
KE::Dispatcher::WaitForSingleObject(&WaitBlock->WakeEvent, WrPushLock, KernelMode, FALSE, NULLPTR);
}
}
/** /**
* Wakes threads waiting on a PushLock. * Wakes threads waiting on a PushLock.
* *