CustomTimerDpc 루틴 등록 및 큐
드라이버는 일반적으로 AddDevice 루틴에서 다음 루틴을 호출하여 CustomTimerDpc 루틴을 등록할 수 있습니다.
KeInitializeDpc 를 사용하여 루틴 등록
KeInitializeTimer 또는 KeInitializeTimerEx 를 사용하여 타이머 개체 설정
그 후 드라이버는 KeSetTimer 또는 KeSetTimerEx 를 호출하여 만료 시간을 지정하고 타이머 개체를 시스템의 타이머 큐에 추가할 수 있습니다. 만료 시간에 도달하면 시스템에서 타이머 개체를 큐에서 제거하고 CustomTimerDpc 루틴을 호출합니다. 다음 그림에서는 이러한 호출을 보여 줍니다.
이전 그림과 같이 드라이버는 DPC 개체와 타이머 개체 모두에 대한 스토리지를 제공해야 합니다. 대부분의 드라이버는 디바이스 확장 또는 다른 드라이버 할당 상주 메모리에서 이러한 개체에 대한 스토리지를 제공합니다.
KeSetTimer 호출에서 드라이버는 이전 그림과 같이 100나노초 단위로 표현된 DueTime과 함께 Dpc 및 Timer 개체에 대한 포인터를 전달합니다. DueTime에 대한 양수 값은 CustomTimerDpc 루틴을 호출해야 하는 절대 만료 시간(1601년 1월 1일 이후)을 지정합니다. DueTime의 음수 값은 상대 만료 시간을 지정합니다.
절대 타이머는 특정 시스템 시간에 만료되므로 타이머가 만료되기 전에 시스템 시간이 변경되는 경우 절대 타이머의 대기 기간은 영향을 받지 않습니다. 반면에 상대 타이머는 절대 시스템 시간 변경에 관계없이 지정된 시간 단위가 경과한 후 항상 만료됩니다.
CustomTimerDpc 루틴을 반복적으로 호출하려면 KeSetTimerEx를 사용하여 타이머를 설정하고 Period 매개 변수에서 되풀이 간격을 지정합니다. KeSetTimerEx 는 이 추가 매개 변수를 제외하고 KeSetTimer 와 같습니다.
이전 그림과 같이 KeSetTimer 또는 KeSetTimerEx 호출은 다음과 같이 지정된 간격 동안 타이머 개체를 큐에 대기합니다.
DueTime이 만료되면 타이머 개체가 큐에서 해제되고 Signaled 상태로 설정됩니다.
컴퓨터의 모든 프로세서가 현재 DISPATCH_LEVEL 보다 크거나 같은 IRQL에서 코드를 실행 중인 경우 타이머 개체와 연결된 DPC 개체가 DPC 큐에 배치됩니다. 그렇지 않으면 CustomTimerDpc 루틴이 호출됩니다.
DueTime 간격이 만료될 때 DPC 개체가 이미 큐에 있는 경우 컴퓨터의 모든 프로세서에서 IRQL이 DISPATCH_LEVEL 아래로 떨어지면 CustomTimerDpc 루틴이 호출됩니다.
참고
CustomTimerDpc 루틴은 모든 DPC 루틴과 마찬가지로 IRQL = DISPATCH_LEVEL 호출됩니다. DPC 루틴이 실행되는 동안 모든 스레드는 동일한 프로세서에서 실행되지 않습니다. 드라이버 개발자는 최대한 짧은 시간 동안 실행되도록 CustomTimerDpc 루틴을 신중하게 디자인해야 합니다.
KeSetTimer 및 KeSetTimerEx에 지정할 수 있는 가장 작은 시간 간격은 약 10밀리초이므로 드라이버는 초당 한 번 실행되는 IoTimer 루틴보다 더 작은 간격의 타이밍을 지정할 때 CustomTimerDpc 루틴을 사용할 수 있습니다.
특정 타이머 개체의 인스턴스화는 한 순간에만 큐에 대기할 수 있습니다. 동일한 타이머 개체 포인터를 사용하여 KeSetTimer 또는 KeSetTimerEx를 다시 호출하면 큐에 대기된 타이머 개체가 취소되고 다시 설정됩니다.
CustomTimerDpc 루틴 설정은 타이머 개체를 초기화하는 추가 단계와 함께 CustomDpc 루틴을 설정하는 것과 똑같습니다. 실제로 프로토타입은 동일하지만 CustomTimerDpc 루틴은 프로토타입에 선언된 두 개의 SystemArgument 포인터를 사용할 수 없습니다.