VOID
KxAcquireSpinLock ( __inout PKSPIN_LOCK SpinLock)
{
//设置SpinLock指定位,并返回原值
//如果原值为0,表示没有上锁,直接返回
//如果原值为1,表示已经上锁,进入函数
if (InterlockedBitTestAndSet64((LONG64 *)SpinLock, 0))
{
KxWaitForSpinLockAndAcquire(SpinLock);
}
return;
}
DECLSPEC_NOINLINE
ULONG64
KxWaitForSpinLockAndAcquire (__inout PKSPIN_LOCK SpinLock)
{
do {
do {
KeYieldProcessor();
} while (*(volatile LONG64 *)SpinLock != 0);//当锁被占用时,循环,内存循环
//锁被释放.再次置位并探测原值, 不一定刚好是当前线程获得了
} while(InterlockedBitTestAndSet64((LONG64 *)SpinLock, 0));//返回原值为1时,继续循环
}
汇编实现:
lock bts qword ptr [rcx], 0 ;判断原值
jnb short RETURN ; jump short if not below (CF=0)
WAIT:
pause;
mov rax, [rcx]
test rax, rax
jnz wait ;为1,继续停机等待
lock bts qword ptr [rcx], 0 ;
jb short WAIT ;CF为1,跳转,说明原值为1,表示并没有获取到锁,继续停机
RETURN:
ret;