我目前正在开发一个实现自己的网络堆栈的 Windows 内核驱动程序。在测试已实现堆栈的一些基本功能时,我注意到对 ping 的回复有时会比平时花费明显更长的时间。进一步调查这个问题,我发现KeAcquireSpinLock
偶尔有高达 20 毫秒(而不是几微秒)的执行时间,即使锁没有被其他内核持有(我通过在调用 KeAcquireSpinLock 之前打印锁值来确认这一点)。
因为我不知道为什么KeAcquireSpinLock
要花这么长时间,所以我用 实现了一种不同的方法KeAcquireSpinLockAtDpcLevel
,如果需要,手动提升 IRQL:
oldIrql = KeGetCurrentIrql();
if (oldIrql < DISPATCH_LEVEL)
{
KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
}
KeAcquireSpinLockAtDpcLevel(m_lock);
// DO STH WITH SHARED RECOURCES
KeReleaseSpinLockFromDpcLevel(m_lock);
if (oldIrql< DISPATCH_LEVEL) KeLowerIrql(oldIrql);
我希望上面的代码在功能上等同于KeAcquireSpinLock
. 但是,事实证明,我遇到的运行时问题已经KeAcquireSpinLock
消失,并且这种方法的性能很好。
我在互联网上搜索过类似的问题KeAcquireSpinLock
,但似乎只有我一个人遇到这个问题。也许我在驱动程序的其他部分有错误?有人可以解释这种行为吗?
请注意,我不是在谈论死锁,因为它KeAcquireSpinLock
总是会在某个时候返回,并且KeAcquireSpinLockAtDpcLevel
使用相同的架构/锁定对象的实现。