共用方式為


使用 CustomTimerDpc 常式

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

回想 一下 KeSetTimerKeSetTimerEx,其先前指定的 TimerDpc 指標在先前指定的間隔到期之前,會有下列效果:

  • 核心會從計時器佇列中移除計時器物件,而不將物件設定為已發出訊號的狀態或佇列 CustomTimerDpc 常式。

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

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

如果驅動程式具有 CustomTimerDpc 常式,而且也會等候非位執行緒內容中的計時器物件,則應該:

  • 請勿在非位執行緒內容中使用執行緒內容相關計時器物件,反之亦然。

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

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

請記住下列 有關 CustomTimerDpc 常式的事實:

只有一個代表特定 DPC 常式的 DPC 物件具現化,可以在任何指定時間排入佇列以供執行。

如果第二個驅動程式常式呼叫 KeSetTimerKeSetTimerEx ,以在第一個呼叫端指定的間隔到期之前執行相同的 CustomTimerDpc 常式, 則 CustomTimerDpc 常式只會在第二個呼叫端指定的間隔到期之後執行。 在這些情況下, CustomTimerDpc 不會執行第一個常式 稱為 KeSetTimer 或 KeSetTimerEx的工作

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

驅動程式無法從 DPC 常式解除配置定期計時器。 驅動程式只能從 DPC 常式解除配置非永久性計時器。

針對同時具有 CustomDpc 和CustomTimerDpc 常式的驅動程式,請考慮下列設計指導方針:

若要避免競爭狀況,請勿將相同的Dpc指標傳遞至KeSetTimer 或 KeSetTimerExKeInsertQueueDpc

換句話說,假設驅動程式的StartIo常式會呼叫KeSetTimer 或KeSetTimerEx來將CustomTimerDpc常式排入佇列,而驅動程式的 ISR 會從具有相同Dpc指標的另一個處理器同時呼叫KeInsertQueueDpc。 當處理器上的 IRQL 低於DISPATCH_LEVEL或計時器間隔到期時,就會執行該 DPC 常式,以優先為准。 首先, StartIo 或 ISR 的一些基本工作只會由 DPC 常式卸載。

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