下列範例說明迷你驅動程式需要執行的同步處理動作,並包含不應使用同步處理的範例:
範例一:具有正常運作 ISR 的迷你驅動程式
如果啟用了串流類別同步,則會使用 KeSynchronizeExecution在提高的 IRQL 上呼叫所有迷你驅動程式進入點,這表示當迷你驅動程式執行其程式碼時,配接器的 IRQ 層級和所有較低的 IRQ 層級會被遮罩。 因此,迷你驅動程式在此模式中必須只執行少量工作。
迷你驅動程式不應該在提高的 IRQL(中斷請求層級)狀態下執行通常需超過 10 到 20 微秒的程式碼。 如果您使用stream.sys的偵錯版本,流類別會記錄在引發 IRQL 所花費的時間,並檢查驅動程式是否花費了過多的時間。 如果迷你驅動程式只需要針對要求設定硬體 DMA 暫存器,或只需要讀取其 ISR 中的埠,則通常可以在引發的 IRQL 執行其所有處理。
如果迷你驅動程式需要執行花費超過幾微秒的處理,例如透過 PIO 傳輸數據的迷你驅動程式,迷你驅動程式應該使用 StreamClassCallAtNewPriority 來排程 DISPATCH_LEVEL 回呼。 在回呼中,迷你驅動程式可能需要大約 1/2 到 1 毫秒的時間來進行其處理程序。 在此模式下要記住的一件事是DISPATCH_LEVEL回調 未 與ISR同步。
如果迷你驅動程式在回呼期間以及 ISR 中存取資源 (例如埠或佇列) 時,硬體保持穩定,則此缺乏同步處理不是問題。 但是,如果不穩定可能會成為問題,迷你驅動程式需要使用StreamClassCallAtNewPriority來排程高優先權回呼,其中DISPATCH_LEVEL回呼會觸碰與ISR所使用的共用資源。
請注意,HIGH 優先順序回呼相當於呼叫 KeSynchronizeExecution。 KeSynchronizeExecution 需要迷你驅動程式參考 StreamClassCallAtNewPriority 未參考的數個參數,但一般而言,這兩個參數會產生相同的行為。
如果迷你驅動程式只是偶爾需要執行超過 1/2 到 1 毫秒的程式代碼,或偶爾需要在PASSIVE_LEVEL呼叫服務 (例如在初始化時) ,則可以使用將 StreamClassCallAtNewPriority 設定為 LOW 優先順序來取得PASSIVE_LEVEL背景工作執行緒。 請注意,低優先順序回呼不會與任何項目同步,而迷你驅動程式在執行低優先順序回呼時,可能會收到新的請求(假設 ReadyForNextRequest NotificationType 參數尚未處理完畢)或進行 ISR 呼叫。
範例二:沒有 ISR 的迷你驅動程式
如果已開啟串流類別同步處理,則會在 DISPATCH_LEVEL 呼叫迷你驅動程式的進入點。 迷你驅動程式可以執行長達 1/2 到 1 毫秒持續時間的處理,而不需要調整優先順序。 如果小型驅動程式偶爾只需要執行花費超過 1/2 毫秒的代碼,或偶爾需要在PASSIVE_LEVEL呼叫服務(例如在初始化階段),則可以使用具有低優先順序的StreamClassCallAtNewPriority來獲取PASSIVE_LEVEL背景工作執行緒。 請注意,低優先順序回呼不會與任何專案同步處理,而且迷你驅動程式在執行低優先順序回呼時,可能會收到新的要求 (假設 ReadyForNextRequest NotificationType 參數擱置中) 。
串流類別同步不應使用時
以下是不應使用串流類別同步處理的情況範例。 這些包括:
當驅動程式經常需要處理時間超過1毫秒的操作(超過迷你驅動程式接收到的要求的20%),或頻繁需要呼叫 PASSIVE_LEVEL 服務,例如 Microsoft DirectDraw時。 使用 stream.sys 的偵錯版本時,串流類別會斷言這兩種情況,並在同步處理開啟時偵測到它們時停止。
當迷你驅動程式作為無相關硬體的篩選器時。 這類迷你驅動程式應該以 PASSIVE_LEVEL 執行,因為沒有要同步處理的基礎硬體,而且迷你驅動程式通常會執行大量處理。 在這種情況下,執行自己的同步比使用流類同步浪費額外負荷更容易。 如有必要,請使用互斥鎖來保護佇列。
同步程式碼中的錯誤通常很難找到,並且在某些環境中(例如在多處理器系統上運行的基於 NT 的作業系統),錯誤可能只有在經過數小時的壓力後才會出現。 根據供應商的經驗,這些不是大多數供應商有能力或想要調試的事情。 只有熟悉撰寫完全異步 WDM 裝置驅動程式的驅動程式開發人員應該嘗試自行進行同步處理。
當迷你驅動程式是匯流排類型的驅動程式 (例如,USB 或 1394 周邊驅動程式) 時,不會真正擔心實際硬體的同步處理,但只會在 PASSIVE_LEVEL 呼叫要求至下一層,並接收通常在 DISPATCH_LEVEL 的回呼。