Sincronização e DPCs encadeados
Para sincronizar o acesso a um local de memória que é acessado dentro e fora de uma rotina CustomThreadedDpc , um driver pode usar bloqueios de rotação comuns ou bloqueios de rotação enfileirados. Ao fazer isso, o driver deve obedecer a determinadas regras para sincronizar corretamente em IRQL = PASSIVE_LEVEL e em IRQL = DISPATCH_LEVEL, porque uma rotina CustomThreadedDpc pode ser executada em ambas as IRQLs.
Para um bloqueio de rotação comum, as seguintes regras se aplicam:
Para adquirir e liberar o bloqueio de rotação, o driver pode chamar KeAcquireSpinLock e KeReleaseSpinLock de dentro e fora da rotina CustomThreadedDpc .
O driver pode chamar KeAcquireSpinLockForDpc e KeReleaseSpinLockForDpc de dentro da rotina CustomThreadedDpc . Observe que a rotina CustomThreadedDpc não deve chamar KeAcquireSpinLockAtDpcLevel ou KeReleaseSpinLockFromDpcLevel, pois essas rotinas só podem ser chamadas com segurança em IRQL = DISPATCH_LEVEL.
As regras para bloqueios de rotação na fila são semelhantes:
Para adquirir e liberar o bloqueio de rotação, o driver pode chamar KeAcquireInStackQueuedSpinLock e KeReleaseInStackQueuedSpinLock de dentro e fora da rotina CustomThreadedDpc .
O driver pode chamar KeAcquireInStackQueuedSpinLockForDpc e KeReleaseInStackQueuedSpinLockForDpc de dentro da rotina CustomThreadedDpc . Observe que a rotina CustomThreadedDpc não deve chamar KeAcquireInStackQueuedSpinLockAtDpcLevel ou KeReleaseInStackQueuedSpinLockFromDpcLevel, pois essas rotinas só podem ser chamadas com segurança em IRQL = DISPATCH_LEVEL.
Como KeAcquireSpinLockForDpc e KeAcquireInStackQueuedSpinLockForDpc não redefinem o IRQL quando chamados em DISPATCH_LEVEL, eles são executados mais rápido do que KeAcquireSpinLock e KeAcquireInStackQueuedSpinLock, respectivamente.
Para obter mais informações sobre bloqueios de rotação, consulte Spin Locks.