-
Notifications
You must be signed in to change notification settings - Fork 240
Kernel spin locks
The kernel_spin_lock
class is defined in wil/resource.h
as part of the RAII resource wrappers library.
It manages a
KSPIN_LOCK
exposing appropriate locking methods:
// The constructor initializes the spin lock using KeInitializeSpinLock.
wil::kernel_spin_lock spinLock1;
wil::kernel_spin_lock spinLock2;
// Calls KeAcquireSpinLock. The RAII object returned calls KeReleaseSpinLock
// when it goes out of scope.
auto lockGuard1 = spinLock1.acquire();
// Calls KeAcquireSpinLockAtDpcLevel. The RAII object returned calls
// KeReleaseSpinLockFromDpcLevel when it goes out of scope.
{
auto lockGuard2 = spinLock2.acquire_at_dpc();
}
// Initialize later.
wil::kspin_lock_guard lockGuard2;
lockGuard2 = spinLock2.acquire();
// Explicit lock release using .reset().
lockGuard2.reset();
The RAII lock guard types returned by these methods are built using unique_any
and hence support all the associated functionality, such as default/empty
construction, reassignment, explicit reset/release, etc.
Though the need should be rare, if you have a raw KSPIN_LOCK
not managed by
the WIL class, you can use the following functions in the wil
namespace to
obtain the same RAII lock guard objects returned by the methods on the class:
// Naturally, the burden is on the user to initialize the KSPIN_LOCK.
KSPIN_LOCK spinLock1;
KeInitializeSpinLock(&spinLock1);
KSPIN_LOCK spinLock2;
KeInitializeSpinLock(&spinLock2);
auto lockGuard1 = wil::acquire_kspin_lock(&spinLock1);
auto lockGuard2 = wil::acquire_kspin_lock_at_dpc(&spinLock2);
There are some gotchas in the use of the lock guard object
returned by the acquire()
method and the
acquire_kspin_lock_xxx
functions.
See Lock guard object for details.