使用 Driver-Created 執行緒管理內嵌的佇列

新的驅動程式應該優先使用 取消安全的 IRP 佇列 架構,以使用本節中所述的方法。

就像系統磁片磁碟機驅動程式一樣,具有裝置專用線程的驅動程式,而不是 StartIo 常式,通常會在多倍連結的連線佇列佇列中管理自己的 IRP 佇列。 驅動程式的執行緒會在裝置上完成工作時,從其連結佇列提取 IRP。

一般而言,驅動程式必須將其執行緒與執行緒同步處理到執行緒與其他驅動程式常式之間共用的任何資源。 驅動程式也必須有一些方法,才能通知其驅動程式建立的執行緒,IRP 已排入佇列。 通常,執行緒會在儲存在裝置延伸模組中的發送器物件上等候,直到驅動程式的 Dispatch 常式在將 IRP 插入到連結佇列之後,將發送器物件設定為 Signaled 狀態為止。

呼叫驅動程式的 Dispatch 常式時,每個都會檢查輸入 IRP 之 I/O 堆疊位置中的參數,如果參數有效,則會將要求排入佇列以進一步處理。 針對排入驅動程式專用線程的每個 IRP,分派常式應該設定其執行緒在呼叫 ExInterlockedInsertXxx清單之前處理該 IRP 所需的內容。 每個 IRP 中的驅動程式 I/O 堆疊位置會提供驅動程式對目標裝置物件的裝置延伸模組的執行緒存取權,其中驅動程式可以與其執行緒共用內容資訊,因為執行緒會從佇列中移除每個 IRP。

佇列可取消 IRP 的驅動程式必須實作 Cancel 常式。 由於 IRP 會以非同步方式取消,因此您必須確保驅動程式可避免產生的競爭狀況。 請參閱 同步處理 IRP 取消 。如需與取消 IRP 和避免其相關競爭條件的詳細資訊。

任何驅動程式建立的執行緒都會在 IRQL = PASSIVE_LEVEL,以及在先前呼叫 PsCreateSystemThread的驅動程式時設定的基底執行時間優先順序執行。 執行緒對 ExInterlockedRemoveHeadList 的呼叫會暫時引發 IRQL,以在目前處理器上DISPATCH_LEVEL,同時從驅動程式的內部佇列中移除 IRP。 原始 IRQL 會在從這個呼叫傳回時還原至PASSIVE_LEVEL。

任何驅動程式執行緒 (或驅動程式提供的背景工作執行緒回呼) 都必須仔細管理其執行所在的 IRQL。 例如,設想下列情況:

  • 因為系統執行緒通常會在 IRQL = PASSIVE_LEVEL執行,所以驅動程式執行緒可能會等待核心定義的發送器物件設定為訊號狀態。

    例如,裝置專用線程可能會等待其他驅動程式滿足事件,並完成執行緒使用 IoBuildSynchronousFsdRequest設定的部分傳輸 IRP 數目。

  • 不過,這類裝置專用線程必須在目前的處理器上引發 IRQL,才能呼叫特定的支援常式。

    例如,如果驅動程式使用 DMA,其裝置專用線程必須在呼叫 KeRaiseIrqlKeLowerIrql之間巢狀地呼叫AllocateAdapterChannelFreeAdapterChannel,因為這些常式和 DMA 作業的某些其他支援常式必須在 IRQL = DISPATCH_LEVEL呼叫。

    請記住,StartIo常式是在DISPATCH_LEVEL執行,因此使用 DMA 的驅動程式不需要從其StartIo常式呼叫KeXxxIrql常式。

  • 驅動程式建立的執行緒可以存取可分頁記憶體,因為它會在非位執行緒內容中執行, (自己的) IRQL = PASSIVE_LEVEL,但許多其他標準驅動程式常式會在 IRQL > = DISPATCH_LEVEL執行。 如果驅動程式建立的執行緒配置這類常式可以存取的記憶體,則必須從非分頁集區配置記憶體。 例如,如果裝置專用線程配置驅動程式的 ISR 或SynchCritSectionAdapterControl、AdapterListControlControllerControlDpcForIsr、CustomDpcIoTimerCustomTimerDpc或較高層級驅動程式IoCompletion常式中存取的任何緩衝區,則執行緒配置的記憶體無法分頁。

  • 如果驅動程式維護裝置擴充功能中的共用狀態資訊或資源,驅動程式執行緒 (類似 StartIo 常式) 必須同步處理其實體裝置的存取權,以及與驅動程式的其他常式共用資料,這些常式會存取相同的裝置、記憶體位置或資源。

    如果執行緒與 ISR 共用裝置或狀態,它必須使用 KeSynchronizeExecution 呼叫驅動程式提供的 SynchCritSection 常式,以程式設計裝置或存取共用狀態。 請參閱 使用重要區段

    如果執行緒與 ISR 以外的常式共用狀態或資源,驅動程式必須使用驅動程式提供儲存體的驅動程式初始化執行微調鎖定來保護共用狀態或資源。 如需詳細資訊,請參閱 微調鎖定

如需使用驅動程式執行緒進行緩慢裝置的設計取捨的詳細資訊,請參閱 輪詢裝置。 另請參閱 管理硬體優先順序。 如需特定支援常式 IRQL 的特定資訊,請參閱常式的參考頁面。