次の方法で共有


共有している状態情報へのアクセス

状態を維持する SynchCritSection ルーチンの設計と記述には、次の一般的なガイドラインを使用します。

  • ISR もアクセスするデータにアクセスするには、ドライバー ルーチンが SynchCritSection ルーチンを呼び出す必要があります。 非クリティカルのセクションコードは中断される可能性があります。 ISR が DIRQL で実行され、スピンロック (KeAcquireSpinLock) を取得すると、割り込みが現在のプロセッサで ISR を呼び出すことができるよう IRQL がDISPATCH_LEVELにのみ発生するため、ISR もアクセスするデータを保護するためにスピンロックを取得するだけでは十分ではないことに注意してください。

  • 状態変数の個別のセットに対する状態情報の責任をメインする各 SynchCritSection ルーチンを指定します。 つまり、重複する状態情報を保持する SynchCritSection ルーチンを記述しないでください。

    これにより、 SynchCritSection ルーチン (およびISR) が同じ状態に同時にアクセスしようとする間のコンテンション(競合状態)が回避されます。

    これにより、1 つの SynchCritSection ルーチンが制御を返すために同じ状態情報の一部を更新する別のルーチンを待機する必要がないため、各 SynchCritSection ルーチンができるだけ迅速に制御を返すようにもなります。

  • 実際に役立つ作業よりも多くの条件のテストを実行して、何をすべきかを判断する単一の大規模な汎用 SynchCritSection ルーチンを記述しないでください。 一方、各ルーチンは 1 バイトの状態情報のみを更新するため、条件付きステートメントを実行しない SynchCritSection ルーチンが多数あることは避けてください。

  • SynchCritSection ルーチンを実行するとドライバーの ISR が実行できなくなるため、すべての SynchCritSection ルーチンにはできるだけすみやかに制御を返すことが求められ…ります。

デバイス拡張機能にタイマーカウンターを維持する方法を次に示します。 ドライバーがカウンターを使用して、I/O 操作がタイムアウトしたかどうかを判断すると仮定します。また、ドライバーが I/O 操作と重複していないと仮定します。

  • ドライバーの StartIo ルーチンは、各 I/O 要求の初期値にタイマーカウンターを初期化します。 その後、ドライバーは IoTimer ルーチンが制御を返した場合に備えて、デバイスのタイムアウト値に一秒を追加します。

  • ドライバーの ISRは、このタイマーカウンターをマイナス 1 に設定する必要があります。

  • ドライバーの IoTimer ルーチンは 1 秒に 1 回呼び出され、タイム カウンターを読み取り、ISR で既にマイナス 1 に設定されているかどうかを判断します。 そうでない場合、 IoTimer ルーチンは KeSynchronizeExecution を使用してカウンターをデクリメントし、SynchCritSection_1 ルーチンを呼び出します。

    カウンターがゼロに設定され、要求がタイムアウトしたことを示す場合、SynchCritSection_1 ルーチンはSynchCritSection_2 ルーチンを呼び出して、デバイスのリセット操作をプログラムします。 カウンターがマイナス 1 の場合、 IoTimer ルーチンは元に戻ります。

  • ドライバーの DpcForIsr ルーチンが部分的な転送操作を開始するデバイスを再プログラミングする必要がある場合は、StartIo ルーチンと同様にタイマーカウンターを再初期化する必要があります。

    DpcForIsr ルーチンでは、 KeSynchronizeExecution を使用して、SynchCritSection_2 ルーチン (場合によってはSynchCritSection_3ルーチン) を呼び出し、デバイスを別の転送操作用にプログラムする必要もあります。

このシナリオでは、ドライバーには複数の SynchCritSection ルーチンがあり、それぞれに個別の特定の責任があります。タイマーカウンターを保持するルーチンと、デバイスをプログラムするための 1 つ以上のルーチンがあります。 各 SynchCritSection ルーチンは、単一の個別のタスクを実行するため、制御をすばやく返すことができます。

ドライバーには、ドライバーの ISR と共にタイマーカウンターに状態を保持する 1 つの メインSynchCritSection_1 ルーチンがあることに注意してください。 したがって、複数の SynchCritSection ルーチンと ISR 間でタイマーカウンターにアクセスするための競合はありません。