共用方式為


存取共用狀態資訊

使用下列一般指導方針來設計和撰寫維護狀態的 SynchCritSection 常式

  • 若要存取 ISR 也會存取的資料,驅動程式常式必須呼叫 SynchCritSection 常式。 非關鍵區段程式碼可能會中斷。 請記住,只要取得微調鎖定來保護 ISR 也存取的資料並不足以保護 ISR,因為 ISR 會在 DIRQL 上執行,並取得微調鎖定 (KeAcquireSpinLock) 只會引發 IRQL 來DISPATCH_LEVEL,這可讓中斷在目前的處理器上叫用 ISR。

  • 為每個 SynchCritSection 常式提供維護一組離散狀態變數的狀態資訊責任。 也就是說,請避免撰寫維護重迭狀態資訊的 SynchCritSection 常式。

    這可防止 SynchCritSection 常式 (和 ISR) 嘗試同時存取相同狀態之間的爭用和可能競爭狀況。

    這也可確保每個 SynchCritSection 常式都會儘快傳回控制項,因為一個 SynchCritSection 常式永遠不需要等待另一個同步處理狀態資訊來傳回控制項。

  • 避免撰寫單一、大型、一般用途 的 SynchCritSection 常式,以執行更多條件測試,以判斷要執行的動作,而不是實際執行實用工作。 另一方面,請避免有許多 SynchCritSection 常式永遠不會執行條件陳述式,因為每個常式只會更新一個位元組的狀態資訊。

  • 每個 SynchCritSection 常式都必須儘快傳回控制權,因為執行任何 SynchCritSection 常式可防止驅動程式的 ISR 執行。

以下是在裝置擴充功能中維護計時器計數器的技術。 假設驅動程式使用計數器來判斷 I/O 作業是否已逾時。此外,假設驅動程式不會重迭 I/O 作業。

  • 驅動程式的 StartIo 常式會將計時器計數器初始化為每個 I/O 要求的某些初始值。 然後,驅動程式會將第二個新增至其裝置逾時值,以防 其 IoTimer 常式剛傳回控制權。

  • 驅動程式的 ISR 必須將此計時器計數器設定為減一。

  • 驅動程式的 IoTimer 常式每秒呼叫一次,以讀取時間計數器,並判斷 ISR 是否已將其設定為減一。 如果沒有, IoTimer 常式會使用 KeSynchronizeExecution 來遞減計數器,以呼叫SynchCritSection_1常式。

    如果計數器移至零,表示要求逾時,SynchCritSection_1常式會呼叫SynchCritSection_2常式來程式設計裝置重設作業。 如果計數器減一, IoTimer 常式只會傳回 。

  • 如果驅動程式的 DpcForIsr 常式必須重新編譯裝置以開始部分傳輸作業,則必須重新初始化計時器計數器,因為 StartIo 常式確實如此。

    DpcForIsr常式也必須使用KeSynchronizeExecution呼叫SynchCritSection_2常式,或可能是SynchCritSection_3常式,以程式設計裝置以進行其他傳輸作業。

在此案例中,驅動程式有一個以上的 SynchCritSection 常式 ,每個常式都有離散、特定的責任;一個用來維護其計時器計數器,另一或多個用來設計裝置的程式。 每個 SynchCritSection 常式都可以快速傳回控制項,因為它會執行單一離散工作。

請注意,驅動程式具有單一SynchCritSection_1常式,以及驅動程式的 ISR 會維護計時器計數器的狀態。 因此,數個 SynchCritSection 常式和 ISR 之間沒有存取計時器計數器的爭用。