共用方式為


使用自訂的 CustomTimerDpc 例程

若要停用先前設定的定時器物件,驅動程式會呼叫 KeCancelTimer。 此例程會從系統的定時器佇列中移除定時器物件。 一般而言,定時器物件不會設定為訊號狀態,而且 CustomTimerDpc 例程不會排入佇列以執行。 不過,如果在呼叫 KeCancelTimer 時定時器即將到期,那麼可能會在 KeCancelTimer 有機會存取時間佇列之前到期,在這種情況下,會發生訊號和 DPC 排隊。

重新呼叫 KeSetTimerKeSetTimerEx,並且在先前已指定的 TimerDpc 指標及指定的時間間隔到期之前,會有以下影響:

  • 核心會從定時器佇列中移除定時器物件,但不會將物件設置為已發送訊號的狀態,也不會將 CustomTimerDpc 例程排入佇列。

  • 核心會使用新的 DueTime 值,在定時器佇列中重新插入定時器物件。

針對不同用途使用相同的定時器物件,可能會導致競爭狀況或嚴重的驅動程序錯誤。 例如,假設驅動程式會指定單一定時器物件,以設定對 customTimerDpc 例程的呼叫,以及在驅動程式專用線程中設定等候。 每當驅動程式專用線程呼叫 KeSetTimerKeSetTimerExKeCancelTimer 一般定時器物件時,線程就會取消對 CustomTimerDpc 例程的呼叫,如果定時器物件已排入佇列以 CustomTimerDpc 呼叫。

如果驅動程式擁有 CustomTimerDpc 例程,並且在非任意線程上下文中等待定時器物件,則它應該:

  • 請勿在非bitrary 線程內容中使用線程內容敏感性定時器物件,反之亦然。

  • 為每個 CustomTimerDpc 例程配置個別的定時器物件。 在非任意線程內容中呼叫的每個驅動程式執行緒或驅動程式例程都應該有自己的一組「可等待」計時器物件。

如果您使用 CustomTimerDpc 例程,請仔細選擇驅動程式傳入呼叫 KeSetTimerKeSetTimerEx的間隔。 此外,請考慮呼叫 KeCancelTimer 的所有可能效果, 與發出此呼叫的任何驅動程式例程相同的定時器物件,特別是在 SMP 平臺上。

請記住下列有關 CustomTimerDpc 例程的事實:

只有一個代表特定 DPC 例程的 DPC 物件實例可以在任何時刻排入佇列執行。

如果第二個驅動程式例程在第一個呼叫端指定的間隔到期之前呼叫 KeSetTimerKeSetTimerEx 來執行相同的 CustomTimerDpc 例程,那麼只有在第二個呼叫端指定的間隔到期之後,才會執行 CustomTimerDpc 例程。 在這些情況下,CustomTimerDpc 不會執行稱為 KeSetTimerKeSetTimerEx的第一個例程。

對於具有 CustomTimerDpc 的驅動程式 例程,並使用定期定時器:

驅動程式無法從 DPC 例程解除分配定期定時器。 驅動程式只能在 DPC 例程中取消分配非週期性計時器。

針對 CustomDpcCustomTimerDpc 例程的驅動程式,請考慮下列設計指導方針:

若要防止競爭條件,請勿將相同的 Dpc 指標傳遞至 KeSetTimerKeSetTimerExKeInsertQueueDpc

也就是說,假設驅動程式的 StartIo 例程呼叫 KeSetTimerKeSetTimerEx 來排入 CustomTimerDpc 例程,而驅動程式的 ISR 同時從擁有相同 Dpc 指標的另一個處理器呼叫 KeInsertQueueDpc。 當處理器上的 IRQL 低於DISPATCH_LEVEL或定時器間隔到期時,將會執行該 DPC 例程,無論哪一個都先行。 無論哪一個都先行,StartIo 或 ISR 的一些基本工作會由 DPC 例程卸除。

此外,兩個具有非常不同功能的標準驅動程式例程所使用的 DPC,效能特性會比個別 CustomTimerDpcCustomDpc 例程更差。 DPC 必須判斷要執行的作業,視導致 StartIo 例程或 ISR 排入佇列的條件而定。 在 DPC 中測試這些條件會使用額外的 CPU 週期。