这玩意本来是在Vista SP1版本就存在了,但是某些傻x客户还在坚持使用老旧的windows操作系统。可以使用下面的移植方案代替。
在微软的实现上好像有一些调试用途或者什么优化,移植不了,去掉了。
#ifndef _MY_EX_SPIN_LOCK
#define _MY_EX_SPIN_LOCK
typedef LONG EX_SPIN_LOCK;
KIRQL NTAPI ExAcquireSpinLockExclusive(volatile EX_SPIN_LOCK *ExSpinLock);
KIRQL NTAPI ExAcquireSpinLockShared(volatile EX_SPIN_LOCK *ExSpinLock);
void NTAPI ExReleaseSpinLockExclusive(EX_SPIN_LOCK *ExSpinLock, KIRQL NewIrql);
void NTAPI ExReleaseSpinLockShared(EX_SPIN_LOCK *ExSpinLock, KIRQL NewIrql);
#endif // _MY_EX_SPIN_LOCK
#include <wdm.h>
#include "exspinlock.h"
VOID NTAPI ExpWaitForSpinLockExclusiveAndAcquire(volatile EX_SPIN_LOCK *ExSpinLock)
{
while(*ExSpinLock < 0 || _interlockedbittestandset(ExSpinLock, 0x1Fu));
}
VOID NTAPI ExpWaitForSpinLockSharedAndAcquire(volatile EX_SPIN_LOCK *ExSpinLock)
{
while(1)
{
if(*ExSpinLock >= 0)
{
EX_SPIN_LOCK Tmp = *ExSpinLock;
if (_InterlockedCompareExchange(ExSpinLock, Tmp + 1, Tmp) == Tmp)
break;
}
}
}
KIRQL NTAPI ExAcquireSpinLockExclusive(volatile EX_SPIN_LOCK *ExSpinLock)
{
KIRQL OldIrql;
OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
if(_interlockedbittestandset(ExSpinLock, 0x1Fu))
ExpWaitForSpinLockExclusiveAndAcquire(ExSpinLock);
while(*ExSpinLock != 0x80000000);
return OldIrql;
}
KIRQL NTAPI ExAcquireSpinLockShared(volatile EX_SPIN_LOCK *ExSpinLock)
{
KIRQL OldIrql;
EX_SPIN_LOCK Tmp;
OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
Tmp = *ExSpinLock & 0x7FFFFFFF;
if(_InterlockedCompareExchange(ExSpinLock, Tmp + 1, Tmp) != Tmp )
{
ExpWaitForSpinLockSharedAndAcquire(ExSpinLock);
}
return OldIrql;
}
void NTAPI ExReleaseSpinLockExclusive(EX_SPIN_LOCK *ExSpinLock, KIRQL NewIrql)
{
_InterlockedAnd(ExSpinLock, 0);
KeLowerIrql(NewIrql);
}
void NTAPI ExReleaseSpinLockShared(EX_SPIN_LOCK *ExSpinLock, KIRQL NewIrql)
{
_InterlockedExchangeAdd(ExSpinLock, 0xFFFFFFFF);
KeLowerIrql(NewIrql);
}