我有一个KSPIN_LOCK
,它在Windows驱动程序的主线程和我用PsCreateSystemThread
创建的一些线程之间共享。问题是如果我尝试获取自旋锁并且没有解除阻塞,则主线程会阻塞。我很困惑为什么会发生这种情况..它可能以某种方式与主线程在驱动程序IRQL上运行这一事实有关,而据我所知,其他线程在PASSIVE_LEVEL运行。
注意:如果我只运行主线程,获取/释放锁定工作正常。
注意:我正在使用KeAcquireSpinLock
和KeReleaseSpinLock
函数来获取/释放锁。
这是我的“卡住”螺旋锁的清单:
使用Driver Verifier可以轻松自动捕获其中一些问题;如果你还没有使用它,请使用它。如果将spinlock封装在一个添加自己的断言的小助手中,则可以捕获其他问题。例如:
typedef struct _MY_LOCK {
KSPIN_LOCK Lock;
ULONG OwningProcessor;
KIRQL OldIrql;
} MY_LOCK;
void MyInitialize(MY_LOCK *lock) {
KeInitializeSpinLock(&lock->Lock);
lock->OwningProcessor = (ULONG)-1;
}
void MyAcquire(MY_LOCK *lock) {
ULONG current = KeGetCurrentProcessorIndex();
NT_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
NT_ASSERT(current != lock->OwningProcessor); // check for recursion
KeAcquireSpinLock(&lock->Lock, &lock->OldIrql);
NT_ASSERT(lock->OwningProcessor == (ULONG)-1); // check lock was inited
lock->OwningProcessor = current;
}
void MyRelease(MY_LOCK *lock) {
NT_ASSERT(KeGetCurrentProcessorIndex() == lock->OwningProcessor);
lock->OwningProcessor = (ULONG)-1;
KeReleaseSpinLock(&lock->Lock, lock->OldIrql);
}
围绕KSPIN_LOCK的包装很常见。 KSPIN_LOCK就像一辆赛车,其所有可选功能都被剥离,以最大限度地提高原始速度。如果你不计算微秒,你可以合理地决定通过将低级别的KSPIN_LOCK包裹在上面这样的东西来加回加热座椅和FM收音机。 (有了#ifdefs的魔力,如果你需要,你可以随时从你的零售版本中取出安全气囊。)