Geoff Chappell - Software Analyst
This function acquires a queued spin lock at low IRQL, raising to DISPATCH_LEVEL.
VOID FASTCALL KeAcquireInStackQueuedSpinLock ( KSPIN_LOCK *SpinLock, KLOCK_QUEUE_HANDLE *LockHandle);
The SpinLock argument provides the address of the spin lock that is to be acquired.
The LockHandle argument provides the address of an opaque context structure. This address is re-presented when releasing the lock. The context must have no other use until the lock has been released.
The KeAcquireInStackQueuedSpinLock function assumes that the IRQL is no higher than DISPATCH_LEVEL. It returns with the IRQL at DISPATCH_LEVEL. The spin lock and the context structure must be in non-paged memory when this function begins and must remain so until the lock is released.
The KeAcquireInStackQueuedSpinLock function is exported by name from x86 builds of the HAL in version 5.1 and higher and of the kernel in version 6.2 and higher. The HAL’s export in version 6.2 and higher is merely a forward to the kernel.
For 64-bit Windows, the KeAcquireInStackQueuedSpinLock function is exported by name from the kernel in all known versions, i.e., starting with the version 5.2 from Windows Server 2003 SP1.
The KeAcquireInStackQueuedSpinLock function is documented.
The KeAcquireInStackQueuedSpinLock function is a compound. Its work is in two parts which can be done independently by calling exported functions: the first from the HAL (originally); the second from the kernel. The implementation gains by inlining its two parts and from skipping the second entirely for single-processor builds.
The first part is to raise the IRQL to DISPATCH_LEVEL if it is not already there. This ensures that the current thread has exclusive use of the current processor. Interrupts can occur at higher IRQL, as with hardware interrupts, but they are not permitted to switch the processor to another thread. An equivalent exported function is KeRaiseIrqlToDpcLevel.
The second part is to arrange that the current processor has exclusive use of the protected resource. All threads that seek to use the resource must acquire the agreed lock. All call this function or a similar one so that all try to acquire the lock in the same way and are made to wait in a more or less tight loop until they own the lock. An equivalent exported function for this second part is KeAcquireInStackQueuedSpinLockAtDpcLevel. This part is trivial in single-processor builds.