次の方法で共有


マルチプロセッサ セーフ

Microsoft Windows NT ベースのオペレーティング システムは、ユニプロセッサ プラットフォームと対称型マルチプロセッサ (SMP) プラットフォームで同様に動作するように設計されているので、カーネル モード ドライバーも同様に動作するように設計する必要があります。

どの Windows マルチプロセッサ プラットフォームに対しても以下の要件があります。

  • すべての CPU が同一であり、すべてのプロセッサに同一のコプロセッサがあるか、どのプロセッサにもコプロセッサがないこと。

  • すべての CPU がメモリを共有し、メモリに同等なアクセスができること。

  • 対称型プラットフォームでは、すべての CPU がメモリにアクセスでき、割り込みを受け入れ、I/O 制御レジスタにアクセスできること (一方、非対称型マルチプロセッサ マシンでは、1 つの CPU がその下位 CPU のセットに対する割り込みをすべて受け入れます)。

SMP プラットフォーム上でオペレーティング システムを安全に実行するには、あるプロセッサがアクセスして変更しているデータに、別のプロセッサで実行しているコードが同時にアクセスして変更することがないようにする必要があります。 たとえば、最下位レベルのドライバーの ISR が 1 つのプロセッサ上でデバイス割り込みを扱っている場合、そのデバイスが別のプロセッサ上で同時に割り込むことがないように、その ISR はデバイス レジスタまたは重要なドライバー定義データに排他的にアクセスできる必要があります。

さらに、ユニプロセッサ コンピューターでシリアル化したドライバーの I/O 操作が、SMP コンピューターでは重複することがあります。 つまり、受信する I/O 要求を処理するドライバーのルーチンがあるプロセッサで実行され、デバイスと通信する別のルーチンが別のプロセッサで同時に実行されることがあり得ます。 カーネル モード ドライバーを実行するコンピューターが単一プロセッサであるか対称型マルチプロセッサであるかに関係なく、そのドライバーでは、ドライバー ルーチン間で共有するドライバー定義データやシステム提供のリソースへのアクセスを同期する必要があります。また、物理デバイスがあれば、そのデバイスへのアクセスも同期する必要があります。

Windows NT カーネル コンポーネントは、同期メカニズムであるスピン ロックをエクスポートします。ドライバーでスピンロックを使用すると、対称型マルチプロセッサ プラットフォーム上で同時に実行されている 1 つ以上のルーチンによる同時アクセスから共有データ (デバイス レジスタ) を保護できます。 スピン ロックの使用に関する以下の 2 つのポリシーがカーネルによって適用されます。

  • 特定の時点で特定のスピン ロックを保持できるルーチンは 1 つのみです。 共有データを参照する各ルーチンは、そのデータにアクセスする前に、そのスピン ロックを取得する必要があります。 現在のルーチンがアクセスしているデータに他のルーチンがアクセスするには、そのスピン ロックを取得する必要がありますが、スピン ロックは現在の所有者が解放するまで取得できません。

  • カーネルは、システムにある各スピン ロックに IRQL 値を割り当てます。 カーネル モード ルーチンは、特定のスピン ロックに割り当てられた IRQL でルーチンが実行されている場合にのみ、そのスピン ロックを取得できます。

このようなポリシーにより、通常は低い IRQL で実行されるものの現在はスピン ロックを保持しているドライバー ルーチンが、同じスピン ロックを取得しようとしている優先度の高いドライバー ルーチンによって割り込まれことがありません。 したがって、デッドロックの発生を防止できます。

スピン ロックに割り当てられる IRQL は、通常、そのスピン ロックを取得できるルーチンの IRQL のうち、最も高い IRQL です。

たとえば、最下位レベルのドライバーの ISR は、ドライバーの DPC ルーチンと状態領域を頻繁に共有します。 DPC ルーチンは、ドライバー指定の クリティカル セクション ルーチンを呼び出して共有領域にアクセスします。 共有領域を保護するスピン ロックの IRQL は、デバイスの割り込みレベルである DIRQL に等しくなっています。 クリティカル セクション ルーチンがスピン ロックを保持し、DIRQL で共有領域にアクセスする限り、ユニプロセッサ マシンでも SMP マシンでも ISR を実行できません。

  • ユニプロセッサ コンピューターでは ISR を実行できません。「常に割り込み可能で常に中断可能」の説明にあるように、デバイス割り込みがマスクされるからです。

  • SMP マシンでは、共有データを保護するスピン ロックを ISR は取得できません。一方、クリティカル セクション ルーチンは共有データを保護するスピン ロックを保持し、DIRQL で共有データにアクセスします。

一連のカーネル モード スレッドは、カーネルのディスパッチャー オブジェクトを待機することにより、共有データまたは共有リソースへのアクセスを同期できます。このようなディスパッチャー オブジェクトとして、イベント、ミューテックス、セマフォ、タイマー、別のスレッドなどがあります。 ただし、ほとんどのドライバーは、スレッド コンテキストを切り替えないことで高いパフォーマンスが得られることから、専用のスレッドを設定しません。 タイム クリティカルなカーネル モードをサポートするルーチンとドライバーを、DISPATCH_LEVEL とした IRQL または DIRQL で実行する場合は、カーネルのスピン ロックを使用して共有データまたは共有リソースへのアクセスを同期する必要があります。

詳細については、「スピン ロックの概要」、「ハードウェアの優先度の管理」、「カーネル ディスパッチャー オブジェクトの概要」を参照してください。