Windows内核读写自旋锁EX_SPIN_LOCK

这玩意本来是在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 
#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);
}

 

你可能感兴趣的:(Windows内核读写自旋锁EX_SPIN_LOCK)