调用使用自旋锁的支持例程
调用 KeAcquireSpinLock 或 KeAcquireInStackQueuedSpinLock 会将当前处理器上的 IRQL 设置为DISPATCH_LEVEL,直到对 KeReleaseSpinLock 或 KeReleaseInStackQueuedSpinLock 的相应调用还原以前的 IRQL。 因此,当驱动程序调用 KeAcquireSpinLock 或 KeAcquireInStackQueuedSpinLock 时,必须在 IRQL <= DISPATCH_LEVEL 处执行。
KeAcquireSpinLockAtDpcLevel、KeAcquireInStackQueuedSpinLockAtDpcLevel、KeReleaseInStackQueuedSpinLockFromDpcLevel 和 KeReleaseSpinLockFromDpcLevel 的调用方运行速度更快,因为它们已在 IRQL = DISPATCH_LEVEL因此这些支持例程无需在当前处理器上重置 IRQL。 因此,在大多数 Windows 平台上,在 IRQL 上运行时调用 KeAcquireSpinLockAtDpcLevel 或 KeAcquireInStackQueuedSpinLockAtDpcLevel 是一个致命错误,而运行 IRQL 小于 DISPATCH_LEVEL。 释放通过调用 KeReleaseSpinLockFromDpcLevel 获取的旋转锁也是一个错误,因为调用方的原始 IRQL 未还原。
持有执行旋转锁(如 ExInterlockedXxx)的例程通常以 IRQL = DISPATCH_LEVEL 执行,直到释放旋转锁并将控制权返回到调用方。但是,驱动程序的 InterruptService 例程和 SynchCritSection 例程 (在 DIRQL) 运行,可以调用某些 ExInterlockedXxx 例程(例如 ExInterlockedXxx列表例程),只要传递给该例程的旋转锁由 ISR 和 SynchCritSection 例程专门使用。
每个保留中断旋转锁的例程在一组关联的中断对象的 DIRQL 处执行。 因此,驱动程序不得从其 ISR 或 SynchCritSection 例程调用 KeAcquireSpinLock 和 KeReleaseSpinLock 或任何其他使用执行旋转锁的例程。 此类调用是一个错误,可能导致系统死锁,要求用户重新启动其计算机。 请注意,如果驱动程序的 ISR 或 SynchCritSection 例程调用 ExInterlockedXxxList 例程,则驱动程序不能在调用 KeXxxSpinLock 或 KeXxxSpinLock Xxx DpcLevel 支持例程时重复使用它传递给 ExInterlocked Xxx 列表例程的旋转锁。
如果驱动程序具有多向量 ISR 或多个 ISR,则其例程可以在执行任何 IRQL 时调用 KeSynchronizeExecution ,最高为连接时为关联的中断对象指定的 SynchronizeIrql 值。