CustomTimerDpc 루틴 사용

이전에 설정된 타이머 개체를 사용하지 않도록 설정하려면 드라이버가 KeCancelTimer를 호출합니다. 이 루틴은 시스템의 타이머 큐에서 타이머 개체를 제거합니다. 일반적으로 타이머 개체는 신호를 받은 상태로 설정되지 않으며 CustomTimerDpc 루틴은 실행을 위해 큐에 대기되지 않습니다. 그러나 KeCancelTimer 가 호출될 때 타이머가 만료되는 경우 KeCancelTimer 가 시간 큐에 액세스할 기회가 있기 전에 만료가 발생할 수 있습니다. 이 경우 신호 및 DPC 큐가 발생합니다.

이전에 지정된 간격이 만료되기 전에 이전에 지정된 타이머Dpc 포인터를 사용하여 KeSetTimer 또는 KeSetTimerEx를 회수하면 다음과 같은 효과가 있습니다.

  • 커널은 개체를 신호 상태로 설정하거나 CustomTimerDpc 루틴을 큐에 대기하지 않고 타이머 큐에서 타이머 개체를 제거합니다.

  • 커널은 새 DueTime 값을 사용하여 타이머 큐에 타이머 개체를 다시 삽입합니다.

동일한 타이머 개체를 다른 용도로 사용하면 경합 상태 또는 심각한 드라이버 오류가 발생할 수 있습니다. 예를 들어 드라이버가 CustomTimerDpc 루틴에 대한 호출을 설정하고 드라이버 전용 스레드에서 대기를 설정하기 위해 단일 타이머 개체를 지정한다고 가정합니다. 드라이버 전용 스레드가 공통 타이머 개체에 대해 KeSetTimer, KeSetTimerEx 또는 KeCancelTimer 를 호출할 때마다 타이머 개체가 CustomTimerDpc 호출을 위해 이미 큐에 대기된 경우 스레드는 CustomTimerDpc 루틴에 대한 호출을 취소합니다.

드라이버에 CustomTimerDpc 루틴이 있고 비비타적 스레드 컨텍스트에서 타이머 개체도 대기하는 경우 다음을 수행해야 합니다.

  • 비비타적 스레드 컨텍스트에서 스레드 컨텍스트에 민감한 타이머 개체를 사용하지 않거나 그 반대의 경우도 마찬가지입니다.

  • CustomTimerDpc 루틴에 대해 별도의 타이머 개체를 할당합니다. 비비타적 스레드 컨텍스트에서 호출되는 각 드라이버 스레드 또는 드라이버 루틴 집합에는 고유한 "대기 가능한" 타이머 개체 집합이 있어야 합니다.

CustomTimerDpc 루틴을 사용하는 경우 드라이버가 KeSetTimer 또는 KeSetTimerEx 호출에서 전달하는 간격을 신중하게 선택합니다. 또한 특히 SMP 플랫폼에서 이 호출을 하는 드라이버 루틴에서 동일한 타이머 개체를 사용하여 KeCancelTimer 호출의 가능한 모든 효과를 고려합니다.

CustomTimerDpc 루틴에 대한 다음 사실을 유의하세요.

특정 DPC 루틴을 나타내는 DPC 개체의 인스턴스화는 지정된 순간에 실행을 위해 큐에 대기할 수 있습니다.

두 번째 드라이버 루틴이 KeSetTimer 또는 KeSetTimerEx 를 호출하여 첫 번째 호출자가 지정한 간격이 만료되기 전에 동일한 CustomTimerDpc 루틴을 실행하는 경우 CustomTimerDpc 루틴은 두 번째 호출자가 지정한 간격이 만료된 후에만 실행됩니다. 이러한 상황에서 CustomTimerDpc는 첫 번째 루틴이 KeSetTimer 또는 KeSetTimerEx라는 작업을 수행하지 않습니다.

CustomTimerDpc 루틴이 있고 주기적인 타이머를 사용하는 드라이버의 경우:

드라이버는 DPC 루틴에서 주기적인 타이머의 할당을 취소할 수 없습니다. 드라이버는 DPC 루틴에서 비자동 타이머만 할당 취소할 수 있습니다.

CustomDpc 및 CustomTimerDpc 루틴이 모두 있는 드라이버에 대한 다음 디자인 지침을 고려합니다.

경합 상태를 방지하려면 KeSetTimer 또는 KeSetTimerExKeInsertQueueDpc에 동일한 Dpc 포인터를 전달하지 마세요.

즉, 드라이버의 StartIo 루틴이 KeSetTimer 또는 KeSetTimerEx를 호출하여 CustomTimerDpc 루틴을 큐에 대기시키고 드라이버의 ISR이 동일한 Dpc 포인터가 있는 다른 프로세서에서 KeInsertQueueDpc를 동시에 호출한다고 가정합니다. 해당 DPC 루틴은 프로세서의 IRQL이 DISPATCH_LEVEL 이하로 떨어지거나 타이머 간격이 만료될 때 실행됩니다. 어느 것이 먼저 오든 StartIo 또는 ISR에 대한 몇 가지 필수 작업은 단순히 DPC 루틴에 의해 삭제됩니다.

또한 기능이 매우 다른 두 표준 드라이버 루틴에서 사용하는 DPC는 별도의 CustomTimerDpcCustomDpc 루틴보다 성능 특성이 저하됩니다. DPC는 StartIo 루틴 또는 ISR이 큐에 넣은 조건에 따라 수행할 작업을 결정해야 합니다. DPC에서 이러한 조건에 대한 테스트는 추가 CPU 주기를 사용합니다.