(57)【要約】【課題】コンピュータシステム内の拡張ボードの動作をモデル化する装置および方法を提供する。【解決手段】拡張カードがインストールされるとき、カードを表すためにオブジェクトがコンピュータビューアによって作成される。コンピュータビューアはカードオブジェクトを使用してカードを調べ、各関数のために必要とするリソースを取得する。リソース要求はリソース競合リゾルバオブジェクトにも与えられ、カード上の各入出力機能にリソースを割り当てることが試みられる。リソース割り当てはオブジェクトにもストアされる。コンピュータビューアはカードオブジェクトを使用して、リソースオブジェクトを永続的ストレージにストアする。次回のシステムブートオペレーション期間には、システムに存在する拡張バスとカードを特定するバスおよびカードレコグナイザオブジェクトを作成し、各拡張カードを表すために機能リソースオブジェクトを永続的ストレージから取り出す。【選択図】図２
2010015595.tif 000002
【特許請求の範囲】
【請求項１】
メモリと、複数のシステムリソースと、拡張カードをコンピュータシステムに追加するためのプログラムを実行するプロセッサにより実現されるコンピュータビューアとを有するコンピュータシステムで使用される装置であって、該装置は、
(a) 前記拡張カードに固有でありかつ前記拡張カード上の入出力機能のためにシステムリソース割り当てを決定し操作する複数のメソッドを有するカードオブジェクトを、前記メモリ内に構築するための、前記コンピュータビューア内の仕組みを提供する手段と、
(b)前記カードオブジェクトを使用してシステムリソース要求を取得するための、前記コンピュータビューア内の仕組みを提供する手段と、
(c) 前記カードオブジェクトに対する一貫性のあるインタフェースを有し、前記コンピュータシステム内の全ての入出力機能に対するシステムリソース割り当て情報へアクセスするためのプログラムを実行するプロセッサにより実現されるリソースマネージャと、
(d)前記コンピュータシステムが起動される度に前記リソースマネージャを使用して前記拡張カード上の入出力機能のために無競合システムリソース割り当てを取得するための、前記コンピュータビューア内の仕組みを提供する手段と、
(e) 前記コンピュータビューアの制御の下で前記カードオブジェクトを使用して、システムリソース割り当てデータを前記メモリにストアし、前記カードオブジェクト内のメソッドの１つを呼び出して、前記カードオブジェクトをプログラムすることにより、手段 (d) により取得された無競合リソース割り当てを使用するために前記カードにより要求されたシステムリソースを動的に変更して、前記無競合リソース割り当てに適合させる前記コンピュータビューア内の仕組みを提供する手段と
を備えたことを特徴とする装置。
【請求項２】
請求項１に記載の装置において、前記カードオブジェクトは、前記拡張カードが自動構成可能カードである場合にシステムリソース要求を前記拡張カードから取得するメカニズムを備えたことを特徴とする装置。
【請求項３】
請求項１に記載の装置において、前記カードオブジェクトは、前記拡張カードがマニュアル構成可能カードである場合にシステムリソース要求を構成オプションデータベースから取得するメカニズムを備えたことを特徴とする装置。
【請求項４】
請求項１に記載の装置において、前記カードオブジェクトは、前記拡張カード上の入出力機能のためのシステムリソース要求、前記入出力機能のための可能なシステムリソース割り当ておよび前記可能なシステムリソース割り当てのうちの無競合システムリソース割り当てをカプセル化する機能リソースオブジェクトを構築するメカニズムを備えたことを特徴とする装置。
【請求項５】
請求項４に記載の装置において、前記リソースマネージャは、システムリソース要求に応答して、拡張カード間のシステムリソース競合を検出する競合検出器をさらに備え、および前記カードオブジェクトは、前記コンピュータビューアによって実行可能で、可能なシステムリソース割り当てを前記競合検出器により登録する手段を備えたことを特徴とする装置。
【請求項６】
請求項５に記載の装置において、前記カードオブジェクトは、前記コンピュータビューアによって実行可能で、無競合システムリソース割り当てを前記競合検出器から取得する手段を備えたことを特徴とする装置。
【請求項７】
請求項４に記載の装置において、前記カードオブジェクトは、前記コンピュータビューアによって実行可能で、前記機能リソースオブジェクトを前記メモリにストアする手段を備えたことを特徴とする装置。
【請求項８】
請求項４に記載の装置において、前記カードオブジェクトは機能リソースオブジェクトのリンクリストを備えたことを特徴とする装置。
【請求項９】
請求項１に記載の装置において、前記カードオブジェクトは、前記コンピュータビューアによって実行可能で、および前記拡張カード上の入出力機能を使用可能にし、使用禁止にする手段をさらに備えたことを特徴とする装置。
【請求項１０】
請求項１に記載の装置において、前記カードオブジェクトは、前記コンピュータビューアによって実行可能で、前記拡張カードのベンダ情報を取得する手段をさらに備えたことを特徴とする装置。
【請求項１１】
メモリと、複数のシステムリソースと、拡張カードをコンピュータシステムに追加するためのプログラムを実行するプロセッサにより実現されるコンピュータビューアとを有するコンピュータシステムで使用される方法であって、該方法は、
(a) 前記拡張カードに固有でありかつ前記拡張カード上の入出力機能のためにリソース割り当てを決定し操作する複数のメソッドを有するカードオブジェクトを、前記コンピュータビューアを使用して前記メモリに構築するステップと、
(b) 前記コンピュータビューアの制御の下で前記カードオブジェクトを使用して、システムリソース要求を取得するステップと、
(c) 前記カードオブジェクトに対する一貫性のあるインタフェースを有し、前記コンピュータシステム内の全ての入出力機能に対するシステムリソース割り当て情報へアクセスするためのプログラムを実行するプロセッサにより実現されるリソースマネージャを作成するステップと、
(d) 前記コンピュータビューアの制御の下で前記リソースマネージャを使用して、前記コンピュータシステムが起動される度に前記拡張カード上の入出力機能のために無競合システムリソース割り当てを取得するステップと、
(e) 前記コンピュータビューアの制御の下で前記カードオブジェクトを使用して、システムリソース割り当てデータを前記メモリにストアし、前記カードオブジェクト内のメソッドの１つを呼び出して、前記カードオブジェクトをプログラムすることにより、ステップ (d) により取得された無競合リソース割り当てを使用するために前記カードにより要求されたシステムリソースを動的に変更して、前記無競合リソース割り当てに適合させるステップと
を備えたことを特徴とする方法。
【請求項１２】
請求項１１に記載の方法において、ステップ (b) は、
(b1) 前記拡張カードが自動構成可能カードである場合に前記カードオブジェクトを使用して、システムリソース要求を前記拡張カードから取得するステップ
を備えたことを特徴とする方法。
【請求項１３】
請求項１１に記載の方法において、ステップ (b) は、
(b2) 前記拡張カードがマニュアル構成可能カードである場合に前記カードオブジェクトを使用して、システムリソース要求を構成オプションデータベースから取得するステップ
を備えたことを特徴とする方法。
【請求項１４】
請求項１１に記載の方法において、
(e) 前記拡張カード上の入出力機能のために要求するシステムリソース、前記入出力機能のための可能なシステムリソース割り当ておよび前記可能なシステムリソース割り当てのうちの無競合システムリソース割り当てをカプセル化する機能リソースオブジェクトを、前記カードオブジェクトを使用して構築するステップ
をさらに備えたことを特徴とする方法。
【請求項１５】
請求項１４に記載の方法において、前記リソースマネージャは、システムリソース要求に応答して拡張カード間のシステムリソース競合を検出する競合検出器をさらに備え、ステップ (c) は、
(c1) 前記コンピュータビューアの制御の下で前記カードオブジェクトを使用して、可能なリソース割り当てを前記競合検出器により登録するステップ
を備えたことを特徴とする方法。
【請求項１６】
請求項１５に記載の方法において、ステップ (c) は、
(c2) 前記コンピュータビューアの制御の下で前記カードオブジェクトを使用して、無競合システムリソース割り当てを前記競合検出器から取得するステップ
を備えたことを特徴とする方法。
【請求項１７】
請求項１４に記載の方法において、ステップ (d) は、
(d1) 前記コンピュータビューアの制御の下でカードオブジェクトを使用して、前記機能リソースオブジェクトを前記メモリにストアするステップ
を備えたことを特徴とする方法。
【請求項１８】
請求項１４に記載の方法において、ステップ (a) は、
(a1) 機能リソースオブジェクトのリンクリストを前記カードオブジェクト内に構築するステップ
を備えたことを特徴とする方法。
【請求項１９】
請求項１４に記載の方法において、ステップ (a) は、
(a2) 前記カードオブジェクト内の前記拡張カード上の入出力機能を使用可能にし、および使用禁止にするメソッドを呼び出すステップ
を備えたことを特徴とする方法。
【請求項２０】
請求項１４に記載の方法において、ステップ (a) は、
(a3) 前記カードオブジェクト内の前記拡張カードのベンダ情報を取得するメソッドを呼び出すステップ
を備えたことを特徴とする方法。
【請求項２１】
メモリと、複数のシステムリソースと、拡張カードをコンピュータシステムに追加するためのプログラムを実行するプロセッサにより実現されるコンピュータビューアとを有するコンピュータシステムで使用されるコンピュータ使用可能媒体であって、該コンピュータ使用可能媒体は、コンピュータ読取可能プログラムコードがそこに格納されており、前記コンピュータ読取可能プログラムコードは、
(a) 前記拡張カードに固有でありかつ前記拡張カード上の入出力機能のためにリソース割り当てを決定し操作する複数のメソッドを有するカードオブジェクトを、前記コンピュータビューアを使用して前記メモリ内に構築するためのプログラムコードと、
(b) 前記コンピュータビューアの制御の下で前記カードオブジェクトを使用して、システムリソース要求を取得するためのプログラムコードと、
(c) 前記プロセッサを、前記カードオブジェクトに対する一貫性のあるインタフェースを有し、前記コンピュータシステム内の全ての入出力機能に対するシステムリソース割り当て情報へアクセスするリソースマネージャとして機能させるプログラムコードと、
(d) 前記コンピュータビューアの制御の下で前記リソースマネージャを使用して、前記コンピュータシステムが起動される度に前記拡張カード上の入出力機能のために無競合システムリソース割り当てを取得するためのプログラムコードと、
(e) 前記コンピュータビューアの制御の下で前記カードオブジェクトを使用して、システムリソース割り当てデータを前記メモリ内にストアし、前記カードオブジェクト内のメソッドの１つを呼び出して、前記カードオブジェクトをプログラムすることにより、プログラムコード (d) により取得された無競合リソース割り当てを使用するために前記カードにより要求されたシステムリソースを動的に変更して、前記無競合リソース割り当てに適合させるためのプログラムコードと
を備えたことを特徴とするコンピュータ使用可能媒体。
【請求項２２】
請求項２１に記載のコンピュータ使用可能媒体において、前記カードオブジェクトを使用してシステムリソース要求を取得するための前記プログラムコードは、前記拡張カードが自動構成可能カードである場合、前記カードオブジェクトを使用してシステムリソース要求を前記拡張カードから取得するためのプログラムコードを備えたことを特徴とするコンピュータ使用可能媒体。
【請求項２３】
請求項２１に記載のコンピュータ使用可能媒体において、前記カードオブジェクトを使用してシステムリソース要求を取得するための前記プログラムコードは、前記拡張カードがマニュアル構成可能カードである場合、前記カードオブジェクトを使用してシステムリソース要求を構成オプションデータベースから取得するためのプログラムコードを備えたことを特徴とするコンピュータ使用可能媒体。
【請求項２４】
請求項２１に記載のコンピュータ使用可能媒体において、前記コンピュータ読取可能プログラムコードは、前記拡張カード上の入出力機能のために要求するシステムリソース、前記入出力機能のための可能なシステムリソース割り当ておよび前記可能なシステムリソース割り当てのうちの無競合システムリソース割り当てをカプセル化する機能リソースオブジェクトを、前記カードオブジェクトを使用して構築するためのプログラムコードをさらに備えたことを特徴とするコンピュータ使用可能媒体。
【請求項２５】
請求項２４に記載のコンピュータ・プログラム使用可能媒体において、前記リソースマネージャは、システムリソース要求に応答して、拡張カード間のシステムリソース競合を検出する競合検出器をさらに備え、および無競合リソース割り当てを取得するための前記プログラムコードは、前記コンピュータビューアの制御の下で前記カードオブジェクトを使用して、可能なシステムリソース割り当てを前記競合検出器により登録するためのプログラムコードを備えたことを特徴とするコンピュータ使用可能媒体。
【請求項２６】
請求項２５に記載のコンピュータ使用可能媒体において、無競合システムリソース割り当てを取得するための前記プログラムコードは、前記コンピュータビューアの制御の下で前記カードオブジェクトを使用して、無競合システムリソース割り当てを前記競合検出器から取得するためのプログラムコードを備えたことを特徴とするコンピュータ使用可能媒体。
【請求項２７】
請求項２４に記載のコンピュータ使用可能媒体において、リソース割り当てデータをストアするための前記プログラムコードは、前記コンピュータビューアの制御の下で前記カードオブジェクトを使用して、前記機能リソースオブジェクトを前記メモリ内にストアするためのプログラムコードを備えたことを特徴とするコンピュータ使用可能媒体。
【請求項２８】
請求項２４に記載のコンピュータ使用可能媒体において、前記カードオブジェクトを構築するための前記プログラムコードは、機能リソースオブジェクトのリンクリストを前記カードオブジェクト内に構築するためのプログラムコードを備えたことを特徴とするコンピュータ使用可能媒体。
【請求項２９】
請求項２４に記載のコンピュータ使用可能媒体において、前記カードオブジェクトを構築するための前記プログラムコードは、前記カードオブジェクト内で前記拡張カード上の入出力機能を使用可能にし、および使用禁止にするメソッドを備えたことを特徴とするコンピュータ使用可能媒体。
【請求項３０】
請求項２４に記載のコンピュータ使用可能媒体において、前記カードオブジェクトを構築するための前記プログラムコードは、前記カードオブジェクト内で前記拡張カードのベンダ情報を取得するメソッドを備えたことを特徴とするコンピュータ使用可能媒体。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明はコンピュータシステムの構成（コンフィギュレーション）に関し、さらに具体的には、コンピュータシステムに結合された複数の入出力 (I/O) デバイスにコンピュータシステムのリソースを割り当てる一方で、デバイス間のリソースの競合を防止するオブジェクト指向装置および方法に関する。
【背景技術】
【０００２】
代表的なコンピュータシステムは、相互に接続された種々のハードウェアコンポーネントおよびデバイスから構成されている。ここで、「コンピュータハードウェアコンポーネント」、「ハードウェアコンポーネント」、「ペリフェラル（周辺）デバイス」、あるいは単に「デバイス」という用語は、いずれも、一緒に結合されてコンピュータシステムを構成する個別のエレクトロニックデバイスのことを指している。例えば、コンピュータキーボード、マウス、モニタ、プリンタ、ハードディスクドライブ、フロッピディスクドライブ、メモリボードなどは、そのようなデバイスを構成している。これらのコンポーネントの多くは、一般に「プレーナ(planar)」または「マザーボード(motherboard)」と呼ばれている、プリント回路ボード (printed circuit board) 上に実装されている。
【０００３】
従来の多くのアーキテクチャでは、種々のコンポーネントはシステムバスによって１つに接続されている。ここでシステムバス (system bus) とは、その上を情報がコンポーネント間で転送される媒体のことである。システムバスは、データ、アドレスおよび制御情報を、種々のシステムコンポーネント間で伝達する、データライン、アドレスラインおよび制御ラインで構成されているのが代表的である。例えば、割り込み信号は、ペリフェラルデバイスの１つまたは２つ以上から、システムバスの制御ラインを通ってプロセッサに送られている。
【０００４】
システムバスおよびシステムバスに接続されている、ある種の基本ハードウェアコンポーネントは統合システム (integrated system) を構成し、これはマザーボード上に収容されているのが一般である。多くのパーソナルコンピュータシステムでは、システムバスは「拡張(expansion)」バスと呼ばれる拡張部分 (extension) に接続され、マザーボードは拡張バス上に１つまたは２つ以上のスロットまたはコネクタを有するのが代表的であり、これらのコネクタは、「拡張スロット(expansion slot)」とも、「拡張コネクタ(expansion connector)」とも呼ばれている。
【０００５】
コンピュータシステムのパフォーマンスを強化するために、「デバイス拡張ボード」とも、「デバイス拡張カード」とも、「拡張ボード」とも、「拡張カード」とも呼ばれるプリント回路ボード上の追加ハードウェアコンポーネントは、拡張スロットにプラグイン可能になっている。コンピュータシステムバスの特定アーキテクチャによっては、拡張カードは、独自のバスとスロットをもつバスアダプタを構成している場合がある。その場合、他の拡張カードを後者のスロットにプラグインすることが可能になっている。
【０００６】
拡張カードは、コンピュータシステムの能力またはパフォーマンスを強化するためにコンピュータシステムに結合されているのが一般である。例えば、拡張カードの一種として、メモリ拡張カードがあり、これはコンピュータシステムのプロセッサが使用できるランダムアクセスメモリ (RAM) の容量を増加するために使用されている。他の拡張カードとしては、サウンドカード、SCSIバスアダプタ、グラフィックスアクセラレータカード (graphics accelerator card)その他がある。
【０００７】
多くの拡張カードは、１つまたは２つ以上のパラメータの値を設定することでカスタマイズまたは構成することが可能になっている。あるカードでは、値は、ボード上に置かれたスイッチのジャンパを変更することで、マニュアル（手操作）で設定されている。他の場合は、パラメータはマニュアルで設定しているか、ソフトウェアによって自動的に設定している。さらに具体的には、コンピュータシステムは、コンピュータオペレーティングシステム（例えば、MS-DOS、OS/2など）と呼ばれるソフトウェアプログラムによって自動的に制御され、調整されているのが代表的である。システムバスに接続された各デバイスは、デバイスドライバ (device driver) と呼ばれる、別のソフトウェアルーチンを通してコンピュータオペレーティングシステムとやりとりしている。デバイスドライバはオぺレーティングシステムからコマンドを受け取り、そのコマンドを使用してデバイスを制御している。
【０００８】
デバイスパラメータがソフトウェアで設定される場合には、デバイスドライバは、多くの場合、そのデバイスパラメータにアクセスが可能であり、そのパラメータはデバイス自身に格納されていることもあれば、コンピュータメモリやコンピュータシステムの他の部分に格納されていることもある。その場合、デバイスパラメータはデバイスドライバソフトウェアを通してマニュアルで設定可能になっている。他の場合には、デバイスパラメータは、構成ソフトウェア (configuration software) がデバイスソフトウェアとやりとりすることによって自動的に設定されている。
【０００９】
デバイスドライバは、典型的な例として、従来のコンピュータシステムに見られるようなデバイスでは、コンピュータのオペレーティングシステムソフトウェアの一部として提供されている。例えば、オペレーティングシステムソフトウェアは、コンピュータキーボード、モニタ、ハードディスクドライブやフロッピディスクドライブ、および通信ポート用のデバイスドライバを具備しているのが代表的である。入出力拡張デバイスの構成は多種多様であるため、これらのデバイスはデバイス固有 (device-specific) のデバイスドライバをもち、これらのデバイスドライバはオペレーティングシステムソフトウェアの一部として提供されるのではなく、別個のファイルとして格納されているのが代表的である。このような個別デバイスドライバは、明示的にシステムメモリにインストールしてからでなければ関連デバイスを使用できないことから、インストール可能デバイスドライバ (installable device driver) と呼ばれているのが一般である。
【００１０】
例えば、MS-DOSオペレーティングシステムが稼動しているコンピュータでは、特定のインストール可能デバイスドライバのインストレーションコマンドは、”config.sys” という名前のブートファイルに追加できるようになっており、そのファイルはコンピュータのメモリに格納されている。コンピュータプロセッサが初期時にMS-DOSオペレーティングシステムの実行を開始するとき、プロセッサは、このconfig.sysファイルに含まれているコマンドを実行する。デバイスドライバのコマンドがそのファイルに含まれているときは、プロセッサはインストール可能デバイスドライバのインストレーションコマンドを実行し、インストール可能デバイスドライバをメモリにロードすることにより、デバイスへのアクセスを可能にしている。別の方法として、デバイスへのアクセスを必要とするアプリケーションプログラムが、その初期化フェーズ期間にドライバをロードすることも可能になっている。
【００１１】
拡張カードを物理的に挿入し、デバイスドライバをインストールし、デバイスパラメータを設定することのほかに、多くの場合、拡張カードにコンピュータリソースを割り振ることも必要である。ここで「コンピュータリソース」、あるいはより単純に「リソース」とは、コンピュータシステム内にあって、コンピュータシステムのメモリを占有するもの、あるいはコンピュータシステムが特定の機能を実行するために必要とされるもの、一切のことである。例えば、ドキュメントのページを印刷するには、文字フォントセット、絵文字 (glyph) セット、ポイントテーブル、ブラシテーブル (brush table)、ユーザ定義のグラフィックイメージおよび印刷しようとするページを記述するデータといった、ある種のリソースが、印刷機能を実行するために必要になる。従って、このようなリソースはプリンタリソースと呼ばれることがある。
【００１２】
拡張カードはコンピュータシステムに対する入出力(I/O)機能も備えている。入出力機能は、独立に入出力リソースが割り当てられる個別デバイスによって提供されている。入出力機能の例として、シリアルポート、SCSIポート、フロッピなどがある。入出力機能には入出力リソースが必要である。入出力リソースの例を挙げると、コンピュータメモリスペース、入出力レジスタ、割り込み信号ライン、割り込みレベル、割り込みソケット、ダイレクトメモリアクセス (DMA) チャネルなどがあるが、これらには限定されない。これらは入出力ハードウェアコンポーネントがコンピュータシステムと一緒に動作できるようにするものである。一般的に、以下の説明の中で入出力デバイスではなく、入出力機能という用語が用いられているのは、単一の物理デバイスまたはカードには、複数の入出力機能が実装されているからである。従って、機能は物理デバイスではなく、論理デバイスに対応している。
【００１３】
コンピュータリソースは、多くの場合、ハードウェアコンポーネントのパラメータが設定されるのと同じように入出力拡張ボードに割り振られている。例えば、リソースはマニュアルで割り振ったり、選択したりできる場合もあれば、自動構成ソフトウェア (automatic configuration software) がリソースを割り振る場合もある。
【００１４】
具体的に説明すると、多くのパーソナルコンピュータは、業界標準アーキテクチャ (ISA) バスアーキテクチャと呼ばれるシステムバスアーキテクチャを利用している。ISAバスアーキテクチャは、非常に多数のIBMおよびIBM互換パーソナルコンピュータに実装されている。ISAバスアーキテクチャを採用するコンピュータでは、メモリ、入出力アドレス空間、ダイレクトメモリアクセス (DMA) チャネル、割り込み要求ライン、および割り込みレベルなどのシステムリソースを、システム内の複数のISA拡張カード間で割り振ることが要求されている。
【００１５】
ISAアーキテクチャを採用するコンピュータシステムで使用できる拡張カードのタイプは、次の６つのカテゴリに分類することができる。すなわち、(1) マニュアル構成(manually-configured) ISAカード、(2) マニュアル構成マザーボードデバイス、(3) マニュアル構成ローカルバスカード、(4) 自動構成(auto-configuration) ISAカード、(5) ペリフェラルコンポーネント相互接続 (peripheral component interconnect - PCI) カード、(6) PCMCIAカードである。自動構成ISAカードは、カード識別、リソース使用状況(resource usage)判別、競合検出(conflict detection)および競合解決(conflict resolution)のためのメカニズムを備えている。この機能を使用すると、ユーザがマニュアルで介入しなくても、互換性のあるオぺレーティングシステムソフトウェアに自動構成ISAカードを自動的に識別させ、構成させることができる。
【００１６】
しかし、従来のISA標準には、ハードウェアまたはソフトウェアでシステムリソースを割り振るためのメカニズムが定義されていない。従って、ISA標準に準拠する拡張カードおよびマザーボードデバイスは、カード識別、リソース使用状況判別、競合検出または競合解決のためのオンボードメカニズムを備えていない場合がある。このことは、システムリソースを割り当てるときに問題となっている。
【００１７】
例えば、コンピュータを制御する特定のオペレーティングシステム（例えば、MS-DOS、WINDOWS、OS/2、WINDOWS 95など）によっては、特定のデバイスに割り込みラインを割り当てることが必要になる場合がある。多くの場合、各デバイスは固有の割り込みラインを必要としている。例えば、WINDOWSグラフィカルユーザインタフェースを使用して動作するコンピュータにインストールされたシリアル通信ボードは、固有の割り込みラインがそこに結合されている必要がある。つまり、同時に動作する他のどのデバイスにも、同じ割り込みラインを割り当てることはできない。
【００１８】
従来のシステムでは、ユーザはインストールされた各デバイスの構成を調べ、各デバイスが割り込みラインを使用している場合、どの割り込みラインを使用しているか、どの割り込みラインが未使用になっているかを判断しなければならない。そして、ユーザはシリアル通信ボードに結合する、未使用の割り込みラインを選択している。割り込みラインの選択は、ジャンパワイヤと呼ばれるもの（より単純にはジャンパ）を手作業で接続したり、拡張カード上にあるデュアルインラインピン (DIP) スイッチの特定端子をオープンまたはクローズしたりすることによって、あるいはデバイスドライバを介して、ISAカード上で行われている。従って、ユーザが従来のISAカードを構成するには、かなり大量の時間が消費されている。
【００１９】
上記のほかに、コンピュータシステムの構成ファイルは、追加デバイスがコンピュータシステムに追加されたことを、コンピュータシステムが認識できるように更新されている必要もある。問題が発生したときは、ユーザは、リソース割り振りに関与する拡張カードのメーカ提供のドキュメンテーションを調べて、リソース割り振りをマニュアルで解決しなければならないのが一般である。
【００２０】
しかし、２つまたは３つ以上のデバイスが、同じメモリデバイスの同一またはオーバラップするメモリ領域などの、同じコンピュータシステムリソースを使用することを同時に試みると、リソース競合 (resource conflict) と呼ばれる問題が発生する可能性がある。このようなリソース競合が起こると、その競合に関係するデバイスの１つまたは２つ以上が正常に動作しなくなるか、あるいはコンピュータシステムが正常に動作しなくなるか、あるいは動作することをまったく停止してしまうことさえある（つまり、システムは「ハングアップ」してしまう）。この問題は、リソースを手作業で割り振らなければならないときは特に深刻である。後者の場合には、ユーザは不慣れのため、リソースを正しく割り振ることができない場合がある。多くのコンピュータシステムは、マウス、通信ポートなどの入出力デバイスが事前に構成に含まれる形で提供されており、システムがユーザに渡されるときリソースは割り振り済みになっている。そのような場合、ユーザがリソースを割り振れるだけの、十分な知識を持っている場合でも、どのリソースが割り振り済みであるかを確かめることは困難である。
【００２１】
ユーザが未使用リソース(free resource)をマニュアルで選択するのを支援するために、いくつかの拡張カードは、どのリソースがすでに使用中であるかを判別することを試みるリソース検査プログラム付きで提供されている。これらのプログラムは、ユーザが拡張カードを物理的に挿入する前に実行され、どのリソースが使用中でないかを判別し、どのリソースがカードの要求条件を満足しているかを判断するようになっているのが一般である。この種のプログラムで起こっている１つの問題は、リソースを使用するカードがアクティブになっていないため、この検査プログラムの実行時にリソースがしばしば使用中になってないことである。従って、リソースは、それが使用中であっても、フリー（未使用）として示されることになる。そのあと、すべてのカードがアクティブになったとき、リソース競合が起こっている。
【００２２】
従来のコンピュータシステムでは、リソース競合が発生したとき、ユーザは、どのコンピュータシステムリソースが各デバイスによってアクセスされているか、どのデバイスが同じリソースにアクセスしようとしているかを判別することで、リソース競合の原因を確かめなければならない。ユーザがリソース競合の原因を確かめた後、ユーザは、次に、リソース競合を解決するプランを立案する必要がある。これは、コンピュータシステム内の各デバイスがどのコンピュータリソースを使用しているかを、しばしば試行錯誤によって判断してから、リソース競合に関係するデバイスに利用可能なコンピュータリソースを再割り当てしなければならないので、多くの場合、ユーザにとって時間のかかる作業になっている。
【００２３】
ISAカードのほかに、ISAアーキテクチャを採用するコンピュータシステムには、追加のバスアーキテクチャを取り扱う拡張スロットを備えた形で提供されているものがいくつかある。例えば、ある種の拡張スロットはローカルバススロットと呼ばれ、「ローカルバス」カードを受け入れている。ローカルバススロットは、ビデオアダプタカードや大容量ストレージカードなどの、拡張カードを受け付けているのが代表的である。このアーキテクチャに準拠するカードは、システムバスの介入なしでカード上のコンポーネント間で情報の転送を可能にする内部バス構造を備えている。この内部ローカルバスを使用すると、コンピュータシステムのパフォーマンスが向上する。一般的に、ISAアーキテクチャを採用するコンピュータシステムは種々のローカルバスアーキテクチャで動作可能であり、この中には、例えば、ビデオ・エレクトロニクス・スタンダード・アソシエイション（VESA）バスアーキテクチャなどが含まれている。しかし、ローカルバスアーキテクチャの多くは、そのスロットにプラグインされたカードを識別し、自動構成するメカニズムを含んでいない。つまり、ローカルバスアーキテクチャカードを採用する多くの拡張カードは自動構成拡張カードになっていない。
【００２４】
むしろ、この種のローカルバスカードは、従来のISA標準に準拠する拡張カードで行っていたように、ジャンパワイヤを接続し、DIPスイッチを設定することによってマニュアルで構成されているのが代表的である。従来のISAカードとマニュアル構成ローカルバスカードは同じ方法で構成されるので、この種のカードは、以下では、「マニュアル入出力拡張カード(manual I/O expansion card)」または「マニュアル構成入出力拡張カード(manually-configured I/O expansion card)」と総称することにする。
【００２５】
ペリフェラルコンポーネント相互接続 (PCI) アーキテクチャと呼ばれる、１つのローカルバスアーキテクチャは、PCI標準に準拠する拡張カードを受け付けている。PCI標準に準拠する拡張カードは、カード識別とリソース使用状況判別のためのメカニズムを含んでいることから自動構成可能になっている。
【００２６】
さらに、いくつかのコンピュータでは、マザーボードは、PCMCIA標準に準拠する拡張カードを受け付けるソケットを有するものが提供されている。PCMCIA標準に準拠する拡張カードは、システムに電源を入れたままでシステムに挿入可能になっている（つまり、コンピュータシステムの電源をオフにしなくても、PCMCIA拡張カードをコンピュータに結合することが可能になっている）。さらに、PCMCIA標準に準拠する拡張カードは、ジャンパワイヤとDIPスイッチによるのではなく、ソフトウェアで構成することが可能になっている。従って、自動構成可能ISA、PCIまたはPCMCIA標準に準拠する拡張カードだけを含むコンピュータシステムは、完全自動構成可能になっている。
【００２７】
しかし、いくつかのコンピュータシステムは、自動構成可能ISA、PCIまたはPCMCIA標準に準拠する拡張カードだけでなく、マニュアル構成ISAとローカルバス標準に準拠する拡張カードも含んでいる。従って、この種のコンピュータシステムでは、マニュアル構成入出力拡張カードを構成する際にユーザによる若干の介入が必要になっている。
【００２８】
マニュアル構成入出力拡張カードを受け付けるコンピュータシステムでは、その拡張カードに関する構成情報をオペレーティングシステムソフトウェアに対して指定するための、なんらかのメカニズムが必要である。ある種のマニュアル構成拡張カードは、デバイス固有のプローブ手法で識別可能になっている。すなわち、拡張カードの構成情報は、拡張カードのデバイス固有ハードウェアポートに読み書きすることで判断可能になっている。しかし、この種のプローブ手法は常に信頼性があるとは限らない。さらに、拡張カードには、プローブ手法と整合性がないものもある。従って、ISAバスアーキテクチャを採用するコンピュータシステムでデバイスを構成するための従来の手法は、メモリ内の構成ファイルを使用してリソース割り当て情報を指定しているか、リソース割り当て情報を対応するデバイスドライバの中にハードコーディングしているか、のどちらかである。
【００２９】
追加のバスアーキテクチャを取り入れている拡張ボードの場合には、その追加バスにプラグインされたデバイスの構成情報とリソース割り振り情報をストアし、および管理するために、リソースマネージャ(resource manager)と呼ばれるプログラムが使用されている。しかし、従来のシステムでは、拡張バスのタイプが異なるごとに別のリソースマネージャが使用されるという問題が起こっている。例えば、ペリフェラルコンポーネント相互接続 (PCI) バスとパーソナル・コンピュータ・メモリ・カード・インタフェース・アソシエイション（PCMCIA）バスの両方を装備しているコンピュータシステムでは、PCI拡張カードで使用されるリソースとPCMCIA拡張カードで使用されるリソースは、各拡張カード上に置かれた別々のリソースマネージャによって管理されることになる。これらの別々のリソースマネージャは情報を共有していないのが代表的であり、従って、どちらのリソースマネージャも、他方のリソースマネージャがどのリソースを使用しているかの情報をもっていないため、リソース競合を引き起こす原因になっている。
【００３０】
従って、すべての拡張カードが統一インタフェースを使用してモデル化できるようにするシステムが望まれている。この統一インタフェースを使用すると、統一化されたコンピュータビューア(computer viewer)がコンピュータハードウェアをグラフィックで描写するので、すべての拡張ボードを単一のリソースマネージャに管理させ、コンピュータシステムに追加することが可能になる。リソースマネージャは１つだけであるので、別々のリソースマネージャ間の競合は起こることがない。
【００３１】
さらに、既存の拡張ボードと将来の拡張ボードを完全な形で表現するとき最大限の柔軟性が保証されるように、拡張ボード上の入出力機能を別々にモデル化できるようにするシステムが望まれている。
【００３２】
さらに、既存の拡張ボードと将来の拡張ボードを完全な形で表現するとき最大限の柔軟性が保証されるように、異なるハードウェア構成を統一インタフェースを使用してモデル化できることが望まれている。
【発明の概要】
【００３３】
本発明によれば、各拡張ボードは、コンピュータビューアおよびリソースマネージャとのインタフェースを標準化することによって、単一のカードオブジェクトによって表現されている。各拡張ボードを表しているカードオブジェクトには、ボード上の入出力機能、各機能用の可能なリソース割り当ておよびリソース競合リゾルバオブジェクト (resource conflict resolver object) によって生成される割り当てを表している他のオブジェクトが組み込まれている。カードオブジェクトは、カードのバージョン番号、タイプ、バス番号、ベンダ情報およびスロットIDといった、カード自身に関する情報をストアすることも可能になっている。このようにして、各拡張カードに関する関係情報は単一のオブジェクトに保存されるので、ストレージからの取り出しが容易化されている。
【００３４】
具体的に説明すると、システムマザーボードおよびインストールされた拡張カードがあれば、そのカードが要求するリソースに関する情報はボードのインストール時に自動的に収集され、永続的ストレージ内の複数のオブジェクトにストアされる。このようなシステムリソース要求としては、メモリレンジ、入出力(I/O)レジスタレンジ、割り込み要求ラインおよびダイレクトメモリアクセス(DMA)チャネルがあるが、これらに限定されるものではない。各カードがコンピュータビューアを使用してインストールされるとき、そのカードを表すオブジェクトがコンピュータビューアによって作成される。このカードは、カード上に存在する入出力機能についても調べられ、各機能のために必要なリソースが取得される。自動構成可能カードの場合には、リソース要求はカードから直接に取得される。マニュアル構成可能カードの場合には、リソース要求は構成オプションデータベースから取得される。リソース要求と可能なリソース割り当ての各々は、オブジェクトにストアされる。リソース要求は、リソース競合リゾルバオブジェクトにも与えられ、カード上の各入出力機能にリソースを割り当てることが試みられる。リソース競合リゾルバが各入出力機能にリソースを割り当てることに成功すると、そのリソース割り当てもオブジェクトにストアされる。そのあと、リソースオブジェクトは永続的ストレージにストアされる。
【００３５】
次回にシステムブートオペレーションが行われるときは、ブーティングシステム(booting system)はバスとカードレコグナイザ(recognizer)オブジェクトを作成し、このオブジェクトは、どの拡張バスとカードがシステムに存在するかを確かめ、機能リソースオブジェクトを永続的ストレージから取り出し、各拡張カードを表現するようにしている。機能リソースオブジェクトには、リソース要求オブジェクト、可能なリソース割り当てオブジェクトおよび競合リゾルバリソース要求オブジェクトが組み込まれているため、シングルリソースマネージャは要求された時にリソースを操作し、完全無競合(conflict-free)リソース割り当てを生成できるようにしている。
【図面の簡単な説明】
【００３６】
【図１】本発明に従って動作するリソース競合リゾルバ付きリソースマネージャを備えたコンピュータシステムを示すブロック図である。
【図２】リソースマネージャのコンポーネントおよびそのコンポーネントと他のシステムコンポーネントとの関係を示す概略ブロック図である。
【図３】マニュアル構成カードの初期インストール期間に行われるリソースの割り当てと競合の解決に関与するリソースマネージャオブジェクト相互間のやりとりを示す概略ブロック図である。
【図４】「プラグアンドプレイ」カードの初期インストール期間に行われるリソースの割り当てと競合の解決に関与するリソースマネージャオブジェクト相互間のやりとりを示す概略ブロック図である。
【図５】システムブートアップ期間に行われるリソースの割り当てと競合の解決に関与するリソース競合リゾルバオブジェクト相互間のやりとりを示す概略ブロック図である。
【図６】システムブートアップ期間に行われるリソースの割り当てと競合の解決に関与するリソース競合リゾルバオブジェクト相互間のやりとりを示す概略ブロック図である。
【図７】拡張バスフレームワーク内にあって、コンピュータシステム内の拡張バスをモデル化するために使用できるクラス相互間の関係を示す一連のBooch図である。
【図８】拡張バスフレームワーク内にあって、コンピュータシステム内の拡張バスをモデル化するために使用できるクラス相互間の関係を示す一連のBooch図である。
【図９】拡張バスフレームワーク内にあって、コンピュータシステム内の拡張バスをモデル化するために使用できるクラス相互間の関係を示す一連のBooch図である。
【図１０】拡張バスフレームワーク内にあって、コンピュータシステム内の拡張バスをモデル化するために使用できるクラス相互間の関係を示す一連のBooch図である。
【図１１】拡張バスフレームワーク内にあって、コンピュータシステム内の拡張バスをモデル化するために使用できるクラス相互間の関係を示す一連のBooch図である。
【図１２】リソース競合解決プロセスの概要を示す流れ図である。
【図１３】可能なリソース割り当てのコレクションがカードオブジェクトから作られるときに使用されるメソッドを示す流れ図である。
【図１４Ａ】図１４Ｂと一緒に使用されて、競合が解決されるとき使用されるメソッドを示す流れを構成する図である。
【図１４Ｂ】図１４Ａと一緒に使用されて、競合が解決されるとき使用されるメソッドを示す流れを構成する図である。
【図１５】機能リソース割り当てクラスに関するクラス相互間の関係を示すBooch図である。
【図１６】可能な入出力リソース割り当てクラスに関するクラス相互間の関係を示すBooch図である。
【図１７】構成レコーダクラスに関するクラス相互間の関係を示すBooch図である。
【図１８Ａ】構成オプションリトリーバクラスに関するクラス相互間の関係を示すBooch図である。
【図１８Ｂ】構成オプションリトリーバクラスに関するクラス相互間の関係を示すBooch図である。
【図１９】マニュアル入出力カードクラスに関するクラス相互間の関係を示すBooch図である。
【図２０】カードレコグナイザクラスに関するクラス相互間の関係を示すBooch図である。
【図２１Ａ】構成レコーダクラスに関するクラス相互間の関係を示すBooch図である。
【図２１Ｂ】構成レコーダクラスに関するクラス相互間の関係を示すBooch図である。
【図２２】マニュアル、プラグアンドプレイおよびPCIカードクラスに関するクラス相互間の関係を示すBooch図である。
【図２３】機能リソースクラスに関するクラス相互間の関係を示すBooch図である。
【図２４】種々雑多のクラスに関するクラス相互間の関係を示すBooch図である。
【発明を実施するための形態】
【００３７】
次に、図１を参照して説明すると、コンピュータ１００は中央処理ユニット１０２を装備している。この中央処理ユニットは、システムバス１２２を介して相互接続された１つまたは２つ以上の従来のマイクロプロセッサにすることが可能である。コンピュータ１００としては、例えば、IBM（登録商標）コンピュータまたはIBM（登録商標）互換コンピュータが使用できるが、Apple（登録商標）Macintosh（登録商標）コンピュータまたはApple（登録商標）互換コンピュータにすることも可能である。従って、コンピュータ１００は、IBM OS/2（登録商標）オペレーティングシステム、Apple System/7（登録商標）オペレーティングシステム、DOSオペレーティングシステムまたはWINDOWS（登録商標）オペレーティングシステムなどの、コンピュータオペレーティングシステムがそのメモリ１１２に格納されているのが代表的である。
【００３８】
システムバス１２２には、複数のデバイスも結合されている。デバイスとしては、ランダムアクセスメモリ(RAM)１１２、リードオンリメモリ(ROM)１１４、ハードディスク１１６、キーボード１２６、マウス１２８、モニタ１４６などがある。コンピュータ１００内の各ハードウェアデバイスは、そのハードウェアデバイスとシステムバス１２２の間に結合されたコントローラをもっている。コントローラは実ペリフェラルデバイスに接続され、プロセッサに代わってそのデバイスを動作させている。従って、キーボード/マウスコントローラ１２４は、システムバス１２２と、キーボード１２６およびマウス１２８の間に結合されている。同様に、ハードディスクコントローラ１２０はシステムバス１２２とハードディスクドライバ１１６の間に結合され、ビデオコントローラ１４４はシステムバス１２２とモニタ１４６の間に結合されている。また、システムバス１２２には、メモリコントローラ１０４、バスコントローラ１０６、および割り込みコントローラ１０８も結合されている。DMAコントローラ１３０は、メモリ１１２への直接データ転送を制御するために使用できる。
【００３９】
プロセッサ１０２は、それぞれのコントローラをプログラミングすることによってデバイスを動作させている。例えば、ハードディスクドライブ１１６は、プロセッサ１０２によってプログラムされたハードディスクコントローラ１２０に接続されている。各コントローラ１２０、１２４および１４４は、それぞれのデバイスをプログラムするために使用される内部レジスタを含んでいる。コマンドオペレーション、ステータスオペレーション、およびデバイスとの間のデータ転送は、そのレジスタを通してコントローラをプログラミングすることにより開始される。
【００４０】
コントローラは、データ転送のためのデバイスバッファも装備している。例えば、ハードディスクコントローラ１２０は、ハードディスクオペレーションをプログラミングするためのレジスタとディスクバッファを装備している。読み取りオペレーションが行われるときは、プロセッサ１０２は、ハードディスクドライブ１１６から読み取りを実行するようにコントローラ１２０をプログラムしている。コントローラ１２０はそのオペレーションを開始し、データを読み取ってコントローラ１２０内のディスクバッファに置いておく。ディスクバッファに置かれたデータは、そのあと、デバイスドライバに対する読み取り要求の中で指定されたメモリロケーションにバス１２２を通って転送される。
【００４１】
コントローラ１２０、１２４および１３０の各々とシステムバス１２２は、物理的にマザーボード１１１上に置かれている。バス１２２に結合され、マザーボードに置かれているものとして、複数の拡張スロット１５０Ａ−１５０Ｎもある。種々の拡張カード１４０Ａ−１４０Ｎは拡張スロット１５０Ａに挿入することができる。例えば、ビデオコントローラ１４４は、拡張スロット１５０Ｂを通してシステムバス１２２に結合することができる。同様に、複数のバスアダプタ１４２Ａ−１４２Ｎも、該当カードをスロット１５０Ｃ−１５０Ｎに挿入することでシステムバス１２２に結合することができる。拡張バス１３８Ａ−１３８Ｎは、バスアダプタ１４２Ａと１４２Ｎの各々に挿入可能である。各拡張バスには、入出力デバイス１３２とCD-ROM１３４などの複数のデバイスおよび追加メモリ１３６を結合することも可能である。
【００４２】
本発明によれば、コンピュータ１００は、コンピュータ１００内で発生したシステムリソース競合を判別し、解決するリソースマネージャ１１０も含んでいる。なお、ここで注目すべきことは、コンピュータ１００は、各拡張カード１４０Ａ−１４０Ｎ、各拡張バス１３８Ａ−１３８Ｎ、およびコンピュータシステム１００に結合された拡張バス上のカード１３２、１３４および１３６などの、拡張カードを管理するシングルリソースマネージャ１１０を含んでいることである。従って、拡張バス１３８ＡがISA拡張バスに対応し、拡張バス１３８ＮがPCMCIA拡張バスに対応している場合でも、リソースマネージャ１１０は、拡張バス１３８Ａ、１３８Ｎの各々によって使用されるシステムリソースを管理している。コンピュータ１００はシングルリソースマネージャ１１０だけを含んでいるので、リソースマネージャ１１０はシステムリソースを追跡するだけでなく、コンピュータ１００に結合された拡張カードとバスのすべてに置かれている、システムリソースにアクセスしようとしているデバイスも追跡する。
【００４３】
好適実施形態では、本発明は「オブジェクト指向」コンピュータプログラミング技法を使用して実現することが可能である。オブジェクト指向コンピュータプログラミング技法では、「オブジェクト」と呼ばれるソフトウェアエンティティが定義され、作成され、使用され、破壊される。各オブジェクトは独立のソフトウェアエンティティであり、「属性(attribute)」と呼ばれるデータと、そのデータを操作する「メンバ関数(member functions)」または「メソッド(method)」とで構成されている。
【００４４】
オブジェクトの１つの特徴は、そのオブジェクトのメソッドだけが、オブジェクトに収められたデータを変更できることである。「カプセル化(encapsulation)」という用語は、データとメソッドを一緒にオブジェクトにパッケージ化するという考え方を表している。従って、オブジェクトは、オブジェクトの一部として含まれるデータとメソッドをカプセル化するとも、隠蔽するとも言われている。カプセル化は、他のオブジェクトによる恣意的で、不本意な使用からオブジェクトのデータを保護することにより、オブジェクトのデータが壊されるのを防止している。
【００４５】
オブジェクト指向コンピュータプログラムを書くためには、コンピュータプログラマは、「オブジェクトクラス」、より単純には「クラス」の集合を定義するコンピュータコードを頭の中で描き、書くことになる。これらのクラスの各々は、オブジェクトのメソッドを実行する属性とプログラム命令を収めておくデータ構造を定義するテンプレートの働きをする。各クラスは、クラステンプレートからオブジェクトを作成する手段も含んでいる。この作成手段は、「コンストラクタ(constructor)」と呼ばれるメソッドである。
【００４６】
コンピュータのプロセッサがオブジェクト指向コンピュータプログラムを実行するとき、プロセッサはコンストラクタメソッドを使用して、クラス情報からオブジェクトを生成する。プログラムの実行中に、１つのオブジェクトが構築され、次に、そのオブジェクトが他のオブジェクトを構築し、次に、そのオブジェクトが他のオブジェクトを構築する場合もある。従って、１つまたは２つ以上のクラスから構築されるオブジェクトのコレクションは、実行されるコンピュータプログラムを形成している。
【００４７】
継承 (inheritance) とは、ソフトウェア開発者がクラスのために既存のコンピュータコードを再利用できるようにする、オブジェクト指向プログラミング技法の特性の１つである。この継承の特性を使用すると、ソフトウェア開発者はコンピュータコードを始めから書かないで済むことになる。むしろ、継承によると、ソフトウェア開発者は、基底クラス (base class) から動作 (behavior−振る舞いとも言う) を継承する、サブクラス (subclass) と言われるものを派生することができる。そのあと、ソフトウェア開発者は、サブクラスのデータ属性とメソッドを特定の要求を満たすようにカスタマイズすることができる。
【００４８】
基底クラス／サブクラスの関係によれば、特定の名前をもつ第１のメソッドは、基底クラスに実装させることができ、同じ名前をもつ第２の異なるメソッドはサブクラスに異なる方法で実装させることができる。プログラムが実行中のとき、第１または第２のメソッドは、オブジェクトを表すパラメータをもつステートメントによってコールされることができる。どちらのメソッドがコールされるかは、オブジェクトがクラスから作成されたものであるか、サブクラスから作成されたものであるかによって決まる。この考え方は多態 (polymorphism) と呼ばれている。
【００４９】
例えば、あるコンピュータプログラムがEmployee（従業員）と名付けたクラスを含んでいるとする。さらに、クラスEmployeeは、ある社員が会社を退職したときに実行される一連のメソッドステップを定義しているメンバ関数 (member function) を含んでいるとする。オブジェクト指向の実装では、この退職 (retire) メソッドはクラスEmployeeのサブクラスによって自動的に継承される。従って、Executive（重役）と名付けたクラスがEmployeeと名付けたクラスのサブクラスであれば、クラスExecutiveはクラスEmployeeのメンバ関数である退職メソッドを自動的に継承する。
【００５０】
しかし、会社または組織は、重役である社員および重役でない社員を退職させる、異なるメソッドをもつことが可能である。その場合には、サブクラスExecutiveは、重役である社員を退職させるとき実行される独自の退職メソッドを含むことが可能である。そのような状況において、Executiveクラスに含まれる、重役社員を退職させるメソッドは、Employeeクラスに含まれる、社員一般を退職させるメソッドをオーバライド（override）する。この基底クラス/サブクラスの構成では、別のオブジェクトは退職メソッドを生起 (invoke) するメソッドを含むことが可能である。実際にどの退職メソッドが生起されるかは、後者のコールで使用されるオブジェクトのタイプによって決まる。Executiveオブジェクトタイプがそのコールの中で使用されていれば、オーバライドする退職メソッドが使用される。そうでなければ、基底クラスに含まれる退職メソッドが使用される。この例が多態的であるのは、コールで使用されるオブジェクトがEmployeeクラスから作成されたたものか、Executiveクラスから作成されたものかに応じて、退職オペレーションが異なる実装メソッドをもち、そのことはプログラムが実行されるまで判断されないからである。
【００５１】
オブジェクト内のデータ属性とメンバ関数がどのように実装されているかは隠されているので、メソッドコールは、どの特定メソッドが生起されるかを知らなくても行うことができる。従って、多態はカプセル化の考え方を拡張したものである。
【００５２】
オブジェクト指向コンピュータプログラミング技法を使用すると、コンピュータプログラムを、特定の動作をもつオブジェクトで構成することができる。いくつかの異なるオブジェクトを特定の方法で組み合わせて、特定の機能を実行し、あるいは特定の結果が得られるようなコンピュータプログラムを作ることができる。オブジェクトの各々は他のオブジェクトから作ることができ、他方、そのオブジェクトは他のオブジェクトから作ることができる。これは、複雑な機械がアセンブリ（部品）から作られ、そのアセンブリがサブアセンブリから作られているのと似ている。
【００５３】
例えば、回路設計者は、ビデオカセットレコーダ (video cassette recorder - VCR) の設計と製作をトランジスタごとには行っていない。むしろ、回路設計者は、増幅器、アクティブフィルタなどのように、各々が数百または数千のトランジスタを内蔵している回路コンポーネントを使用している。各回路コンポーネントは、特定のオペレーションを実行するオブジェクトになぞらえることができる。各回路コンポーネントは特定の構造上および機能上の特性をもち、特定の方法で他の回路コンポーネントと通信している。回路設計者は部品管理表(bill of materials)を使用し、そこには、異種タイプの回路コンポーネントの各々がリストされ、これらの回路コンポーネントを組み立てることによってVCRが得られるようになっている。同様に、コンピュータプログラムは、各々が特定の構造上および機能上の特性をもつ異種タイプのオブジェクトからアセンブルすることができる。
【００５４】
「クライアントオブジェクト」またはより単純に「クライアント」とは、「サーバクライアント」とも「サーバ」とも一般に呼ばれている、別のオブジェクトのリソースを使用するオブジェクトのことである。「フレームワーク」とは、特定タイプのアプリケーションプログラムに対してサービス群（例えば、証券や債権取引のためのサービス）を提供できる、相互に関連をもつクラスが集まったものと言うことができる。また、フレームワークは、広範囲にわたるアプリケーションプログラムに対してサービス群（例えば、Windowsシステムに対してグラフィカルユーザインタフェースを提供する基礎クラスライブラリ(foundation class libraries)）を提供する、相互に関連をもつクラスの集まりと言うこともできる。従って、フレームワークは、クライアントが使用し、あるいは適応できる複数の個別クラスとメカニズムを提供している。
【００５５】
アプリケーションフレームワークとは、ある特定アプリケーションプログラムと共にコンパイルされ、リンクされ、ロードされるのが代表的である、クラスの集まりのことであり、これらのクラスは、ある種の機能をその特定アプリケーションプログラムに実装するために、その特定アプリケーションプログラムで使用されている。他方、システムフレームワークは、コンピュータオペレーティングシステムプログラムの一部として提供されている。従って、システムフレームワークはある特定アプリケーションプログラムと共にコンパイルされ、リンクされ、ロードされることはない。むしろ、システムフレームワークは、コンピュータシステムによって実行されて、コンピュータオペレーティングシステムとやりとりする、すべてのアプリケーションプログラムが利用できるクラス群を提供している。
【００５６】
以下では、図２乃至図１７を参照して、リソースマネージャ１１０とそのコンポーネントについて詳しく説明する。要約して説明すると、リソースマネージャ１１０は、コンピュータシステム内の異なるバス上の入出力機能間のリソース使用状況を検出し、解決する。リソース競合の存在を検出すると、リソースマネージャ１１０は、拡張バスのタイプまたはバスにプラグインされたカードのタイプに関係なく、コンピュータシステム内の、すべての入出力機能の間で無競合システムリソース群の割り振りを計算する。リソースマネージャ１１０は、ISAシステム内の拡張カードとマザーボード用の構成レコーダを動的にインスタンス生成(instantiate)することにより、コンピュータの入出力システムのブートを支援する。プラグアンドプレイ(plug & play)カードだけをもつバスシステムは完全自動構成可能である。しかし、理解されるように、マニュアル入出力カードのようなマニュアル構成カードを、同じシステム内に自動構成可能カードと共存させることが可能である。このようなシステムでは、マニュアル構成カードを構成するとき若干のユーザ介入が必要になる。
【００５７】
図２は、リソースマネージャ１１０のコンポーネントを含むコンピュータ２００のコンポーネント、およびこれらのコンポーネントと他のシステムコンポーネントとの関係を示す概略ブロック図である。図２において、図１のエレメントに対応するエレメントには、対応する符号が付けられている。例えば、図１に示すシステムバス１２２は図２のシステムバス２２２に対応している。
【００５８】
無競合リソース割り当てを計算し、管理するために、リソースマネージャ１１０はリソース競合リゾルバ（解決）モジュール２２０を含んでいる。リソース競合リゾルバモジュール２２０に結合されたバス/カードレコグナイザ（認識）システム２７０は、システムに接続された拡張カード１４０Ａ−１４０Ｎとバス１３８Ａ−１３８Ｎを認識し、プラグアンドプレイカードのように、必要とするリソースをオンボードでストアしているバスとカードから情報を取り出す。カードによっては、必要とするリソースをオンボードで収容していないものがあるため、これらの拡張カード上の入出力機能に必要なリソースをストアするには、構成オプションデータベース２０６が使用されている。図示の例では、構成オプションデータベース２０６は永続的データベースになっており、ユーザがマニュアル構成入出力拡張カードをインストールするときにも、あるいはカードをインストールするときユーザによって実行されるセットアッププログラムによっても、エントリがそこに作成できるようになっている。セットアッププログラムは、カードメーカによって提供される構成情報をデータベース２０６にインストールする。バス/カードレコグナイザシステム２１６は、リソース要求をストアしていないバスとカードについては、構成オプションデータベース２０６から情報を取り出す。
【００５９】
マザーボード１１１の構成は、システムバス１２２上の、拡張スロット１５０Ａ−１５０Ｎの各々のハードウェアインタフェース識別子を作成するスロット識別メカニズム（図示せず）を含んでいるスロット構成レコグナイザ２１０によって判断される。バス/カードレコグナイザシステムはスロット識別子をキーとして使用して、拡張カード１４０Ａ−１４０Ｎ上の入出力機能に必要なリソースをリソース競合リゾルバモジュール２７４に登録する。
【００６０】
以下で詳しく説明するように、リソース競合リゾルバモジュール２２０は、レコグナイザシステム２１６からのバス/カード情報を使用して、無競合リソース割り当てのセットを生成する。リソース競合リゾルバモジュール２２０が、その割り当てを生成している途中で競合を見つけると、競合しているリソースのID、競合している期間、競合している入出力機能のIDなどの情報を生成し、この情報は、入出力リソース競合モジュール２２０からユーザに提供されたリソース競合モジュールオブジェクト２２１にカプセル化されている。
【００６１】
リソースが本発明によるシステムによって割り当てられると、種々の割り当てはカード構成レコーダシステム２１４によってハードウェア構成データベース２０４にストアされる。マザーボードの構成はマザーボード構成レコーダ２０８によってデータベース２０４に記録される。以下で詳しく説明するように、ハードウェア構成データベース２０４は、次回以降のブート期間にコンピュータブートシステム２０２によって使用され、どのレコグナイザを構築すべきかが判断され、以前にストアされたリソース割り当てが取り出される。
【００６２】
リソースマネージャ１１０が前述したオブジェクト指向プログラミング技法を使用して実装されていれば、バスレコグナイザシステム２１６とレコーダシステム２０８、２１４は、種々のバスとカードの動作を全般的に記述しているフレームワークの一部として実装させることができる。例えば、拡張バスフレームワークは、種々拡張カードの一般的動作を表しているクラス群を含むことが可能である。特定タイプの拡張バスでは、特定のサブクラス群は拡張バスフレームワークに用意されているクラスから派生している。拡張バスフレームワークは、拡張カードを認識し、拡張カード上の入出力機能に必要なリソースを登録し、種々拡張バス上にある拡張カードの各々の構成レコーダオブジェクトをインスタンス生成するための共通モデルを用意している。自動構成可能拡張カード、マニュアル構成可能カードおよびマザーボードにも、類似のフレームワークが用意されている。
【００６３】
リソース競合リゾルバモジュール２２０がオブジェクト指向コンピュータプログラムの一部として実装されていれば、競合リゾルバ２２０は、競合リゾルバフレームワークの一部であるクラスから作成されるオブジェクトにすることが可能であり、この競合リゾルバフレームワークは、拡張カード１４０Ａ−１４０Ｎによるリソース要求と制約(constraints)の種々表現（例えば、マイクロチャネルカードのアダプタ記述子ファイルやEISAカードの構成ファイル）をカプセル化している複数のクラスを含んでいる。これらのクラスは、コンピュータの拡張カードとマザーボード上の、複数の入出力機能の間で発生するリソース使用の競合を検出し、解決するバス独立モデルを提供している。入出力競合リゾルバフレームワークの重要な抽象化については、以下で簡単に説明した後、図７乃至図９を参照して詳しく説明する。
【００６４】
以下では、２種類の拡張ボードについて２つのフェーズに分けて説明する。第１フェーズは、新しい拡張ボードがコンピュータシステム２００にインストールされるときの、競合リゾルバシステムのオペレーションに関係するものである。ボードのインストールは、プラグアンドプレイボードとマニュアル構成ボードの両方について説明されている。
【００６５】
マニュアル構成入出力拡張ボードは、自動構成可能拡張カードとは異なり、ソフトウェアで構成することはできない。むしろ、マニュアル入出力拡張カードは、ジャンパワイヤをマニュアルで接続するか、カード上のDIPスイッチを設定することによって構成される。従って、マニュアル構成入出力拡張カードを含むコンピュータシステムでは、マニュアル構成入出力拡張カードのリソース要求の各々は、まず、構成可能カードが残りのリソースで構成できるような形で満たされなければならない。
【００６６】
マニュアル構成入出力拡張カードが利用可能な拡張スロットにインストールされるとき、競合リゾルバは現行リソース割り当てを記録にとっておき、新しいリソース割り当てを生成する。新しいマニュアル構成入出力カードは、コンピュータがリブートされるまではコンピュータオペレーティングシステムによって認識されないので、競合リゾルバは、現行ブートと次回ブートの両方のリソース割り当てを管理している。このようにすると、ユーザは、マニュアル構成入出力カードが必要とするリソースを登録してから、そのカードをシステムに物理的にインストールすることが可能になる。従って、ユーザは、カードが挿入され、無競合リソース割り当てが生成された後、ボードは次回ブート時に無競合でブートアップされることが保証されることになる。
拡張カードの初期インストール
次に、図３を参照して、コンピュータシステムへのマニュアルカード３３６の初期インストールについて説明する。以下の説明では、便宜上、コンピュータシステムがブートされ、稼動中であると想定されている。ブートを行うとき不可欠であるマニュアル入出力カードでは、ブートに先立ってエントリが永続的ハードウェア構成データベース３０４に作られていて、該当デバイスドライバが生起 (invoke) され、オペレーティングシステムが正常にロードされるようになっている必要がある。この種のカードは、マザーボード、ディスプレイカードのような出力デバイスコントローラ、キーボードや他の入力デバイスコントローラ、およびディスクドライブのようなブートデバイスコントローラを含んでいるのが一般である。これらのカードの初期データベースエントリは、ある種の低レベルインストレーションユーティリティで作成することが可能である。別の方法として、ブートを行うとき不可欠であるマニュアルカードは、パワーアップ時に自身が自動的に構成されるような構造にすることも可能である。これは、無競合リソース割り振りのセットが得られるように、カード上の該当ジャンパまたはスイッチをマニュアルで設定することによって行うことができる。カードの数は少ないので、この作業は容易に行うことができる。
【００６７】
カード３３６のように、ブートを行うとき不可欠でないマニュアル入出力カードでは、コンピュータシステム内のハードウェアコンポーネントをグラフィカルビューでユーザに表示するコンピュータビューアオブジェクト(computer viewer object) ３０２を使用すると、エントリをハードウェア構成データベース３０４に作ることができる。オブジェクト３０２は、例えば、米国特許第5,546,595号に記載されているような、ハードウェア構成システムによって生成することが可能である。なお、この記載内容は引用により本明細書の一部になっている。
【００６８】
コンピュータビューアオブジェクト３０２はコントロールパネルオブジェクト３１２をインスタンス生成することにより、ユーザがシステム構成を変更できるようにする。このコントロールパネルオブジェクト３１２の方は、それぞれ矢印３１７と３１８で示すように、構成オプションリトリーバオブジェクト(configuration option retriever object) ３３４とマニュアル入出力カードオブジェクト３３２をインスタンス生成する。オプションリトリーバオブジェクト３３４は、矢印３１６で示すようにデフォルトのリソース割り当てを構成オプションデータベース３１０から取り出し、そのデフォルトリソース割り当てをマニュアル入出力カードオブジェクト３３２に渡す（矢印３２４で図示）。
【００６９】
マニュアル入出力カードオブジェクト３３２は、カード上の入出力機能のために可能な割り当て、デフォルト割り当ておよび割り当ての制約といった、リソース要求を、矢印３３０で示すようにリゾルバオブジェクト３２０に登録する。そのあと、マニュアル入出力カードオブジェクト３３２は、カード上の各入出力機能用のリソース割り当てを、そのデフォルトジャンパ設定状態に応じて生成するようにリゾルバオブジェクト３２０に要求する（カードが初期インストールされるときは、そのジャンパ設定状態は一般にデフォルト設定状態にある）。
【００７０】
リゾルバオブジェクト３２０がカード上の入出力機能用の無競合リソース割り当てセットを、そのデフォルト割り当てを使用して作成することに成功すれば、インストールはユーザの介入なしで完了する。無競合リソースセットは、矢印３２８で示すようにマニュアル入出力カードオブジェクトに戻される。そのあと、マニュアル入出力カードオブジェクトは、カードに必要なリソースを矢印３２６で示すように、永続的ハードウェア構成データベース３０４にストアする。
【００７１】
カードのデフォルトジャンパ設定状態に対応するリソースが、現在、自動構成可能カード（Plug & Play ISAまたはPCIカードなど）に割り振られていて、そのリソースが次回のブートオペレーション期間に再割り当て可能である場合には、マニュアル入出力カードオブジェクト３３２はカードに必要なリソースを永続的データベース３０４にストアする。そのあと、ユーザはシステムをリブートするように指示される。リブート期間に、自動構成可能カードは再構成され、カードのデフォルトジャンパ設定状態に対応するリソースがマニュアル入出力カード３３６に割り当てられる。
【００７２】
上記とは別に、カード３３６のデフォルトジャンパ設定状態に対応するリソースが、現在、他のカードに割り振られていて、そのリソースが再割り当てできない場合には、カード３３６のジャンパ設定状態を変更するときユーザの介入が必要になる。リゾルバオブジェクト３２０は、競合しているリソース、インストールしようとしているカードが競合している入出力機能、およびカード３３６によって使用できる、可能な無競合割り当てといったような、競合に関する詳細情報を収めている競合オブジェクト３３８を作成する。ユーザは、競合オブジェクト３３８に入っている情報を使用して、カード３３６のジャンパ設定状態をマニュアルで変更する必要がある。ユーザが競合オブジェクト３３８に入っている情報に従ってジャンパ設定状態を変更することを選んだときは、マニュアル入出力カードオブジェクト３３２は、カード３３６の該当エントリを永続的ハードウェア構成データベース３０４に作成する。
【００７３】
マニュアル入出力カードオブジェクト３３２がエントリを永続的データベース３０４に作成すると、そのエントリはカード３３６上のコネクタ（デフォルトコネクタであるのが代表的）のハードウェアインタフェース識別子と関連付けられる。その後で行われるブート期間には、必要なリソースは、コネクタの識別子をキーとして使用して永続的データベースから取り出される。
【００７４】
インストール期間には、ネストされたレコグナイザ（SCSIバスなど）をブート期間に生起させる必要のあるマニュアルカードの構成レコーダオブジェクト３１４は、マニュアルレコーダレジストリ (manual recorder registry) と呼ばれる永続的データベースに登録される。このマニュアルレコーダレジストリは、ネストされたレコグナイザをブート期間に生起させる必要のあるマニュアルレコーダのコレクションを保存している。上述してきたステップを完了すると、コンピュータビューア３０２はカードモジュールをハードウェア構成データベース３０４に登録する。このブートのためにカードにリソースが割り当てられていて、カードのレコーダが認識のためのマニュアルレコーダレジストリに登録されていれば、カードが必要とするネストされたレコグナイザが開始される。
【００７５】
図４は、プラグアンドプレイカードのような自動構成可能カード４４０の、コンピュータシステムへの初期インストールを示している。この場合も、説明の便宜上、カード４４０の挿入時にコンピュータシステムがブートされ、動作状態にあるものと想定されている。
【００７６】
マニュアル入出力カードの場合と同様に、自動構成可能カード４４０は、コンピュータシステム内のハードウェアコンポーネントを、グラフィカルビューでユーザに表示するコンピュータビューアオブジェクト４０２を使用してインストールされる。コンピュータビューアオブジェクト４０２はコントロールパネルオブジェクト４１２をインスタンス生成することによって、ユーザがシステム構成を変更できるようにする。コントロールパネルオブジェクト４１２の方は、矢印４１８で示すようにプラグアンドプレイ入出力カードオブジェクト４３６をインスタンス生成する。プラグアンドプレイ入出力カードオブジェクト４３６は、矢印４３４で示すようにデフォルトリソース割り当てをカード４４０から直接に取り出す。
【００７７】
プラグアンドプレイ入出力カードオブジェクト４３６は、カード上の入出力機能のための可能な割り当て、デフォルト割り当ておよび割り当ての制約といった、リソース要求を、矢印４３０で示すようにリゾルバオブジェクト４２０に登録する。そのあと、プラグアンドプレイ入出力カードオブジェクト４３６は、カード上の各入出力機能のためのリソース割り当てを生成するようにリゾルバオブジェクト４２０に要求する。
【００７８】
リゾルバオブジェクト４２０がカード上の入出力機能のための無競合リソース割り当てセットを作成することに成功すると、インストールはユーザの介入なしで完了する。この無競合リソースセットは、矢印４２８で示すようにプラグアンドプレイ入出力カードオブジェクト４３６に戻される。そのあと、プラグアンドプレイ入出力カードオブジェクト４３６は、無競合リソース割り当てをもつカード４４０を矢印４３２に示すようにプログラムし、カードに必要なリソースを矢印４２６で示すように永続的ハードウェア構成データベース４０４にストアする。
【００７９】
プラグアンドプレイ入出力カードレコーダオブジェクト４１４も、矢印４０５と４０７で示すように、コンピュータビューア４０２の制御の下でオブジェクトデータベース４０６から復元 (resurrect) される。
ブート時のリソース割り当て
次に、図５を参照して、マニュアルカード５３６またはマザーボード（図５には図示されていない）を含んでいるコンピュータシステムのブートアップオペレーション期間に使用されるオペレーションとオブジェクトについて説明する。コンピュータのブート期間に、ブートシステム（図示せず）は該当カードレコグナイザセットをインスタンス生成する。このカードレコグナイザセットは、マザーボードデバイス、ISAスロット、VESAスロット、PCIスロットおよびPCMCIAソケットなどの、システムに存在するすべてのバス用のカードレコグナイザを収容している。各カードレコグナイザは、それが表しているバス上の拡張カードを判断すること、各カード上の機能のための可能なリソース割り当てをリソース競合リゾルバに登録すること、および各カード用の該当構成レコーダをインスタンス生成することを受け持っている。
【００８０】
具体的に説明すると、マニュアルカード入出力レコグナイザオブジェクト５４２はブートシステム（図示せず）によってインスタンス生成される。なお、このブートシステムは、米国特許第5,379,431号に記載されているブートシステムと同じものが使用できるが、その記載内容は引用により本明細書の一部になっている。以下で詳しく説明するように、レコグナイザオブジェクト５４２は、種々のカードから情報を取得するように設計されたレコグナイザフレームワークの一部になっている、より一般的なクラスからカード５３６用に手直しされているサブクラスからインスタンス生成される。このサブクラスは、例えば、カードメーカに生成させることも可能である。
【００８１】
システムのブートオペレーション期間に、カードレコグナイザオブジェクト５４２は、システムバスに結合されたマニュアル入出力カードの各々を判別する。ブートシステムは、特定のマザーボードを表している該当マザーボード構成レコグナイザ（図２中の２９４）もインスタンス生成する。マニュアルカードとマザーボードはリソース要求のためのオンボードストレージを有しないので、レコグナイザオブジェクト２９４と５４２は、マザーボードと各マニュアルカードが必要とするリソースをハードウェア構成データベース５０４から取り出す。ハードウェア構成データベース５０４内のリソース要求は、上述したコンピュータビューアをカードのインストール時に使用すると、ハードウェア構成管理システムに生成させることができる。別の方法として、リソース要求はユーザが直接に入力することも、カード自体から取得することも可能である。
【００８２】
マニュアル入出力カードレコグナイザ５４２は、矢印５３４で示すように、マニュアルカード５３６の現行リソース割り当てとレンジ（範囲）を受け取り、矢印５３０で図示するように、現行リソース割り当てとレンジをリソース競合リゾルバオブジェクト５２０に渡す。
【００８３】
リソース競合リゾルバオブジェクト５２０が、リソース競合が起こっていると判断すると、リゾルバオブジェクト５２０は、リソース競合が起こったことをユーザに通知し、可能な解決方法（つまり、無競合リソース割り当て）をユーザに指示する競合オブジェクト４７８をインスタンス生成する。逆に、リソース競合が存在しないとリソース競合リゾルバオブジェクト５２０が判断したときは、リゾルバオブジェクト５２０は、矢印５２８で示すように、マニュアルカード５３６用の無競合リソース割り当てをレコグナイザオブジェクト５４２に返す。
【００８４】
無競合リソース割り当ては、次に、レコグナイザオブジェクト５４２によってインスタンス生成されたマニュアル入出力レコーダオブジェクト５１４と、マザーボードレコグナイザによってインスタンス生成された、対応するマザーボードレコーダオブジェクトとにカプセル化される。図５に示すように、レコーダオブジェクトは、ユニークなIDから得られた識別子を使用してオブジェクトをデータベース５０６から復元するサービスによってインスタンス生成される。オブジェクトデータベース５０６は、リソース競合リゾルバオブジェクト５２０を含んでいるコンピュータシステムのメモリに永続的に置かれている。構成レコーダオブジェクトは、矢印５０５と５０７で示すように、ボードIDに基づく識別子とマザーボードのタイプを使用して該当オブジェクトを復元するサービスを使用してインスタンス生成される。マザーボードの場合には、レコーダは、マザーボードとマザーボードに置かれた機能のマニュアル入出力機能リソースオブジェクトのコレクションを表すマニュアル入出力カードを作成する。
【００８５】
そのあと、レコグナイザオブジェクト５４２はレコーダオブジェクト５１４内のメソッドを使用して、現行リソース割り当てをハードウェア構成データベース５０４に記録する。
【００８６】
次に、図６を参照して説明すると、プラグアンドプレイカード６４０を含んでいるコンピュータのブート期間に使用されるオペレーションとオブジェクトが図示されている。マニュアル入出力カードの場合と同様に、プラグアンドプレイ入出力カードレコグナイザオブジェクト６４２は、ブートシステム（図示せず）によってインスタンス生成される。以下で詳しく説明するように、レコグナイザオブジェクト６４２は、種々のカードから情報を得るように設計されたレコグナイザフレームワークの一部である、より一般的なクラスからカード６４０用に手直しされたサブクラスからインスタンス生成される。このサブクラスは、例えば、カードメーカに生成させることも可能である。
【００８７】
構成可能カードの場合は、各レコグナイザは、無競合リソース割り当てをもつカードを構成することも受け持っている。プラグアンドプレイカード用の、可能なリソース割り当てはカード自身から取り出される。具体的には、プラグアンドプレイ入出力カードレコグナイザオブジェクト６４２は、プラグアンドプレイカード６４０用の現行リソース割り当てとレンジをプラグアンドプレイカード６４０から取り出す。このような現行リソース割り当てとレンジは、矢印６３４で図示するように、カード６４０上にマウントされているメモリ（図示せず）から取り出すことが可能である。
【００８８】
現行リソース割り当てとレンジは、矢印６３０で示すようにレコグナイザオブジェクト６４２からリソース競合リゾルバオブジェクト６２０に渡される。他のレコグナイザオブジェクト（図示せず）も、ブートアップ時に存在する他のカード（図示せず）から取り出す。以下で詳しく説明するように、リソース競合リゾルバオブジェクト６２０は、送られてきたリソース割り当てとレンジを調べ、２つのアクションのどちらかを行う。すなわち、カード６４０のリソース割り当てとレンジ間で他のシステムリソースとの競合が存在するとリゾルバオブジェクト６２０が判断していれば、リゾルバオブジェクト６２０は競合が存在することと、その競合の性質を示す競合オブジェクト６５０をインスタンス生成する。この競合オブジェクト６５０は、競合しているリソースのID、競合している期間、競合している入出力機能のIDなどの情報を含めることが可能である。
【００８９】
しかし、リゾルバオブジェクト６２０がリソースの無競合割り当てを生成できるために、カード６４０に割り当てられたリソースとレンジが、システム内の他のカードの、他のリソース割り当ておよびレンジとの競合を引き起こさない場合には、リゾルバオブジェクト６２０は無競合リソース割り当てのセットを生成し、カード６４０用の無競合リソース割り当てを、矢印６２８で示すようにレコグナイザオブジェクト６４２に返す。そのあと、レコグナイザオブジェクト６４２は、リソース割り当て情報を、例えば、矢印６４４で示すように、カード６４０のメモリにストアさせることによってカード６４０を「プログラム」する。
【００９０】
プラグアンドプレイカードレコグナイザ６４２も、各プラグアンドプレイカードが特定されるたびに、該当のプラグアンドプレイカード構成レコーダオブジェクト６１４をインスタンス生成する。この構成レコーダオブジェクト６１４も、オブジェクトデータベース６０６にストアされたオブジェクトから該当オブジェクトを、ユニークなカードIDから求めた識別子を使用して復元するサービスを使用してインスタンス生成される。カードレコーダオブジェクト６１４は、カード６４０をハードウェア構成データベース６０４内に登録し、構成情報をデータベースに記録することも受け持っている。
【００９１】
以下で説明するように、レコグナイザオブジェクト６４２、競合リゾルバオブジェクト６２０、競合オブジェクト６５０およびレコーダオブジェクト６１４は、いずれも、図７乃至図１８を参照して以下で説明するクラスに類似したクラスから得ることが可能である。図７乃至図１８は、種々の異なるフレームワークを形成するクラスを示す一連の所謂Booch図である。クラスの各々とクラス間の関係については、以下で詳しく説明する。Booch図とそこで用いられている表記は、当業者ならば周知であるので、ここで記述しまたは説明することは省略する。Booch図と表記の意味については、Grady Booch著「アプリケーションによるオブジェクト指向分析と設計(Object-Oriented Analysis and Design with Applications)」という書名でBenjamin/Cummings Publishing Company, Inc.から出版されている解説書に解説されているが、その内容は引用により本明細書の一部になっている。
【００９２】
競合リゾルバフレームワーククラス
1.  拡張バスフレームワーク
図７乃至図９は、拡張バスフレームワークを形成するクラス群の構成と相互関係を示している。拡張バスフレームワークは、種々の異なる拡張バスの一般的動作を表しているクラス群から得られる。特定タイプの拡張バスについては、特定のサブクラス群が、拡張バスフレームワークに用意されているクラスから派生している。従って、拡張バスフレームワークは、拡張カードを認識し、拡張カード上の入出力機能を判別し、拡張カード上の入出力機能に必要なリソースを登録し、種々の拡張バス上の、拡張カードの各々の構成レコーダオブジェクトをインスタンス生成するための共通モデルを提供している。
【００９３】
次に、図７を参照して説明すると、拡張バスフレームワークは、図示のようにTIOCardRecognizerと名付けた基底クラス７００を含んでいる。TIOCardRecognizerクラス７００は、レコグナイザオブジェクトの一般的動作を表しているメンバ関数（オブジェクト７００の隣に表示のボックスに示されている）を含んでいる抽象基底クラス(abstract base class)である。メンバ関数は純粋仮想関数 (pure virtual function) として示されているが、このことは、この関数は派生サブクラスではオーバライドしなければならないことを意味する。従って、各々の特定タイプの拡張バスごとに、特定のレコグナイザサブクラスはTIOCardRecognizerクラス７００から派生し、特定拡張バスの対応するレコグナイザオブジェクトは派生レコグナイザクラスからインスタンス生成される。派生サブクラスでは、抽象基底クラスの純粋仮想関数はオーバライドされる。
【００９４】
TIOCardRecognizerクラス７００は、代表的なコンストラクタとデコンストラクタメンバ関数を含むほかに、複数の独自のメンバ関数も含んでいる。例えば、TIOCardRecognizerクラス７００は、SetSlotIdentifiersと名付けたメソッドを含んでおり、このメソッドは、特定のレコグナイザオブジェクトが受け持っている拡張バス上のスロットごとにTHardwareInterfaceIdentifierオブジェクトを作成するためにコールすることができる。このメソッドは次のような形式になっている。
【００９５】
void  SetSlotIdentifiers (THardwareModuleMaker& parentDevice, const
THardwareInterfaceIdentifier& parentInterface, const short baseSlotIndex, const short slotCount) = 0;
【００９６】
SetSlotIdentifiersメソッドは、バス上のハードウェアを記述しているTHardwareModuleMakerオブジェクトにTHardwareInterfaceIdentifierオブジェクトを追加する働きもする。SetSlotIdentifiersメソッドはマザーボードのインストール期間にマザーボード構成レコーダオブジェクトによってもコールされ、マザーボード上のスロットを判別する。
【００９７】
TIOCardRecognizerクラス７００は、RegisterPossibleAssignmentsと名付けたメソッドも含んでいる。このメソッドは、デフォルトの、または可能とされる、リソース要求をリソース競合リゾルバオブジェクトに登録するためにコールされる。このようなリソース要求としては、特定のバスに置かれた全拡張カード上の、複数の入出力機能のための可能なリソース割り当てとリソース割り当ての制約があるが、これらに限定されない。自動構成可能拡張カードの場合は、可能なリソース割り当ては拡張カードから取得され、リソース割り当ての制約は入出力機能制約レジストリから取得される。マニュアル構成可能カードの場合は、リソース要求（可能なリソース割り当てとリソース割り当ての制約の両方）は、上述したように永続的ハードウェア構成データベースから取得される。このメソッドは次のような形式になっている。
【００９８】
void RegisterPossibleAssignments (const THardwareModuleHandle& parent,
TIOResourceConflictResolverHandle& resolver) = 0;
【００９９】
TIOCardRecognizerクラス７００はInstantiateCardRecordersと名付けたメソッドも含んでいる。このメソッドはブートオペレーション期間にカードレコグナイザによってコールされ、コンピュータシステム内の各自動構成可能拡張カードに対する該当構成レコーダオブジェクトがインスタンス生成される。このメソッドは次のような形式になっている。
【０１００】
void InstantiateCardRecorders (const THardwareModuleHandle& parent, const
TIOResourceConflictResolverHandle& resolver, const THardwareInterfaceIdentifier& parentInterface, const TInterruptHandlerReference& parentHandler) = 0;
【０１０１】
自動構成可能バスの場合は、InstantiateCardRecordersメソッドは、バスに結合された各拡張カード上の入出力機能のために無競合リソース割り当てをリソース競合リゾルバオブジェクトから取り出し、拡張カードをその割り当てに応じてプログラムする。このメソッドは、バス上の認識された各カードのための、対応する構成レコーダオブジェクトも復元し、生起する。
【０１０２】
レコグナイザオブジェクトは、拡張カード上の各エッジ電気コネクタのための該当THardwareInterfaceIdentifierオブジェクトを作成し、そのエッジコネクタ識別子オブジェクトを構成レコーダオブジェクトに渡す。InstantiateCardRecordersメソッドは、ハードウェアカードモジュールを各構成レコーダオブジェクトからの取得、およびバス上のハードウェアを表すためにそのカードモジュールを前記コンピュータハードウェア構成データベースへの登録も行う。レコグナイザは該当スロット識別子をカードモジュールから取り出し、それを該当構成レコーダオブジェクトに渡して、構成レコーダオブジェクトがストアされたバスカードモジュールを適切に変更できるようにする。
【０１０３】
InstantiateCardRecordersメソッドは、「ソフトウェア障害(software-impaired)」カード（自動構成可能でないカード）を表しているTHardwareModuleMakerオブジェクトも作成し、そのソフトウェア障害カードをコンピュータハードウェア構成データベースに登録し、ソフトウェア障害カードのための、対応する構成レコーダオブジェクトがシステムで利用可能になるまで待つ新しいスレッドを生成する。マニュアル構成バスの場合は、InstantiateCardRecordersメソッドは使用されない。
【０１０４】
TIOCardRecognizer基底クラス７００から派生するサブクラスとして考えられるものには、ManualIOCardRecognizerクラス７０２、TPlugNPlayISACardRecognizerクラス７０４、TPCICardRecognizerクラス７０６、およびTEISACardRecognizerクラス７０８がある。これらのサブクラスの各々からは、対応するタイプの拡張バスのレコグナイザオブジェクトをインスタンス生成することができる。
【０１０５】
レコグナイザオブジェクトは、レコグナイザオブジェクトが、特定タイプの拡張バスについて、拡張バスが結合されている拡張スロットを特定できるようにするデータ属性とメンバ関数(SetSlotIdentifiers)をもつオブジェクトである。これらのメンバ関数は、拡張カードの可能なリソース割り当てを入出力競合リゾルバオブジェクト(RegisterPossibleAssignments)に登録する手段と、カードレコーダオブジェクト(InstantiateCardRecorders)をインスタンス生成する手段も備えている。
【０１０６】
TPlugNPlayISACardRecognizerクラス７０４は、抽象TIOCardRecognizer基底クラス７００から派生したサブクラスの一例である。上述したように、プPlug-and-Play ISA標準に準拠する拡張カードは自動構成可能である。自動構成可能バスのレコグナイザオブジェクトはバスに結合された各々の自動構成可能カードを認識するために、対応するバスを「探索(walk)」し、各自動構成可能カード上の入出力機能のためのリソース要求を取り出し、そのリソース要求をリソース競合リゾルバに登録する。バス上で自動構成可能カードを探し出すサーチ期間に実行される実際の関数は、バスハードウェアによって決まる。しかし、バスはあらかじめ決めた順序でサーチされ、バス上のすべての拡張カードが探し出され、検査されることが保証されている。
【０１０７】
自動構成可能バスのレコグナイザオブジェクトは、自動構成可能拡張カードのための該当構成レコーダオブジェクトもインスタンス生成し、その構成レコーダオブジェクトは、バスに結合されたリソース競合リゾルバによって計算された、それぞれの無競合リソース割り当てをストアする。レコグナイザオブジェクトは、拡張バススロットの各々を特徴付けているTHardwareInterfaceIdentifierオブジェクトを作成し、マザーボードのインストール期間にそれらをマザーボードに追加することも受け持っている。
【０１０８】
TManualI/OCardRecognizerクラス７０２は、TIOCardRecognizer基底クラス７００の可能とされるサブクラスの別の例である。TManualI/OCardRecognizerクラス７０２のインスタンスはManualI/OCardRecognizerオブジェクトであり、これはマニュアル構成入出力カードのレコグナイザオブジェクトである。マニュアル構成入出力拡張カードがバスに結合されるとき、ManualI/OCardRecognizerオブジェクトはマニュアル構成入出力拡張カードのエントリをハードウェア構成データベースに作成する。
【０１０９】
マニュアル構成可能バスのレコグナイザオブジェクトも、各拡張バスを「探索(walk)」し、バス上のマニュアル構成入出力拡張カード上の入出力機能が必要とするリソースを、永続的ハードウェア構成データベースから取り出し、そのリソース要求をリソース競合リゾルバオブジェクトに登録する。個別的拡張バスのレコグナイザは単態的(monomorphic)であるので、開発者によってサブクラス化されないのが通常である。
【０１１０】
次に、図８を参照して説明すると、拡張バスフレームワークは、TConfigurationOptionRetrieverと名付けたオブジェクトクラス８００も含んでいる。TConfigurationOptionRetrieverクラス８００は、リソース要求を前記永続的構成オプションデータベースから取り出すときのプロトコルを定義している抽象基底クラスである。このようなリソース要求としては、拡張カードとマザーボード上の、複数の入出力機能のために可能とされるリソース割り当てセットおよびリソース割り当ての制約があるが、これらに限定されるものではない。従って、コンピュータシステムに結合された各々の特定タイプの拡張バスごとに、特定のオプションリトリーバクラスがTConfigurationOptionRetrieverクラスから派生し、対応するリトリーバオブジェクトがその派生クラスからインスタンス生成されることになる。
【０１１１】
例えば、EISA拡張バスとマニュアル構成拡張バスの両方を含んでいるコンピュータシステムでは、TEISAConfigurationOptionRetrieverクラス８０４とTManualConfigurationOptionRetrieverクラス８０８はTConfigurationOptionRetrieverクラス８００から派生する。これらの２つの派生クラス８０４、８０８からは、対応するリトリーバオブジェクトをインスタンス生成して、それぞれのカードの各々にある各入出力機能に関する関数情報を、それぞれのEISAとマニュアル構成拡張カードのベンダ固有情報と共に取り出すことができる。
【０１１２】
TConfigurationOptionRetrieverクラス８００は、代表的なコンストラクタとデコンストラクタメンバ関数を含むほかに、純粋仮想関数であり、従って、派生クラスによってオーバライドされる複数の固有メンバ関数も含んでいる。例えば、TConfigurationOptionRetrieverクラス８００は、GetPossibleAssignments()と名付けられたメンバ関数を含んでいる。このメンバ関数は構成オプションデータベースについて調べ、拡張カード上の個別的入出力機能のための可能なリソース割り当てセットを返す。GetDefaultAssignment()と名付けられた、もう１つのメンバ関数は、ファクトリでの拡張カードの設定状態に対応する、個別的入出力機能のためのデフォルトリソース割り当てを返す。GetFunctionInformation()メソッドは、拡張カード上の個別的入出力機能の機能情報を返す。GetFunctionCount()メソッドは、拡張カード上の入出力機能の数を返す。クラス定義は次のようになっている。
【０１１３】
class TConfigurationOptionRetriever
{
public:
virtual         ~TConfigurationOptionRetriever ();          // デストラクタ
// ストリーミング演算子
//.................................................................................
virtual TStream&            operator >>=  (TStream& toWhere) const;
virtual TStream&            operator <<=  (TStream& fromWhere);
typedef unsigned int   FunctionCount;
virtual FunctionCount   GetFunctionCount() const = 0;
virtual void    GetFunctionInformation 
(const TIOFunctionHardwareInterfaceIdentifier::
FunctionNumber  functionNumber,
TIOFunctionInformation& function) const = 0;
virtual void    GetPossibleAssignments 
(const TIOFunctionHardwareInterfaceIdentifier::
FunctionNumber functionNumber, 
TCollectionOf <TPossibleIOResourceAssignment>
& possibles) const = 0;
virtual void    GetDefaultAssignment 
(const TIOFunctionHardwareInterfaceIdentifier::
FunctionNumber functionNumber,
TCollectionOf <TPossibleIOResourceAssignment>
& default) const = 0;
virtual void    GetVendorInformation (TText& vendor) const = 0;
virtual void    SetModuleSignature (const THardwareModuleHandle::
HardwareModuleSignature& card );
protected:
TConfigurationOptionRetriever (const THardwareModuleHandle::
HardwareModuleSignature& card);
TConfigurationOptionRetriever ();
TConfigurationOptionRetriever (
const TConfigurationOptionRetriever&
copy); 
TConfigurationOptionRetriever& operator = (const
TConfigurationOptionRetriever& right); 
private:
TStandardText  fModule;
};
【０１１４】
ConfigurationOptionRetrieverオブジェクトは、カードを表している対応するハードウェアモジュールオブジェクトに入っている、対応するカードのユニークなハードウェアIDであるSetModuleSignatureメソッドも含んでいる。同様に、GetVendorInfoメソッドは、ベンダ固有情報を拡張カードから取り出し、オブジェクトの中で参照されたベンダテキストオブジェクトにその情報を書き出す。
【０１１５】
TIOFunctionInformationクラス８０２は、TConfigurationOptionRetrieverクラス８００と関連付けられている。TIOFunctionInformationクラスは、関数番号、機能タイプなどの、カード上の入出力機能に関するバス固有情報をカプセル化している基底クラスである。特定タイプのカードについて、特定の機能情報クラスはTIOFunctionInformationクラス８０２から派生することができる。
【０１１６】
例えば、図９に示すように、複数の例示の機能情報クラス９０２−９０８は、TIOFunctionInformationクラス９００から派生していることが示されている。これらの派生クラスの各々は、１つの特定タイプのカードに置かれている入出力機能に関する情報を収めている。例えば、TPlugNPlayISAFunctionInformationクラス９０４が示されているが、これは、Plug and Play ISA標準に準拠する拡張カード上の、特定の入出力機能に関するバス固有情報を収めている。同様に、TPCIFunctionInformationとTEISAFunctionInformationクラス９０６、９０８の各々は、それぞれPCI標準とEISA標準に準拠する拡張カード上の、特定の入出力機能に関するバス固有情報を収めている。図示のように、TManualIOFunctionInformationクラス９０２も、TIOFunctionInformation基底クラス９００から派生している。TManualIOFunctionInformationクラス９０２はマニュアル構成可能ボード上の入出力機能情報をカプセル化している。
【０１１７】
次に、図８を参照して説明すると、TPossibleResourceAssignmentクラス８０６も、TConfigurationOptionRetrieverクラス８００と関連付けられている。TPossibleResourceAssignmentクラス８０６は、可能なリソース割り当てとデフォルト（ファクトリ割り当て）リソース割り当ての両方をカプセル化している。図８に示すように、TConfigurationOptionRetrieverの各々のインスタンスごとに、１つまたは２つ以上のTPossibleResourceAssignmentオブジェクトをインスタンス生成することが可能であり、その各々は可能なリソース割り当てセットを収めている。１つのデフォルトリソース割り当てセットは１つのインスタンスと関連付けられている。
【０１１８】
次に、図１０を参照して説明すると、拡張バスフレームワークは、TIOFunctionConstraintRegistryと名付けたクラス１０００も含んでいる。TIOFunctionConstraintRegistryクラス１０００は、Plug & Play ISAおよびPCI拡張カードなどの、自動構成可能拡張カード上の入出力機能のためのリソース割り当ての制約をカプセル化している。制約とは、リソース割り当ての制限のことである。TIOFunctionConstraintregistryオブジェクトは永続的データベース（図示せず）にストアされる。TIOFunctionConstraintRegistryクラス１０００は、代表的なコンストラクタとデストラクタメンバ関数を収めているほかに、機能制約レジストリデータベースに登録されている入出力機能の制約が変更されるのを待っているWaitForChange()メンバ関数も収めている。
【０１１９】
TIOFunctionConstraintクラス１００４はTIOFunctionConstraintRegistryクラス１０００と関連付けられている。TIOFunctionConstraintクラス１００４は、入出力機能のためのリソース割り当ての制約に関する情報をカプセル化している。カプセル化される情報は入出力機能によって決まる。
【０１２０】
TIOFunctionConstraintクラス１００４は、代表的なコンストラクタとデストラクタメンバ関数のほかに、制約情報をカプセル化する複数の属性も収めている。例えば、TIOFunctionConstraintクラス１００４は、カードエッジコネクタを特定しているレファレンスTHardwareInterfaceIdentifierオブジェクトを収容しているCardEdge属性を含んでいる。Function属性は、ボード上の、複数の機能の中の１つをユニークに識別しているFunctionNumberを収容している。最後に、Constraint属性は、実際の制約を指定しているTPossibleResourceAssignmentオブジェクトへのレファレンス（参照）を収容している。クラス定義は次のようになっている。
【０１２１】
class TIOFunctionConstraint
{
public:
TIOFunctionConstraint ();
TIOFunctionConstraint (const TIOFunctionConstraint& copy); 
TIOFunctionConstraint& operator= (const TIOFunctionConstraint& right); 
virtual  ~TIOFunctionConstraint ();          // デストラクタ
// ストリーミング演算子
//.................................................................................
virtual TStream&            operator >>=  (TStream& toWhere) const;
virtual TStream&            operator <<=  (TStream& fromWhere);
virtual THardwareInterfaceIdentifier*          CopyEdgeIdentifier () const;
virtual void    SetEdgeIdentifier (const THardwareInterfaceIdentifier&
edgeID);
virtual TIOFunctionHardwareInterfaceIdentifier::FunctionNumber
GetFunctionNumber () const;
virtual void    SetFunctionNumber 
(const TIOFunctionHardwareInterfaceIdentifier::
FunctionNumber functionNumber);
virtual void    GetAssignmentConstraint 
(TPossibleIOResourceAssignment& constraint) const;
virtual void    SetAssignmentConstraint (const 
TPossibleIOResourceAssignment& constraint);
enum EgarbageCollect        {kGarbageCollection, kNoGarbageCollection};
virtual EgarbageCollect        GetGarbageCollectionStatus () const;
virtual void                              SetGarbageCollectionStatus (const                                        EGarbageCollect status);
private:
THardwareInterfaceIdentifier*                fEdgeID;
TPossibleIOResourceAssignment            fConstraint;
TIOFunctionHardwareInterfaceIdentifier::FunctionNumber    fFunctionNumber;
EgarbageCollect              fGarbageCollect;            // PCMCIA=FALSEのとき
};
【０１２２】
拡張バスフレームワークは、TConfigurationRecorderLoaderテンプレートクラス１００２も含んでいる。すべての個別的バスフレームワークはこのクラスを使用し、個別的バスフレームワークはこのクラスのCreateConfigurationRecorder()メンバ関数を使用して、拡張カードの該当構成レコーダオブジェクトを復元(resurrect)する。クラス定義は次のようになっている。
【０１２３】
template <class AConfigurationRecorder>
class TConfigurationRecorderLocator 
{
public:
TConfigurationRecorderLocator(const TText& theRecorderID);
virtual  ~TConfigurationRecorderLocator();
virtual   AConfigurationRecorder* CreateConfigurationRecorder(Boolean
WaitForRecorder);
};
【０１２４】
2.  競合リゾルバフレームワーク
図１１乃至図１３は、競合リゾルバフレームワークを構成するクラス群を示している。この競合リゾルバフレームワークは、コンピュータの拡張カードとマザーボード上の、複数の入出力機能間で発生するリソース使用の競合を検出し、解決するバス独立モデルを提供するクラス群から構成されている。
【０１２５】
以下では、図１１乃至図１３を参照して、入出力競合リゾルバフレーム内の複数のクラスについて詳しく説明する。なお、概要を説明すると、競合リゾルバフレームワークは、TIOResourceConflictResolverと名付けられていて、マザーボードと拡張カード上の入出力機能への入出力リソース（入出力レジスタ、入出力メモリ、割り込み信号ライン、割り込みレベルおよびDMAチャネルなど）の割り当てを管理する抽象クラスを含んでいる。
【０１２６】
リソース競合リゾルバオブジェクトは、ハードウェア構成データベースにストアされていて、カードとそのカード上の機能に関するリソース情報をカプセル化している複数のカード使用状況クラスとやりとりする。このリソース情報には、可能なリソース割り当てセット、制約情報、およびリソース競合リゾルバオブジェクトによって行われた無競合リソース割り当てが含まれている。このようなリソース割り当て情報は、例えば、可能なリソース割り当て、リソース割り当ての制約、無競合リソース割り当ておよびリソース競合情報（競合が見つかったとき）に対応させることができる。TIOCardResourceUsageクラスはリソース使用状況およびカード上のすべての入出力機能に対してリソース競合リゾルバオブジェクトによって行われた無競合リソース割り当てをカプセル化している。リソース競合リゾルバオブジェクトは、個別的入出力機能のリソース使用状況情報をカプセル化している、TIOFunctionResourceUsageオブジェクトとも関連付けられている。
【０１２７】
一般的に、リソース競合リゾルバオブジェクトは４つのリソースを取り扱っている。すなわち、メモリ、入出力レジスタ、DMAチャネルおよび割り込みソケットである。TIOMemoryUsageModeクラスはメモリレンジの特性をカプセル化し、TinterruptUsageModeクラスは割り込みソケットの特性をカプセル化し、TDMAUsageModeクラスはDMAチャネルの特性をカプセル化している。
【０１２８】
本発明の一側面によれば、TIOFunctionResourceUsageクラスは、入出力機能に割り当てられていて、TIOFunctionResourceUsageオブジェクトにカプセル化されているシステムリソースへのアクセスを管理するTIOResourceLockEntryと関連付けられている。以下で説明するように、IOResourceLockEntryオブジェクトは、デバイスドライバのように、リソース割り当てへのアクセス権を取得した後、割り当てられたリソースへのアクセス権を取得することを望んでいるクライアントが獲得しなければならないセマフォ(semaphore)を収めている。
【０１２９】
TIOFunctionResourceUsageクラスはTIOResourceConflictクラスとも関連付けられている。TIOResourceConflictクラスは、特定の入出力機能のためのリソース割り当てで競合が見つかったときの、リソース競合に関する情報をカプセル化している。TIOResourceConflictクラスからインスタンス生成されるオブジェクトは、必要とするリソースが特定の入出力機能に割り当てることができなかった理由と、リソース競合に他の、どの入出力機能が関与しているかを説明した情報を含んでいる。
【０１３０】
可能なリソース割り当てセットとそのリソース割り当ての制約は、他の、複数のオブジェクトにカプセル化されている。TPossibleIOFunctionResourceAssignmentクラスは、個別的入出力機能のための、システムリソース割り当ての選択と制約を表している情報を収めている。TIOMemoryConstraintは、入出力機能が必要とするメモリレンジの制約を表している。TIORegisterContraintは、入出力機能が必要とする入出力レジスタレンジとそのレンジの制約を表している。TInterruptConstraintは、入出力機能が必要とする割り込みソケットとそのソケットの制約を表している。TDMAConstraintは、入出力機能が必要とするDMAチャネルとそのチャネルの制約を表している。
【０１３１】
TIOFunctionResourceUsageクラスは、さらに、リソース競合リゾルバオブジェクトによって生成され、リソース使用状況オブジェクトによって参照される無競合リソース割り当てをカプセル化している、複数のオブジェクトとも関連付けられている。例えば、TIOFunctionResourceUsageクラスは、個別的入出力機能のための無競合リソース割り当てを表すためにリソース競合リゾルバオブジェクトによって使用される。TIOMemoryAssignmentクラスは、入出力機能に割り当てられたメモリレンジを表している情報を収めている。TIORegisterAssignmentクラスは、入出力機能に割り当てられた入出力レジスタレンジを表している情報を収めている。TInterruptAssignmentクラスは、入出力機能に割り当てられた割り込みソケットを表している。TDMAAssignmentクラスは、入出力機能に割り当てられたDMAチャネルを表している。
【０１３２】
次に、図１１を参照して説明すると、競合リゾルバフレームワークはTIOResourceConflictResolverクラス１１００を含んでおり、このクラスは、コンストラクタとデストラクタメンバ関数を含んでいるほかに、複数の固有メンバ関数も含んでいる。コンストラクタは、遅延評価 (lazy evaluation) によって単一の参照カウントマスタオブジェクトを作成する（競合リゾルバを要求する最初のクライアントは、コンストラクタをコールすることによってこれを作成する）。デストラクタは、参照カウントがゼロになると、オブジェクトを破壊する。TIOResourceConflictResolverクラスは単態クラスであるので、開発者によってサブクラス化されないのが通常である。
【０１３３】
リソース競合リゾルバオブジェクトのクライアントはGetSystemResourceConflictResolver()メソッドを実行すると、システム競合リゾルバオブジェクトへのハンドルが戻されるので、そのオブジェクトとの通信が可能になる。このハンドルは、リゾルバオブジェクトの表現を簡潔化、単純化しているので、その表現はコピーとストリーム化が容易になっている。
【０１３４】
TIOResourceConflictResolverクラス１１００は、拡張カードまたはマザーボード上の、すべての入出力機能のための可能なリソース割り当てを登録するRegisterPossibleAssignments()メソッドも含んでいる。可能なリソース割り当ては、レコグナイザまたはカードオブジェクトによって生成されたリソース使用状況オブジェクトにカプセル化されている。登録は、リソース競合リゾルバオブジェクト内のカードリソース使用状況オブジェクトのデキュー(dequeue)にカードを追加することによって行われる。この関数のコードは次の通りである。
【０１３５】
void TIOResourceConflictResolver::RegisterPossibleAssignments
(const TIOCardResourceUsage & card)
{
TIOCardResourceUsage
*cardToRegister;
ThardwareInterfaceIdentifier                              *slot id;
TDequeOf<TIOFunctionResourceUsage>    newUsage;
slot id = card.CopySlotIdentifier();
// 既存カードの探索を試みる
if ((cardToRegister = FindCardByID(*slot id)) == NIL) {
cardToRegister = new TIOCardResourceUsage(card);
cardToRegister->SetSlotIdentifier(*slot id);
fCard.Add(cardToRegister); 
} 
else { 
card.GetFunctionResourceUsage(newUsage);
cardToRegister->SetFunctionResourceUsage(newUsage);
newUsage.DeleteAll();
}
}
【０１３６】
各入出力機能のための可能なリソース割り当ては、このメソッドへのコールの前に判断されていなければならない。マザーボードレコーダ、カードレコグナイザおよびカードビューアなどの、リソース競合リゾルバのクライアントは、マザーボードと拡張カード上の入出力機能のための可能なリソース割り当ておよびリソース割り当ての制約といったリソース要求を、このメソッドをコールすることによってリソース競合リゾルバオブジェクトに登録する。リソース要求は、カードのスロット識別子(Slot id)をキーとして使用して、カード単位(TIOCardResourceUsage)でリソース競合リゾルバオブジェクトに登録される。
【０１３７】
メソッドProduceConflictFreeAssignments()がコールされると、それに応答して、リソース競合リゾルバオブジェクトは、各拡張カード上の各入出力機能のための無競合リソース割り当て（TIOFunctionResourceAssignmentオブジェクトにカプセル化されている）を作成する。ある場合には、入出力リソース割り当てを、現在のブートオペレーション期間に行うことが好ましいことがある。他の場合には、入出力リソース割り当てを、次回のブートオペレーション期間に行うことが好ましいこともある。従って、ブート期間はクライアントによって指定され、そのブート期間は、入出力機能のためのリソース割り当てが現在のブートオペレーションで有効か、次回のブートオペレーションで有効かを示している。
【０１３８】
リソース競合リゾルバオブジェクトが、特定の入出力機能のためのリソース割り当てを作成している途中でリソース競合を見つけると、リソース競合リゾルバは、その特定入出力機能のためのTIOResourceConflictオブジェクトも作成し、無競合リソース割り当てを得るために別のリソース計算の試みを続ける。TIOResourceConflictオブジェクトは、どのシステムリソースが競合に関与しているか、競合が存続している期間、どの入出力機能が競合しているか、といった情報をカプセル化している。その後で無競合リソース割り当てが入出力機能のために生成されると、リソース競合リゾルバオブジェクトはリソース競合オブジェクトを削除し、そうでなければ例外がスロー(throw)される。
【０１３９】
リソース競合リゾルバオブジェクトは、コンピュータシステム内の、すべての入出力機能のための、リソース割り振り情報の集中化ソースの働きをする。カードレコグナイザのような、リソース競合リゾルバオブジェクトのクライアントは、入出力機能のTHardwareInterfaceIdentifierを、その情報がストアされているハードウェア構成データベースへのキーとして使用して、入出力機能のリソース割り振り情報にアクセスする。リソース競合リゾルバオブジェクトは、複数のクライアントによる、ストアされたリソース割り振り情報へのアクセスを、リソース競合リゾルバオブジェクトによって計算されたリソース割り当てと同期させるためのアクセス制御メカニズムも含んでいる。
【０１４０】
例えば、本発明の原理によれば、リソース競合リゾルバオブジェクトのデバイスドライバクライアントは、TIOResourceLockEntryクラス１１０６からインスタンス生成されたIOResourceLockEntryオブジェクトにカプセル化されているセマフォロックを取り出す。TIOResourceLockEntryクラス１１０６は以下で詳しく説明する。なお、ここでは、デバイスドライバクライアントは、TIOResourceLockEntryオブジェクトをインスタンス生成し、TIOResourceLockEntryオブジェクトのAcquire()メソッドを生起することでリソースのロックを獲得しなければならない、とだけ述べておく。ロックを獲得した後、デバイスドライバは、IOResourceLockEntryオブジェクトのGetResourceAssignment()メソッドをコールすることで、対応する入出力機能の実際のリソース割り当てにアクセスすることができる。
【０１４１】
リソース割り当ては、カードがコンピュータシステムに物理的に挿入される前に、上述したようにコンピュータビューアによってハードウェア構成データベースに入力できるので、リソース競合リゾルバオブジェクトは、カードが物理的にインストールされていなくても、カード上の入出力機能のための入出力機能リソース割り当てを生成し、返すことができる。そのために、該当デバイスドライバは、リソース割り当ての対象となっているデバイスがコンピュータシステムに存在するかどうかを確かめなければならない。
【０１４２】
TIOResourceConflictResolverクラスは、リソース割り当てが有効でなくなったとき（例えば、新しいカードが追加され、無競合リソース割り当てを行うことができないとき）、入出力機能単位だけでなく、拡張カード単位でもリソース割り当てを削除するためのメソッド(RemoveCardResourceUsage(); RemoveFunctionAssignment(); RemoveFunctionResourceUsage())を提供している。
【０１４３】
TIOResourceConflictResolverクラス１１００は、拡張カード上の入出力機能のためのリソース割り当ての制約を、競合リゾルバオブジェクトに登録するためのSetFunctionAssignmentConstraints()メソッドも含んでいる。SetFunctionAssignmentConstraints()メソッドは、リソース競合リゾルバオブジェクトのクライアントによって使用され、特定の入出力機能のリソース割り当てを強制的に特定値にする。リソース割り当ての制約は、カードの可能なリソース割り当てと競合していてはならない。制約の間に競合があると、このメソッドは例外をスローする。このメソッドは、カードまたは機能がリゾルバに登録されていないときも例外をスローする。
【０１４４】
RemoveFunctionAssignmentConstraints()メソッドは、前記のSetFunctionAssignmentConstraint()メソッドで設定された、入出力機能に関連するリソース割り当て制約を除去する。このメソッドは、カードまたは機能が競合リゾルバオブジェクトに登録されていないと例外をスローする。
【０１４５】
TIOResourceConflictResolverのGetCardResourceUsage()メソッドは、スロットIDで特定された拡張カード上の、すべての入出力機能のための無競合リソース割り当てを取得するためにコールされる。無競合リソース割り当ては、その前のProduceConflictFreeAssignment()メソッドのコールによって作成される。GetCardResourceUsage()メソッドは、拡張カードがリソース競合リゾルバオブジェクトに登録されていないと例外をスローする。このメソッドのコードは以下に示すとおりである。
【０１４６】
void TIOResourceConflictResolver::GetCardResourceUsage (
const THardwareInterfaceIdentifier & slot id,
TIOCardResourceUsage & cardAssignments) 
{
TIOCardResourceUsage                    *card;
if ((card = FindCardByID(slot id)) == NIL){
throw (TconflictResolverException
(TConflictResolverException::kCardNotRegistered));
return;
}
cardAssignments = *card;      // Copy stuff over
}
TIOCardResourceUsage * TIOResourceConflictResolver::FindCardByID
(const THardwareInterfaceIdentifier & slot id) const
{
TIOCardResourceUsage                                    *card;
ThardwareInterfaceIdentifier                              *checkid;
TIteratorOver<TIOCardResourceUsage>                    *iterator;
iterator = fCard.CreateIterator();
card = iterator->First();
while (card != NIL) {
checkid = card->CopySlotIdentifier();
if (*checkid == slot id) {
delete checkid;
delete iterator;
return card;
}
card = iterator->Next();
delete checkid;
}
delete iterator;
return NIL;
}
【０１４７】
TIOResourceConflictResolverクラス１１００のRemoveCardResourceUsageメソッドは、特定の拡張カードのための、すべてのリソース割り当て(TIOCardResourceUsage)を除去するためにコールされる。このメソッドは、拡張カードがコンピュータシステムから除去されるときコールされるのが代表的であり、カードが除去されるとき拡張カードがリソースを使用中であれば、例外を引き起こす。このメソッドのコードは次のようになっている。
【０１４８】
void TIOResourceConflictResolver::RemoveCardResourceUsage(const
THardwareInterfaceIdentifier & slot id)
{
TIOCardResourceUsage
*cardToRemove;
TDequeOf<TIOFunctionResourceUsage>                    funcDeque;
TSequenceOfIterator<TIOFunctionResourceUsage>          *funcIterator;
TIOFunctionResourceUsage                                *funcUsage;
if ((cardToRemove = FindCardByID(slot id)) == NIL) {
throw (TconflictResolverException
(TConflictResolverException::kCardNotRegistered));
return;
}
fCard.Remove(*cardToRemove);            // カードを除去する
}
【０１４９】
GetFunctionAssignment()メソッドはレコグナイザとコンピュータビューアのコントロールパネルによってのみコールされ、特定拡張カード上の特定入出力機能のための無競合リソース割り当てを返す。このメソッドのコードは次に示すとおりである。
【０１５０】
void TIOResourceConflictResolver::GetFunctionAssignment(
const TIOFunctionHardwareInterfaceIdentifier& functionID,
TIOFunctionResourceAssignment& function) const
{
TIOFunctionResourceUsage    *functionItem;
if ((functionItem = FindFunctionByID (functionID)) == NIL) {
throw (TconflictResolverException
(TConflictResolverException::kFunctionNotRegistered));
return;
}
if (functionItem->GetAssignment(function) ==
TIOFunctionResourceUsage::kNotAssigned) {
TDequeOf <TIOResourceConflict> conflicts;
functionItem->GetResourceConflicts(conflicts);
if (conflicts.Count())
throw (TconflictResolverException
(TConflictResolverException::kConflictInResources));
else
throw (TConflictResolverException
(TConflictResolverException::kNoAssignmentCreated));
return;
}
}
TIOFunctionResourceUsage *
TIOResourceConflictResolver::FindFunctionByID(const
TIOFunctionHardwareInterfaceIdentifier & functionID) const
{
TSequenceOfIterator<TIOCardResourceUsage>            *cardIterator;
TIOCardResourceUsage                                  *card;
TDequeOf<TIOFunctionResourceUsage>                    functionDeque;
TSequenceOfIterator<TIOFunctionResourceUsage>          *functionIterator;
TIOFunctionResourceUsage                              *functionUsage;
ThardwareInterfaceIdentifier                              *slot id, *checkID,
*edgeID;
TIOFunctionHardwareInterfaceIdentifier::FunctionNumber
functionNumber;
functionNumber = functionID.GetIOFunction();
// HW Config DBをナビゲートすることによって機能IDから
// スロットIDを見つける
if ((edgeID =  functionID.CopyParent()) == NIL)
return          NIL;
THardwareConfigurationHandle myDB;
myDB = THardwareConfigurationHandle::GetComputerDatabase();
THardwareInterfaceHandle edgeHandle = myDB.GetInterface(*edgeID);
TDequeOf <THardwareConnectionHandle> myConnections;
edgeHandle.GetAllConnections(myConnections);
THardwareConnectionHandle* edgeConnection = myConnections.First();
THardwareInterfaceHandle slotHandle = edgeConnection->GetOtherEnd
(edgeHandle);
slot id = slotHandle.CopyHardwareInterfaceIdentifier();
myConnections.DeleteAll();
if (slot id == NIL)
return        NIL;
cardIterator = fCard.CreateSequenceIterator();
card = cardIterator->First();
while (card != NIL) {
checkID = card->CopySlotIdentifier();
if (*checkID != *slot id) {
delete checkID;
card = cardIterator->Next();
continue;
}
delete checkID;
card->GetFunctionResourceUsage(functionDeque);
functionIterator = functionDeque.CreateSequenceIterator();
functionUsage = functionIterator->First();
while (functionUsage != NIL) {
if (functionNumber ==
functionUsage->GetFunctionNumber()) {
delete cardIterator;
delete functionIterator;
delete slot id;
TIOFunctionResourceUsage    *saveUsage;
saveUsage = new            TIOFunctionResourceUsage
(*functionUsage);
functionDeque.DeleteAll();
return saveUsage;
}
functionUsage = functionIterator->Next();
}
delete functionIterator;
card = cardIterator->Next();
}
delete slot id;
delete cardIterator;
functionDeque.DeleteAll();
return        NIL;
}
【０１５１】
各々の特定入出力機能はユニークな識別子(THardwareInterfaceIdentifier)をもち、これはキーとしてGetFunctionAssignment()メソッドに渡され、FindFunctionByID()メソッドによって突き止められた特定入出力機能のためのリソース割り当てがハードウェア構成データベースから取得される。各々の特定拡張カードおよび対応する構成レコーダオブジェクトのための構成レコーダは、TIOFunctionHardwareInterfaceIdentifierクラスからサブクラス化することによって、拡張カード上の各入出力機能のユニークな識別子を作成する。
【０１５２】
ここで注意すべきことは、GetFunctionAssignment()メソッドは、拡張カードがシステムに物理的にインストールされていなくても、そのカードがハードウェア構成データベースに登録されている限り、拡張カードのためのリソース割り当てを返すことである。GetFunctionAssignment()メソッドは、リソース割り当てが作成されていない場合や、特定の入出力機能のためのリソース割り当てを作成するとき競合が発生した場合、あるいは入出力機能が競合リゾルバに登録されていない場合に例外をスローする。
【０１５３】
TIOResourceConflictResolverクラス１１００はGetResourceConflicts()メソッドを含んでおり、このメソッドはカードレコグナイザとコントロールパネルによってのみコールされ、入出力機能のリソース割り当ての競合を返す。特定の入出力機能のリソース競合を取得するには、入出力機能のユニークなTHardwareInterfaceIdentifierがキーとして、この関数に渡される。競合はハードウェア構成データベース内のリソース使用状況オブジェクトから取り出される。GetResourceConflicts()メソッドは、入出力機能がリソース競合リゾルバに登録されていないと例外をスローする。このメソッドのコードは次に示すようになっている。
【０１５４】
void TIOResourceConflictResolver::GetResourceConflicts (const
TIOFunctionHardwareInterfaceIdentifier& functionID,
TCollectionOf <TIOResourceConflict>& conflicts) const
{
TIOFunctionResourceUsage    *functionItem;
TIOFunctionResourceAssignment function;
if ((functionItem = FindFunctionByID (functionID)) == NIL) {
throw (TconflictResolverException
(TConflictResolverException::kFunctionNotRegistered));
return;
}
if (functionItem->GetAssignment(function) ==
TIOFunctionResourceUsage::kNotAssigned) {
functionItem->GetResourceConflicts(conflicts);
}
}
【０１５５】
入出力機能がシステムから削除されるとき、TIOResourceConflictResolverクラス１１００のRemoveFunctionAssignment()メソッドとRemoveFunctionResourceUsage()メソッドがコールされ、入出力機能に割り当てられたリソース割り当て(TIOFunctionResourceAssignment)と入出力機能に関連するリソース使用状況(TIOFunctionResourceUsage)が除去される。RemoveFunctionAssignment()メソッドの場合は、このメソッドのコール側は、リソースに対する応答が対応するハードウェアによってなされていないことを表明(assert)する。このメソッドは、リソースが使用中であれば例外を引き起こし、入出力機能がリソース競合リゾルバに登録されていないときも例外を引き起こす。この関数のコードは次のようになっている。
【０１５６】
void TIOResourceConflictResolver::RemoveFunctionAssignment (const
TIOFunctionHardwareInterfaceIdentifier & functionID) const
{
TSequenceOfIterator<TIOCardResourceUsage>              *cardIterator;
TIOCardResourceUsage                                          *card;
TDequeOf<TIOFunctionResourceUsage>                    functionDeque;
TSequenceOfIterator<TIOFunctionResourceUsage>          *functionIterator;
TIOFunctionResourceUsage                                *functionUsage;
ThardwareInterfaceIdentifier                                      *checkID,
*cardIdentifier;
TIOFunctionHardwareInterfaceIdentifier::FunctionNumber
functionNumber;
if ((cardIdentifier = functionID.CopyParent()) == NIL) {
throw (TconflictResolverException
(TConflictResolverException::kFunctionNotRegistered));
}
cardIterator = fCard.CreateSequenceIterator();
card = cardIterator->First();
functionNumber = functionID.GetIOFunction();
while (card != NIL) {
checkID = card->CopySlotIdentifier();
if (*checkID != *cardIdentifier) {
delete checkID;
card = cardIterator->Next();
continue;
}
delete checkID;
card->GetFunctionResourceUsage(functionDeque);
functionIterator = functionDeque.CreateSequenceIterator();
functionUsage = functionIterator->First();
while (functionUsage != NIL) {
if (functionNumber ==
functionUsage->GetFunctionNumber()) {
functionUsage->ClearAssignment();
card->SetFunctionResourceUsage (functionDeque);
delete cardIterator;
delete functionIterator;
delete cardIdentifier;
functionDeque.DeleteAll();
return;
}
functionUsage = functionIterator->Next();
}
delete functionIterator;
functionDeque.DeleteAll();
card = cardIterator->Next();
}
delete cardIdentifier;
delete cardIterator;
throw (TConflictResolverException
(TConflictResolverException::kFunctionNotRegistered));
}
【０１５７】
RemoveFunctionResourceUsage()メソッドの場合は、このメソッドのコール側は、リソースに対する応答が対応するハードウェアによってなされていないことを表明する。このメソッドは、リソースが使用中であれば例外を引き起こし、入出力機能がリソース競合リゾルバに登録されていないときも例外を引き起こす。この関数のコードは次のようになっている。
【０１５８】
void TIOResourceConflictResolver::RemoveFunctionResourceUsage(const 
TIOFunctionHardwareInterfaceIdentifier & functionID) const
{
TSequenceOfIterator<TIOCardResourceUsage>                *cardIterator;
TIOCardResourceUsage                                            *card;
TDequeOf<TIOFunctionResourceUsage>                    functionDeque;
TSequenceOfIterator<TIOFunctionResourceUsage>          *functionIterator;
TIOFunctionResourceUsage                                *functionUsage;
TIOFunctionHardwareInterfaceIdentifier                    *functionIdentifier;
cardIterator = fCard.CreateSequenceIterator();
card = cardIterator->First();
while (card != NIL) {
card->GetFunctionResourceUsage(functionDeque);
functionIterator = functionDeque.CreateSequenceIterator();
functionUsage = functionIterator->First();
while (functionUsage != NIL) {
functionIdentifier = functionUsage->CopyFunctionIdentifier();
if (*functionIdentifier == functionID) {
functionIterator->Remove();
card->SetFunctionResourceUsage(functionDeque);
functionDeque.DeleteAll();
delete cardIterator;
delete functionIterator;
return;
}
delete functionIdentifier;
functionUsage = functionIterator->Next();
}
delete functionIterator;
card = cardIterator->Next();
}
delete cardIterator;
functionDeque.DeleteAll();
throw (TConflictResolverException 
(TConflictResolverException::kFunctionNotRegistered));
}
【０１５９】
TIOResourceConflictResolverクラス１１００は、TIOCardResourceUsageと名付けたクラス１１０２およびTIOFunctionResourceUsageと名付けたクラス１１０４と関連付けられている。TIOCardResourceUsageクラス１１０２の目的は、カード上の複数の入出力機能に関するリソース使用状況情報をカプセル化することである。リソース競合リゾルバオブジェクトのクライアントは、拡張カードのリソース使用状況情報を、その拡張カードがインストールされている拡張スロットのTHardwareInterfaceIdentifierを使用してハードウェア構成データベースから取り出す。TIOCardResourceUsageクラス１１０２は単態クラスであるので、開発者によってサブクラス化されないのが通常である。
【０１６０】
TIOCardResourceUsageクラス１１０２は、代表的なコンストラクタとデストラクタメンバ関数を含んでいるほかに、複数の固有メンバ関数も含んでいる。例えば、GetFunctionResourceUsageメンバ関数は特定拡張カード上の、複数の入出力機能のリソース使用状況を返す。この関数は次のような形式になっている。
【０１６１】
void GetFunctionResourceUsage (TCollectionOf
<TIOFunctionResourceUsage>& function) const;
【０１６２】
TIOCardResourceUsageクラス１１０２は、SetFunctionResourceUsage()メンバ関数も含んでいる。このメンバ関数によって実装されているメソッドは、拡張カード上の、複数の入出力機能のリソース使用状況を書き出し、次のような形式になっている。
【０１６３】
void SetFunctionResourceUsage (const TcollectionOf
<TIOFunctionResourceUsage>&            function);
【０１６４】
TIOCardResourceUsageクラスは、THardwareInterfaceIdentifier* CopySlotIdentifier()メソッドおよびSetSlotIdentifier()メソッドも含んでいる。THardwareInterfaceIdentifier* CopySlotIdentifier()メソッドは、拡張カードがインストールされている拡張スロットのTHardwareInterfaceIdentifierを返し、SetSlotIdentifier()メソッドは、拡張カードがインストールされている拡張スロットのTHardwareInterfaceIdentifierを書き出す。これらの関数は次のような形式になっている。
【０１６５】
THardwareInterfaceIdentifier* CopySlotIdentifier() const; および
void SetSlotIdentifier (const THardwareInterfaceIdentifier& slot id);
【０１６６】
TIOFunctionResourceUsageクラス１１０４の目的は、可能なリソース割り当てとリソース割り当ての制約、および個別的入出力機能の無競合リソース割り当てをカプセル化することである。TIOFunctionResourceUsageクラス１１０４は、リソース割り当てが有効になっている割り当て期間、および無競合リソース割り当てを生成している途中でリソース競合が見つかったときの、リソース競合に関する情報もカプセル化する。レコグナイザのような、リソース管理システムのクライアントは、入出力機能のTIOFunctionResourceUsageオブジェクトを、その入出力機能に関連付けられた機能番号を使用してハードウェア構成データベースから取り出す。TIOFunctionResourceUsageクラス１１０４は単態クラスであるため、開発者によってサブクラス化されないのが通常である。
【０１６７】
TIOFunctionResourceUsageクラス１１０４は代表的なコンストラクタとデストラクタメンバ関数を含んでいるほかに、複数の固有メンバ関数も含んでいる。例えば、TIOFunctionResourceUsageクラスはSetPossibleAssignment()メソッドとGetPossibleAssignment()メソッドを含み、これらのメソッドは、それぞれが特定入出力機能の可能なリソース割り当てを書き出し、返す。これらのメソッドは次のような形式になっている。
【０１６８】
void GetPossibleAssignments (TcollectionOf
<TPossibleIOResourceAssignment>&possibles) const; および
void SetPossibleAssignments (const TCollectionOf
<TPossibleIOResourceAssignment>& possibles);
【０１６９】
TIOFunctionResourceUsageクラスはGetAssignmentConstraints()メソッドとSetAssignmentConstraints()メソッドをさらに含んでおり、これらのメソッドは、それぞれが特定入出力機能のリソース割り当ての制約を書き出し、返している。これらの関数は次のような形式になっている。
【０１７０】
void GetAssignmentConstraints (TcollectionOf
<TPossibleIOResourceAssignment>& constraints) const; および
void SetAssignmentConstraints (const TCollectionOf
<TPossibleIOResourceAssignment>& constraints);
【０１７１】
TIOFunctionResourceUsageクラス１１０４のGetAssignment()メソッドは、クラス１１０４のSetAssignment()メソッドが特定入出力機能の無競合リソース割り当てを、対応するIOFunctionResourceUsageオブジェクトに書いている間に、入出力機能の無競合リソース割り当てを返す。なお、ここで注意すべきことは、デバイスドライバはGetAssignment()メソッドを使用して、特定入出力機能のリソース割り当てを取得できないことである。むしろ、デバイスドライバは、特定入出力機能のためのリソース割り当てを、以下で説明するようにIOResourceLockEntryオブジェクトを通して取得する。GetAssignment()メソッドは、リソース競合リゾルバオブジェクトがリソース割り当てを作成していれば、第１の列挙型値(kAssigned)を返し、リソース競合リゾルバオブジェクトがリソース割り当てを作成していなければ、別の異なる値(kNotAssigned)を返す。これらの関数は次のような形式になっている
【０１７２】
void EAssignmentStatus GetAssignment (TIOFunctionResourceAssignment&
assignment) const; および
void SetAssignment (const TIOFunctionResourceAssignment& assignment);
【０１７３】
GetFunctionNumber()メソッドは入出力機能に関連付けられた機能番号を返し、この番号は拡張ボード上の特定機能を示している。SetFunctionNumber()メソッドは入出力機能に関連付けられた機能番号を書き出す。これらの関数は次のような形式になっている。
【０１７４】
TIOFunctionHardwareInterfaceIdentifier::FunctionNumber
GetFunctionNumber const; および
void SetFunctionNumber (TIOFunctionHardwareInterfaceIdentifier::FunctionNumber
functionNumber);
【０１７５】
GetResourceConflicts()メソッドは、入出力機能のリソース割り当てに関連するリソース競合オブジェクトのコレクションを返し、SetResourceConflicts()メソッドは、入出力機能のリソース割り当てに関連するリソース競合をIOFunctionResourceUsageオブジェクトに書き込む。これらの関数は次のような形式になっている。
【０１７６】
void GetResourceConflicts (TCollectionOf <TIOResourceConflict>& conflicts ) const; および
void SetResourceConflicts (const TCollectionOf <TIOResourceConflict>&
conflicts);
【０１７７】
GetAssignmentPeriod()メソッドは、特定リソース割り当てのためのリソース割り当て期間を返し、そのリソース割り当てが現行ブート期間で有効であれば第１の値(kThisBoot)を返し、そのリソース割り当てが次回のブート期間だけで有効であれば第２の異なる値(kNextBoot)を返す。SetAssignmentPeriod()メソッドは割り当てのためのリソース割り当て期間をIOFunctionResourceUsageオブジェクトに書き込む。これらの関数は次のような形式になっている。
【０１７８】
EAssignmentPeriod GetAssignmentPeriod() const; および
void SetAssignmentPeriod (const EAssignmentPeriod period);
【０１７９】
TIOResourceConflictResolverクラス１１００は、システム内のマザーボードと拡張カード上の入出力機能のための無競合リソース割り当てを、特定のブート期間に生成するProduceConflictFreeAssignmentsメソッドをさらに含んでいる。ブート期間パラメータは、競合リゾルバオブジェクトにリソース割り当てをこのブート期間(kThisBoot)に生成させるか、次回のブート期間(kNextBoot)に生成させるかを競合リゾルバオブジェクトに指示する値になっている。TIOResourceConflictResolverクラス１１００のProduceConflictFreeAssignmentsメソッドは、現在、リソース割り当てのないすべての入出力機能のためのIOFunctionResourceAssignmentオブジェクトを生成する。リソース割り当てに競合が起こっていなければ、ProduceConflictFreeAssignments()メソッドはIOResourceConflictオブジェクトを作成する。リソース割り当ての生成を試みている途中でリソース割り当ての競合が見つかったときは、ProduceConflictFreeAssignments()メソッドは例外をスローするが、既存のリソース割り当ては変更しない。
【０１８０】
無競合リソース割り当てメソッド
以下では、図１２、１３および図１４Ａ、１４Ｂに示すフローチャートを参照して、ProduceConflictFreeAssignments()メソッドのオペレーションについて詳しく説明する。図１２は、無競合リソース割り当てセットを生成するルーチン例を示すフローチャートである。このルーチンはステップ１２００からスタートし、ステップ１２０２へ進み、そこでシステム内の拡張カード上の全機能のコレクションが、前述したように、競合リゾルバオブジェクトに登録されているIOCardResourceUsageオブジェクトから作成される。このステップでは、ルーチンはIOCardResourceUsageオブジェクトを通るたびに繰り返され、すべてのIOFunctionResourceUsageオブジェクトを抽出し、それらを配列に入れる。
【０１８１】
次に、ステップ１２０４では、限界カウント(limit counts)がメモリ割り当て、入出力レジスタ割り当て、DMAチャネル割り当ておよび割り込みソケット割り当てに対して設定される。これらの限界カウントは、PossibleIOResourceAssignmentオブジェクト内にネストされている、該当のメモリ、レジスタ、DMAおよび割り込み制約オブジェクトから取得される。これらの限界値は次のステップ（１２０６）のとき使用され、すべてのリソース組み合わせがいつ試みられたかを判断し、競合リソース割り振りをいつ行うことができないかを競合リゾルバが決定できるようにする。
【０１８２】
次に、ステップ１２０６では、ステップ１２０２で作成された機能コレクションが調べられ、可能なリソース割り振りがPossibleIOResourceAssignmentオブジェクトと、ネストされたIOMemoryConstraint、IORegisterConstraint、DMAConstraintおよびInterruptConstraintオブジェクトとを使用して構築される。次に、可能な割り当てセットは各機能を通るループに入ることによって、IOFunctionResourceUsageオブジェクトを使用してチェックされ、その割り当てが他の割り当てと競合しているかが判断される。ステップ１２０８で示すように、競合が見つかれば、ステップ１２１０に示すように、追加のリソース組み合わせが試みられないまま残っているかどうかを判断するためのチェックが行われる。試みられていない追加のリソース組み合わせが残っていれば、ルーチンはステップ１２０６に戻り、そこで新しい可能なリソース割り当てが作られ、試みられる。
【０１８３】
ステップ１２１０で、試みられていないリソース組み合わせが残っていなければ、ルーチンはステップ１２１４へ進み、競合オブジェクトを作成し、無競合リソース割り振りが達成できないことを示す例外をスローする。好ましいルーチンでは、競合オブジェクトは最初に競合が検出されたとき生成される。しかし、競合が検出されても、ルーチンは、すべてのリソース組み合わせが試みられるまで追加のリソース組み合わせを試みることを続ける。無競合リソース割り振りが取得できなければ、最初に作成された競合オブジェクトがユーザに戻されるので、ユーザは、なぜ競合が起こったか、どのようにすれば競合を除去できるかを判断することができる。そのあと、ルーチンはステップ１２１６で終了する。
【０１８４】
上記とは別に、ステップ１２０８で、特定のリソース割り振りとの競合が見つからなければ、ルーチンはステップ１２１２へ進み、そこでIOResourceCardUsageオブジェクトが新しいリソース割り振りを使用して更新される。そのあと、ルーチンはステップ１２１６で終了する。
図１３は、機能コレクション配列を、ステップ１２０２に示すようにTIOCardResourceUsageオブジェクトから作成するためのルーチンを示すフォローチャートである。具体的には、ステップ１３０２で、機能コレクションを収めておく２つの配列が作成される。これらはブート配列(boot array)および非ブート配列(non-boot array)と呼ばれる。ブート配列は現行ブートオペレーションに不可欠である機能を収容し、他方、非ブート配列は現行ブートオペレーションに不可欠でない機能（例えば、次回のブートで使用される関数）を収容している。
【０１８５】
ステップ１３０４では、ルーチンはTIOCardResourceUsageオブジェクトが置かれているデキューをループし、不可欠な機能を指すポインタをブート配列に挿入する。次に、ステップ１３０６では、ルーチンはTIOCardResourceUsageオブジェクトをループし、非不可欠な機能を指す機能ポインタを非ブート配列に挿入する。ステップ１３０８で、ボート配列と非ブート配列は分類された機能コレクションを作成するように促される。
【０１８６】
次に、ステップ１３１０では、機能の各々のための可能なIOResourceAssignmentオブジェクトが取り出されて、各機能のための可能なリソース割り当てのデキューが作られる。そのあと、ルーチンはステップ１３１２で終了する。このルーチンを実行する実際のルーチンを示すコードフラグメントは次の通りである。
【０１８７】
void TIOResourceConflictResolver::CreateFunctionCollectionFromCards()
{
TDequeOf<TIOFunctionResourceUsage>                  functionDeque;
TIOFunctionResourceUsage                                  *function;
TSequenceOfIterator<TIOFunctionResourceUsage>        *functionIterator;
TIOCardResourceUsage                                          *card;
TSequenceOfIterator<TIOCardResourceUsage>                *cardIterator;
Int          index, bootIndex = 0, nonBootIndex = 0, indexCollection = 0;
TArrayOf<TIOFunctionResourceUsage>                    functionForBoot,
functionNonBoot;
ConflictResolverFunctionIndex                            *whichCollection;
TArrayOf<struct ConflictResolverFunctionIndex>                bootIndexes,
nonBootIndexes;
cardIterator = fCard.CreateSequenceIterator();
functionForBoot.SetAutoGrowFlag(TRUE);
functionNonBoot.SetAutoGrowFlag(TRUE);
bootIndexes.SetAutoGrowFlag(TRUE);
nonBootIndexes.SetAutoGrowFlag(TRUE);
for (card = cardIterator->First(); card != NIL; card = cardIterator->Next()) {
card->GetFunctionResourceUsage(functionDeque);
functionIterator = functionDeque.CreateSequenceIterator();
for (function = functionIterator->First(); function != NIL; function =
functionIterator->Next()) {
whichCollection = new struct ConflictResolverFunctionIndex;
whichCollection->indexPriority =
function->GetFunctionPriority();
whichCollection->indexIntoCollection = indexCollection++;
if (function->GetFunctionPriority() ==
TIOFunctionResourceUsage::kEssentialForBoot) {
functionForBoot.AtPut(bootIndex, function);
bootIndexes.AtPut(bootIndex, whichCollection);
bootIndex++;
} else {
functionNonBoot.AtPut(nonBootIndex, function);
nonBootIndexes.AtPut(nonBootIndex,
whichCollection);
nonBootIndex++;
}
}
delete functionIterator;
functionDeque.RemoveAll();
}
fFunctionCount = bootIndex + nonBootIndex;
fFunctions = new FunctionPossibleAssignment[fFunctionCount];
//
// ブート機能と非ブート機能コレクションを、ソートした
// コレクションとして１つにマージする
//
indexCollection = 0;
for (index = 0; index < bootIndex; index++) {
BuildFunctionPossible(fFunctions[indexCollection], 
*functionForBoot.At(index), *bootIndexes.At(index));
indexCollection++;
}
for (index = 0; index < nonBootIndex; index++) {
BuildFunctionPossible(fFunctions[indexCollection],
*functionNonBoot.At(index), *nonBootIndexes.At(index));
indexCollection++;
}
functionForBoot.DeleteAll();
functionNonBoot.DeleteAll();
bootIndexes.DeleteAll();
nonBootIndexes.DeleteAll();
delete cardIterator;
return;
}
void TIOResourceConflictResolver::BuildFunctionPossible(
TIOResourceConflictResolverDoer::FunctionPossibleAssignment & function, TIOFunctionResourceUsage & functionUsage, 
ConflictResolverFunctionIndex & index)
{
TIOFunctionResourceAssignment                        assignment;
TSequenceOfIterator<TPossibleIOResourceAssignment>      *iterator;
TDequeOf<TPossibleIOResourceAssignment>              possibleDeque;
TPossibleIOResourceAssignment                        *possible;
Int        maxRegisterCount = 0, maxMemoryCount = 0,
maxInterruptCount = 0, maxDMACount = 0;
functionUsage.GetAssignmentConstraints(possibleDeque);
if (possibleDeque.Count() == 0) 
functionUsage.GetPossibleAssignments(possibleDeque);
function.fPossibleCount = possibleDeque.Count();
iterator = possibleDeque.CreateSequenceIterator();
function.fPossibles = new
PossibleResources[function.fPossibleCount];
possible = iterator->First();
for (int i = 0; i < function.fPossibleCount; i++, possible =
iterator->Next()) {
CreateMemoryPossible(function.fPossibles[i], *possible,
maxMemoryCount);
CreateRegisterPossible(function.fPossibles[i], *possible,
maxRegisterCount);
CreateDMAPossible(function.fPossibles[i], *possible,
maxDMACount);
CreateInterruptPossible(function.fPossibles[i], *possible,
maxInterruptCount);
}
if (maxMemoryCount) {
function.fMemoryBaseAddresses = new
TPossibleIOResourceAssignment::TIOMemoryConstraint::
BaseAddress[maxMemoryCount];
function.fMemoryUseBoolean = new Boolean[maxMemoryCount];
} else {
function.fMemoryBaseAddresses = NIL;
function.fMemoryUseBoolean = NIL;
}
if (maxRegisterCount) 
function.fRegisterBaseAddresses = new
TPossibleIOResourceAssignment::TIORegisterConstraint::
BaseAddress[maxRegisterCount];
else 
function.fRegisterBaseAddresses = NIL;
if (maxDMACount)
function.fDMAChannelNumbers = new
TDMAChannelInformation::DMAChannelNumber
[maxDMACount];
else
function.fDMAChannelNumbers = NIL;
if (maxInterruptCount)
function.fInterruptSocketNumbers = new
InterruptSocketNumber[maxInterruptCount];
Else          function.fInterruptSocketNumbers = NIL;
delete iterator;
possibleDeque.DeleteAll();
function.fConflicts = NIL;
function.fConstructedAssignment = NIL;
function.fHaveAssignment = FALSE;
function.fMemoryCount = 0;
function.fRegisterCount = 0;
function.fInterruptCount = 0;
function.fDMACount = 0;
function.fFunctionIndex = index.indexIntoCollection;
function.fFunctionIdentifier = functionUsage.CopyFunctionIdentifier();
//
// 構築される割り当てはResolve PeriodがNext Bootに対するものか、
// または既存の割り当てが存在しないときは作成されない
//
if (fResolvePeriod == TIOFunctionResourceUsage::kNextBoot || 
functionUsage.GetAssignment(assignment) ==
TIOFunctionResourceUsage::kNotAssigned) {
//
// 割り当てを構築する
//
if (maxInterruptCount)
function.fInterruptAssignments = new
InterruptAssignment[maxInterruptCount];
Else          function.fInterruptAssignments = NIL;
if (maxDMACount)
function.fDMAAssignments = new
DMAAssignment[maxDMACount];
Else          function.fDMAAssignments = NIL;
if (maxMemoryCount)
function.fMemoryAssignments = new
MemoryAssignment[maxMemoryCount];
Else          function.fMemoryAssignments = NIL;
if (maxRegisterCount)
function.fRegisterAssignments = new
RegisterAssignment[maxRegisterCount];
Else          function.fRegisterAssignments = NIL;
return;
}
function.fHaveAssignment = TRUE;
TDequeOf<TIOFunctionResourceAssignment::TIOMemoryAssignment>
memoryDeque;
TIOFunctionResourceAssignment::TIOMemoryAssignment
*memory;
TDequeOf<TIOFunctionResourceAssignment::TIORegisterAssignment>
registerDeque;
TIOFunctionResourceAssignment::TIORegisterAssignment      *io;
TDequeOf<TIOFunctionResourceAssignment::TDMAAssignment>
dmaDeque;
TIOFunctionResourceAssignment::TDMAAssignment          *dma;
TDequeOf<TIOFunctionResourceAssignment::TInterruptAssignment>
interruptDeque;
TIOFunctionResourceAssignment::TinterruptAssignment      *interrupt;
assignment.GetMemoryAssignment(memoryDeque);
if (memoryDeque.Count()) {
TDequeOfIterator<TIOFunctionResourceAssignment::
TIOMemoryAssignment>  memoryIterator(&memoryDeque);
MemoryAssignment                  *memoryAssignment;
function.fMemoryCount = memoryDeque.Count();
function.fMemoryAssignments =
memoryAssignment = new
MemoryAssignment[function.fMemoryCount];
for (memory = memoryIterator.First(); memory; memory =
memoryIterator.Next(), memoryAssignment++) {
memoryAssignment->fCanShare = memory->IsSharable();
memoryAssignment->fBaseAddress =
memory->GetBaseAddress();
memoryAssignment->fLength = memory->GetLength();
}
}
assignment.GetIOAssignment(registerDeque);
if (registerDeque.Count()) {
TDequeOfIterator<TIOFunctionResourceAssignment::
TIORegisterAssignment>    registerIterator(&registerDeque);
RegisterAssignment                      *registerAssignment;
function.fRegisterCount = registerDeque.Count();
function.fRegisterAssignments = registerAssignment = new
RegisterAssignment[registerDeque.Count()];
for (io = registerIterator.First(); io; io= registerIterator.Next(),
registerAssignment++) {
registerAssignment->fCanShare = io->IsSharable();
registerAssignment->fBaseAddress =io->GetBaseAddress();
registerAssignment->fLength = io->GetLength();
}
}
assignment.GetDMAAssignment(dmaDeque);
if ((function.fDMACount = dmaDeque.Count()) != 0) {
TDequeOfIterator<TIOFunctionResourceAssignment::
TDMAAssignment> dmaIterator(&dmaDeque);
DMAAssignment              *dmaAssignment;
function.fDMAAssignments = dmaAssignment =
new DMAAssignment[function.fDMACount];
for (dma = dmaIterator.First(); dma; dma = dmaIterator.Next(),
dmaAssignment++) {
dmaAssignment->fCanShare = dma->IsSharable();
dmaAssignment->fDMAChannel =
dma->GetChannelNumber();
}
}
assignment.GetInterruptAssignment(interruptDeque);
if ((function.fInterruptCount = interruptDeque.Count()) != 0) {
TDequeOfIterator<TIOFunctionResourceAssignment::
TInterruptAssignment> interruptIterator(&interruptDeque);
InterruptAssignment          *interruptAssignment;
function.fInterruptAssignments = interruptAssignment
= new InterruptAssignment[function.fInterruptCount];
for (interrupt = interruptIterator.First(); interrupt; interrupt =
interruptIterator.Next(), interruptAssignment++) {
interruptAssignment->fCanShare = interrupt->IsSharable();
interruptAssignment->fInterruptSocket =
interrupt->GetInterruptSocket();
}
}
}
void TIOResourceConflictResolver::CreateMemoryPossible(
TIOResourceConflictResolverDoer::PossibleResources & function,
TPossibleIOResourceAssignment & possible,
Int            & maxCount)
{
TDequeOf<TDequeOf<TPossibleIOResourceAssignment::
TIOMemoryConstraint> > masterDeque;
TDequeOf<TPossibleIOResourceAssignment::TIOMemoryConstraint>
*memoryDeque;
TSequenceOfIterator<TPossibleIOResourceAssignment::TIOMemoryConstraint>
*iterator;
TSequenceOfIterator<TDequeOf<TPossibleIOResourceAssignment::
TIOMemoryConstraint>>            *collectionIterator;
TPossibleIOResourceAssignment::TIOMemoryConstraint      *memory;
MemoryPossible                                *memoryResource;
MemoryCollection                              *memoryCollection;
possible.GetMemoryConstraints(masterDeque);
if ((function.fMemoryCollectionCount = masterDeque.Count()) == 0)  {
function.fMemoryPossible = NIL;
return;
}
memoryCollection = function.fMemoryPossible = new
MemoryCollection[function.fMemoryCollectionCount];
collectionIterator = masterDeque.CreateSequenceIterator();
for (memoryDeque = collectionIterator->First(); memoryDeque;
memoryDeque = collectionIterator->Next(), memoryCollection++) {
iterator = memoryDeque->CreateSequenceIterator();
memoryCollection->fMemoryCount = memoryDeque->Count();
if (memoryCollection->fMemoryCount > maxCount)
maxCount = memoryCollection->fMemoryCount;
memoryResource = memoryCollection->fMemoryPossible =
new MemoryPossible[memoryCollection->fMemoryCount];
for (memory = iterator->First(); memory; memory = iterator->Next(),
memoryResource++) {
memoryResource->fLowerBaseAddress =
memory->GetLowerBaseAddress();
memoryResource->fUpperBaseAddress =
memory->GetUpperBaseAddress();
memoryResource->fLength = memory->GetLength();
memoryResource->fIncrement =
memory->GetBaseIncrement();
memoryResource->fConstraint =
memory->GetConstraintNumber();
memoryResource->fCanShare = memory->IsSharable();
memory->GetMemoryUsageMode(
memoryResource->fMemoryMode);
}
delete iterator;
}
delete collectionIterator;
::DeepDelete(masterDeque);
}
void TIOResourceConflictResolver::CreateRegisterPossible(
TIOResourceConflictResolverDoer::PossibleResources&         function,
TPossibleIOResourceAssignment& possible, int& maxCount)
{
TDequeOf<TDequeOf<TPossibleIOResourceAssignment::
TIORegisterConstraint> >masterDeque;
TDequeOf<TPossibleIOResourceAssignment::
TIORegisterConstraint> *registerDeque;
TSequenceOfIterator<TDequeOf<TPossibleIOResourceAssignment::
TIORegisterConstraint> > *collectionIterator;
TSequenceOfIterator<TPossibleIOResourceAssignment::
TIORegisterConstraint> *iterator;
TPossibleIOResourceAssignment::TIORegisterConstraint      *io;
RegisterPossible *registerResource;
RegisterCollection *registerCollection;
possible.GetIOConstraints(masterDeque);
if ((function.fRegisterCollectionCount = masterDeque.Count()) == 0)  {
function.fRegisterPossible = NIL;
return;
}
collectionIterator = masterDeque.CreateSequenceIterator();
registerCollection = function.fRegisterPossible = new
RegisterCollection[function.fRegisterCollectionCount];
for (registerDeque = collectionIterator->First(); registerDeque;
registerDeque = collectionIterator->Next(), registerCollection++) {
registerCollection->fRegisterCount = registerDeque->Count();
registerResource = registerCollection->fRegisterPossible = new
RegisterPossible[registerCollection->
fRegisterCount];
if (registerCollection->fRegisterCount > maxCount)
maxCount = registerCollection->fRegisterCount;
iterator = registerDeque->CreateSequenceIterator();
for (io = iterator->First(); io; io = iterator->Next(),
registerResource++) {
registerResource->fLowerBaseAddress =
io->GetLowerBaseAddress();
registerResource->fUpperBaseAddress =
io->GetUpperBaseAddress();
registerResource->fLength = io->GetLength();
registerResource->fIncrement = io->GetBaseIncrement();
registerResource->fConstraint = io->GetConstraintNumber();
registerResource->fCanShare = io->IsSharable();
io->GetRegisterUsageMode(registerResource->
fRegisterMode);
}
delete iterator;
}
delete collectionIterator;
::DeepDelete(masterDeque);
}
void TIOResourceConflictResolverDoer::CreateDMAPossible(
TIOResourceConflictResolverDoer::PossibleResources &
function,
TPossibleIOResourceAssignment & possible,
int&            maxCount)
{
TDequeOf<TDequeOf<TPossibleIOResourceAssignment::
TDMAConstraint> >masterDeque;
TDequeOf<TPossibleIOResourceAssignment::TDMAConstraint>
*dmaDeque;
TSequenceOfIterator<TDequeOf<TPossibleIOResourceAssignment::
TDMAConstraint> >            *collectionIterator;
TSequenceOfIterator<TPossibleIOResourceAssignment::
TDMAConstraint> *iterator;
TPossibleIOResourceAssignment::TDMAConstraint          *dma;
DMAPossible *dmaResource;
DMACollection *dmaCollection;
possible.GetDMAConstraints(masterDeque);
if ((function.fDMACollectionCount = masterDeque.Count()) == 0)  {
function.fDMAPossible = NIL;
return;
}
dmaCollection = function.fDMAPossible = new
DMACollection[function.fDMACollectionCount];
collectionIterator = masterDeque.CreateSequenceIterator();
for (dmaDeque = collectionIterator->First(); dmaDeque; dmaDeque =
collectionIterator->Next(), dmaCollection++) {
dmaCollection->fDMACount = dmaDeque->Count();
dmaResource = dmaCollection->fDMAPossible = new
DMAPossible[dmaCollection->fDMACount];
if (dmaCollection->fDMACount > maxCount)
maxCount =  dmaCollection->fDMACount;
iterator = dmaDeque->CreateSequenceIterator();
for (dma = iterator->First(); dma; dma = iterator->Next(),
dmaResource++) {
dmaResource->fLowerDMAChannel =
dma->GetLowerChannelNumber();
dmaResource->fUpperDMAChannel =
dma->GetUpperChannelNumber();
dmaResource->fConstraint = dma->GetConstraintNumber();
dmaResource->fCanShare = dma->IsSharable();
dma->GetDMAUsageMode(dmaResource->fDMAMode);
}
delete iterator;
}
::DeepDelete(masterDeque);
delete collectionIterator;
}
void TIOResourceConflictResolverDoer::CreateInterruptPossible(
TIOResourceConflictResolverDoer::PossibleResources & function,
TPossibleIOResourceAssignment & possible,
int&                      maxCount)
{
TDequeOf<TDequeOf<TPossibleIOResourceAssignment::
TInterruptConstraint> > masterDeque;
TDequeOf<TPossibleIOResourceAssignment::
TInterruptConstraint>*interruptDeque;
TSequenceOfIterator<TDequeOf<TPossibleIOResourceAssignment::
TInterruptConstraint> > *collectionIterator;
TSequenceOfIterator<TPossibleIOResourceAssignment::
TInterruptConstraint> *iterator;
TPossibleIOResourceAssignment::TinterruptConstraint        *interrupt;
InterruptPossible                                  *interruptResource;
InterruptCollection                                *interruptCollection;
possible.GetInterruptConstraints(masterDeque);
if ((function.fInterruptCollectionCount = masterDeque.Count()) == 0) {
function.fInterruptPossible = NIL;
return;
}
function.fInterruptPossible = interruptCollection = new
InterruptCollection[function.fInterruptCollectionCount];
collectionIterator = masterDeque.CreateSequenceIterator();
for (interruptDeque = collectionIterator->First(); interruptDeque;
interruptDeque = collectionIterator->Next(),
interruptCollection++) {
interruptCollection->fInterruptCount = interruptDeque->Count();
if (interruptCollection->fInterruptCount > maxCount)
maxCount = interruptCollection->fInterruptCount;
interruptResource = interruptCollection->fInterruptPossible =
new InterruptPossible[interruptCollection->fInterruptCount];
iterator = interruptDeque->CreateSequenceIterator();
for (interrupt = iterator->First(); interrupt; interrupt =
iterator->Next(),
interruptResource++) {
interruptResource->fLowerInterruptSocket =
interrupt->GetLowerInterruptSocket();
interruptResource->fUpperInterruptSocket =
interrupt->GetUpperInterruptSocket();
interruptResource->fConstraint =
interrupt->GetConstraintNumber();
interruptResource->fCanShare = interrupt->IsSharable();
interrupt->GetInterruptUsageMode(
interruptResource->fInterruptMode);
}
delete iterator;
}
delete collectionIterator;
::DeepDelete(masterDeque);
}
【０１８８】
図１４Ａおよび図１４Ｂは一緒に使用され、ステップ１２０６に示すように機能を通るループに入り、競合の有無をチェックするルーチンを示すフローチャートである。このルーチンはステップ１４００からスタートし、ステップ１４０２へ進み、そこでリソースを割り当てる必要のある追加機能が残っているかどうかが判断される。残っていなければ、ルーチンは他ページ結合子１４１９と１４２１を経て次へ進み、ステップ１４３４で終了する。別の機能が残っていれば、ルーチンはステップ１４０６へ進み、そこで図１３に示すルーチンによってアセンブルされた機能コレクションから新しい機能が取得される。この機能は、リソースがすでに割り当てられているかどうかが確かめられる。すでに割り当てられていれば、ルーチンはステップ１４０２に戻り、追加機能があるかどうかがチェックされる。もしなければ、ルーチンはステップ１４１０へ進み、そこでメモリ、DMA、入出力レジスタおよび割り込みリソースの新しい組み合わせが作られる。
【０１８９】
次に、ルーチンはステップ１４１２へ進み、そこで割り当て変数を通るループに入り、新しい可能なリソース割り当てが生成される。次に、ルーチンは他ページ結合子１４１８と１４２２を経てステップ１４２４へ進み、そこで各々の割り当て変数ごとに、各機能を通るループに入り、競合の有無がチェックされる。ステップ１４２６で、ルーチンは現行機能のための割り込み、DMA、入出力レジスタおよびメモリ割り当てで競合が起こっているかどうかをチェックする。
【０１９０】
ステップ１４２８で競合が検出されなければ、ルーチンはステップ１４３４で終了する。逆に、競合が検出されると、ルーチンはステップ１４３０へ進み、そこで前述したように、最初に「ループを通過する」とき競合オブジェクトが生成される。次に、ステップ１４３２で、割り当て可能な追加リソースがあるかどうかを確かめるチェックが行われる。もしあれば、ルーチンは他ページ結合子１４２０と１４１６を経てステップ１４１０へ進み、そこで新しいリソースの組み合わせが作成され、上記プロセスが繰り返される。
【０１９１】
上記とは別に、ステップ１４３２で、割り振るべきリソースが残っていなければ、ルーチンはステップ１４３４で終了する。前述したように、競合オブジェクトが生成されていれば、例外がスローされ、競合が起こったことがユーザに通知される。図１４Ａと図１４Ｂに示すステップを実行するコードフラグメントの例を示すと、次の通りである。
【０１９２】
Boolean TIOResourceConflictResolver::LoopThroughFunction (
int currentIndex)
{
FunctionPossibleAssignment                              *thisFunction;
if (currentIndex >= fFunctionCount) 
return        FALSE;
thisFunction = &fFunctions[currentIndex];
//
// 機能が割り当てをすでにもっていれば、それをスキップする
//
if (thisFunction->fHaveAssignment == TRUE) {
currentIndex++;
if (currentIndex < fFunctionCount)
return        LoopThroughFunction(currentIndex);
else
return        FALSE;
} else {
PossibleResources                                *thisPossible;
In                                              possibleIndex;
thisPossible = thisFunction->fPossibles;
for (possibleIndex = 0; possibleIndex <
thisFunction->fPossibleCount;
possibleIndex++, thisPossible++) {
if (LoopThroughPossibleResources(*thisPossible,
*thisFunction, currentIndex)) {
fFirstPass = FALSE;
} else {
return FALSE;
}
}
return        TRUE;
}
}
Boolean TIOResourceConflictResolver::LoopThroughPossibleResources(
TIOResourceConflictResolver::PossibleResources & thisPossible,
TIOResourceConflictResolver::FunctionPossibleAssignment &
thisFunction,
int                            currentIndex)
{
MemoryCollection                                        *memoryItem;
RegisterCollection                                        *registerItem;
InterruptCollection                                        *interruptItem;
DMACollection                                              *dmaItem;
Int                          memoryIndex, registerIndex, interruptIndex,
dmaIndex;
Boolean                      interruptLooppedOnce, dmaLooppedOnce,
registerLooppedOnce, memoryLooppedOnce;
//
// プログラムは、thisPossibleが特定のハードウェアリソースを
// 使用していなくても、各リソースで少なくとも一回繰り返し
// を行う。リソースが使用されなければ、そのリソースはスキップ
// される。しかし、他のリソース（使用の有無に関係なく）は
// ループに入って繰り返される。
//
interruptItem = thisPossible.fInterruptPossible;
interruptLooppedOnce = FALSE;
interruptIndex = 0;
while(interruptIndex < thisPossible.fInterruptCollectionCount ||
interruptLooppedOnce == FALSE) {
interruptLooppedOnce = TRUE;
interruptIndex++;
dmaItem = thisPossible.fDMAPossible;
dmaLooppedOnce = FALSE;
dmaIndex = 0;
while (dmaIndex < thisPossible.fDMACollectionCount ||
dmaLooppedOnce == FALSE) {
dmaLooppedOnce = TRUE;
dmaIndex++;
registerItem = thisPossible.fRegisterPossible;
registerLooppedOnce = FALSE;
registerIndex = 0;
while (registerIndex < thisPossible.fRegisterCollectionCount
|| registerLooppedOnce == FALSE) {
registerIndex++;
registerLooppedOnce = TRUE;
memoryItem = thisPossible.fMemoryPossible;
memoryLooppedOnce = FALSE;
memoryIndex = 0;
while (memoryIndex <
thisPossible.fMemoryCollectionCount
|| memoryLooppedOnce == FALSE) {
memoryLooppedOnce = TRUE;
memoryIndex++;
if (LoopThroughAssignmentVariables(
thisPossible, thisFunction,
currentIndex, interruptItem,
dmaItem, registerItem,
memoryItem) == FALSE) {
ConstructNewAssignment(thisFunction,
interruptItem, dmaItem,
registerItem, memoryItem);
return FALSE;
}
fFirstPass = FALSE;
if (memoryItem)
memoryItem++;
}
if (registerItem)
registerItem++;
}
if (dmaItem)
dmaItem++;
}
if (interruptItem)
interruptItem++;
}
thisFunction.fHaveAssignment = FALSE;
return        TRUE;
}
Boolean TIOResourceConflictResolverDoer::LoopThroughAssignmentVariables
(TIOResourceConflictResolverDoer::PossibleResources &
thisPossible, TIOResourceConflictResolverDoer::
FunctionPossibleAssignment & thisFunction, int currentIndex,
TIOResourceConflictResolverDoer::InterruptCollection        *interruptItem, 
TIOResourceConflictResolverDoer::DMACollection *dmaItem, 
TIOResourceConflictResolverDoer::RegisterCollection*registerItem
TIOResourceConflictResolverDoer::MemoryCollection
*memoryItem)
{
InterruptSocketNumber                                  *interruptCurrent;
TDMAChannelInformation::DMAChannelNumber              *dmaCurrent;
TPossibleIOResourceAssignment::TIORegisterConstraint::BaseAddress
*lowerIOAddress;
TPossibleIOResourceAssignment::TIOMemoryConstraint::BaseAddress
*lowerMemAddress;
Boolean 
*useMemoryItem;
InterruptAssignment
*interruptAssignment;
MemoryAssignment
*memoryAssignment;
RegisterAssignment                            *registerAssignment;
DMAAssignment
*dmaAssignment;
int i;
//RemoveConstructedAssignments(thisFunction);
thisFunction.fMemoryCount = 0;
thisFunction.fRegisterCount = 0;
thisFunction.fDMACount = 0;
thisFunction.fInterruptCount = 0;
thisFunction.fHaveAssignment = TRUE;
// 
// 変数割り当ての各々を通るループに入って繰り返される
//
if (interruptItem) {
interruptAssignment = thisFunction.fInterruptAssignments;
thisFunction.fInterruptCount = interruptItem->fInterruptCount;
interruptCurrent = thisFunction.fInterruptSocketNumbers;
for (i = 0; i < thisFunction.fInterruptCount; i++) {
interruptAssignment->fCanShare =
interruptItem->fInterruptPossible[i].fCanShare;
interruptCurrent[i] = interruptItem->
fInterruptPossible[i].fLowerInterruptSocket;
}
} 
if (dmaItem) {
dmaAssignment = thisFunction.fDMAAssignments;
thisFunction.fDMACount = dmaItem->fDMACount;
dmaCurrent = thisFunction.fDMAChannelNumbers;
for (i = 0; i < dmaItem->fDMACount; i++) {
dmaCurrent[i] =
dmaItem->fDMAPossible[i].fLowerDMAChannel;
dmaAssignment[i].fCanShare =
dmaItem->fDMAPossible[i].fCanShare;
}
} 
if (registerItem) {
registerAssignment = thisFunction.fRegisterAssignments;
thisFunction.fRegisterCount = registerItem->fRegisterCount;
lowerIOAddress = thisFunction.fRegisterBaseAddresses;
for (i = 0; i < registerItem->fRegisterCount; i++) {
registerAssignment[i].fCanShare =
registerItem->fRegisterPossible[i].fCanShare;
registerAssignment[i].fLength =
registerItem->fRegisterPossible[i].fLength;
lowerIOAddress[i] =
registerItem->fRegisterPossible[i].fLowerBaseAddress;
}
}
if (memoryItem) {
memoryAssignment = thisFunction.fMemoryAssignments;
thisFunction.fMemoryCount = memoryItem->fMemoryCount;
useMemoryItem = thisFunction.fMemoryUseBoolean;
lowerMemAddress = thisFunction.fMemoryBaseAddresses;
for (i = 0; i < memoryItem->fMemoryCount; i++) {
if (memoryItem->fMemoryPossible[i].fMemoryMode.
GetMemoryType() ==
TIOMemoryReference::kCardMemory)                               {
useMemoryItem[i] = TRUE;
memoryAssignment[i].fCanShare =
memoryItem->fMemoryPossible[i].fCanShare;
memoryAssignment[i].fLength =
memoryItem->fMemoryPossible[i].fLength;
lowerMemAddress[i] =
memoryItem->fMemoryPossible[i].
fLowerBaseAddress;
memoryAssignment[i].fIsCardMemory = TRUE;
} else {
useMemoryItem[i] = FALSE;
memoryAssignment[i].fIsCardMemory = FALSE;
}
}
}
for (Boolean processInterrupt = TRUE; processInterrupt;) {
if (interruptItem) {
for (i = 0; i < interruptItem->fInterruptCount; i++)  {
interruptAssignment[i].fInterruptSocket =
interruptCurrent[i];
}
}
if (dmaItem) {
for (i = 0; i < dmaItem->fDMACount; i++)
dmaCurrent[i] =
dmaItem->fDMAPossible[i].fLowerDMAChannel;
}
for (Boolean processDMA = TRUE; processDMA;) {
if (dmaItem) {
for (i = 0; i < dmaItem->fDMACount; i++) {
dmaAssignment[i].fDMAChannel =
dmaCurrent[i];
}
}
if (registerItem) {
for (i = 0; i < registerItem->fRegisterCount; i++)
lowerIOAddress[i] =
registerItem->fRegisterPossible[i].
fLowerBaseAddress;
} 
for (Boolean processRegister = TRUE; processRegister;) {
if (registerItem) {
for (i = 0; i < registerItem->fRegisterCount; i++) {
registerAssignment[i].fBaseAddress =
lowerIOAddress[i];
}
}
//
// アイテムがあり、かつそのアイテムが実カードメモリ
// （入出力にホストメモリを使用するオンボードメモリを
// 実装していないカードと対比）を表しているときだけ
// メモリを調べる。
//
if (memoryItem) {
for (i = 0; i < memoryItem->fMemoryCount; i++)
if (useMemoryItem[i])
lowerMemAddress[i] =
memoryItem->
fMemoryPossible[i].
fLowerBaseAddress;
}
for (Boolean processMemory = TRUE;
processMemory;) {
if (memoryItem) {
for (i = 0; i <
memoryItem->fMemoryCount;
i++)
if (useMemoryItem[i]) {
memoryAssignment[i].
fBaseAddress =
lowerMemAddress[i];
}
}
if (IsAssignmentWithinPlatformLimits(
thisFunction)) {
if (CheckAssignmentForConflict(
thisFunction, currentIndex) ==
FALSE) {
Return        FALSE;
} 
} 
fFirstPass = FALSE;
if (memoryItem == NIL)
break;
for (i = 0; i < memoryItem->
fMemoryCount; i++) {
lowerMemAddress[i] +=
memoryItem->fMemoryPossible[i].
fIncrement;
if (useMemoryItem[i]) {
if (lowerMemAddress[i] >
memoryItem->fMemoryPossible[i].
fUpperBaseAddress)  {
processMemory = FALSE;
break;
} else        processMemory = TRUE;
}
}
}
if (registerItem == NIL)
break;
for (i = 0; i < registerItem->fRegisterCount; i++) {
lowerIOAddress[i] +=
registerItem->fRegisterPossible[i].
fIncrement;
if (lowerIOAddress[i] >
registerItem->fRegisterPossible[i].
fUpperBaseAddress) {
processRegister = FALSE;
break;
} else processRegister = TRUE;
}
}
if (dmaItem == NIL)
break;
for (i = 0; i < dmaItem->fDMACount; i++) {
dmaCurrent[i]++;
if (dmaCurrent[i] >
dmaItem->fDMAPossible[i].
fUpperDMAChannel) {
processDMA = FALSE;
break;
} else        processDMA = TRUE;
}
}
if (interruptItem == NIL)
break;
for (i = 0; i < interruptItem->fInterruptCount; i++) {
interruptCurrent[i]++;
if (interruptCurrent[i] >
interruptItem->fInterruptPossible[i].
fUpperInterruptSocket) {
processInterrupt = FALSE;
break;
} else processInterrupt = TRUE;
}
}
thisFunction.fHaveAssignment = FALSE;
return TRUE;
}
Boolean TIOResourceConflictResolver::CheckAssignmentForConflict (
TIOResourceConflictResolver::FunctionPossibleAssignment &
thisFunction, int currentIndex)
{
FunctionPossibleAssignment                *function;
Boolean                      doesConflict = FALSE;
Int        i, count;
//
// 各機能を通るループに入って繰り返され、現行機能と突き合わせチェックする。
// 割り当てをもつ機能だけがチェックされる。
//
// 注意−最初に通るパスのとき、リゾルバは競合リストを作成する。
// しかし、以後のパスでは、競合が見つかると走査はそこで
//  中止される。この結果、早期に前のルーチンに戻って別の
//  シーケンスを試すことが可能になる。
//
function = &fFunctions[0];
for (i = 0; i < fFunctionCount; i++, function++) {
if (i == currentIndex)
continue;
if (function->fHaveAssignment == FALSE) 
continue;
if (CheckMemoryAssignmentConflict(*function, thisFunction)) {
if (fFirstPass == FALSE)
return TRUE;
doesConflict = TRUE;
}
if (CheckRegisterAssignmentConflict(*function, thisFunction)){
if (fFirstPass == FALSE)
return TRUE;
doesConflict = TRUE;
}
if (CheckDMAAssignmentConflict(*function, thisFunction)) {
if (fFirstPass == FALSE)
return TRUE;
doesConflict = TRUE;
}
if (CheckInterruptAssignmentConflict(*function, thisFunction)) {
if (fFirstPass == FALSE)
return TRUE;
doesConflict = TRUE;
}
}
//
// 可能ならば、次の機能へ進む
//
currentIndex++;
if (currentIndex < fFunctionCount) {
if (LoopThroughFunction(currentIndex) == TRUE)
return        TRUE;
}
return doesConflict;
}
Boolean TIOResourceConflictResolver::CheckMemoryAssignmentConflict (
TIOResourceConflictResolver::FunctionPossibleAssignment &
checkFunction, TIOResourceConflictResolver::
FunctionPossibleAssignment & thisFunction)
{
TIOFunctionResourceAssignment::TIOMemoryAssignment::BaseAddress
thisMemoryAddress, memoryToCheckAddress;
TIOFunctionResourceAssignment::TIOMemoryAssignment::BlockLength
thisMemoryLength, memoryToCheckLength;
MemoryAssignment        *thisMemory, *checkMemory;
Int                                        thisIndex, checkIndex;
if (thisFunction.fMemoryCount == 0 || checkFunction.fMemoryCount == 0) 
return FALSE;
Boolean                    doesConflict = FALSE;
thisMemory = thisFunction.fMemoryAssignments;
for (thisIndex = 0; thisIndex < thisFunction.fMemoryCount; thisIndex++,
thisMemory++) {
if (thisMemory->fIsCardMemory == FALSE)
continue;
thisMemoryAddress = thisMemory->fBaseAddress;
thisMemoryLength = thisMemory->fLength;
checkMemory = checkFunction.fMemoryAssignments;
for (checkIndex = 0; checkIndex < checkFunction.fMemoryCount;
checkIndex++, checkMemory++) {
if (checkMemory->fIsCardMemory == FALSE)
continue;
memoryToCheckAddress = checkMemory->fBaseAddress;
memoryToCheckLength = checkMemory->fLength;
if (thisMemory->fCanShare == FALSE ||
checkMemory->fCanShare == FALSE) {
if ((thisMemoryAddress >= memoryToCheckAddress
&& thisMemoryAddress <
memoryToCheckAddress+
memoryToCheckLength)
|| (memoryToCheckAddress >=
thisMemoryAddress
&& memoryToCheckAddress <
thisMemoryAddress+
thisMemoryLength)) {
//
// 最初のパスのときだけ競合を作成する
//
if (fFirstPass)
CreateResourceConflict(checkFunction,
TIOResourceConflict::
kMemoryRange);
else return        TRUE;
doesConflict = TRUE;
} 
} 
}
}
return        doesConflict;
}
Boolean TIOResourceConflictResolver::CheckRegisterAssignmentConflict (
TIOResourceConflictResolver::FunctionPossibleAssignment &
checkFunction, TIOResourceConflictResolver::
FunctionPossibleAssignment & thisFunction)
{
TIOFunctionResourceAssignment::TIORegisterAssignment::BaseAddress
thisRegisterAddress, registerToCheckAddress;
TIOFunctionResourceAssignment::TIORegisterAssignment::BlockLength
thisRegisterLength, registerToCheckLength;
RegisterAssignment        *thisRegister, *checkRegister;
Int                                          thisIndex, checkIndex;
if (thisFunction.fRegisterCount == 0 || checkFunction.
fRegisterCount == 0) 
return FALSE;
Boolean                      doesConflict = FALSE;
thisRegister = thisFunction.fRegisterAssignments;
for (thisIndex = 0; thisIndex < thisFunction.fRegisterCount; thisIndex++,
thisRegister++) {
checkRegister = checkFunction.fRegisterAssignments;
thisRegisterAddress = thisRegister->fBaseAddress;
thisRegisterLength = thisRegister->fLength;
for (checkIndex = 0; checkIndex < checkFunction.fRegisterCount;
checkIndex++, checkRegister++) {
registerToCheckAddress = checkRegister->fBaseAddress;
registerToCheckLength = checkRegister->fLength;
if (thisRegister->fCanShare == FALSE ||
checkRegister->fCanShare == FALSE) {
if ((thisRegisterAddress >=
registerToCheckAddress
&& thisRegisterAddress <
registerToCheckAddress+
registerToCheckLength)
|| (registerToCheckAddress >=
thisRegisterAddress
&& registerToCheckAddress <
thisRegisterAddress+
thisRegisterLength)) {
//
// 最初のパスのときだけ競合を作成する
//
if (fFirstPass == FALSE)
return        TRUE;
CreateResourceConflict(checkFunction,
TIOResourceConflict::kIORange);
doesConflict = TRUE;
} 
} 
}
}
return doesConflict;
}
Boolean TIOResourceConflictResolver::CheckDMAAssignmentConflict (
TIOResourceConflictResolver::FunctionPossibleAssignment &
checkFunction, TIOResourceConflictResolver::
FunctionPossibleAssignment & thisFunction)
{
Boolean                                        doesConflict = FALSE;
Int                                              checkIndex, thisIndex;
DMAAssignment                                *checkDMA, *thisDMA;
if (checkFunction.fDMACount == 0 || thisFunction.fDMACount == 0) 
return        FALSE;
thisDMA = thisFunction.fDMAAssignments;
for (thisIndex = 0; thisIndex < thisFunction.fDMACount; thisIndex++,
thisDMA++) {
checkDMA = checkFunction.fDMAAssignments;
for (checkIndex = 0; checkIndex < checkFunction.fDMACount;
checkIndex++, checkDMA++) {
if (checkDMA->fCanShare == TRUE &&
thisDMA->fCanShare == TRUE)
continue;
if (thisDMA->fDMAChannel == checkDMA->fDMAChannel) {
if (fFirstPass == FALSE)
return TRUE;
CreateResourceConflict(checkFunction,
TIOResourceConflict::kDMA);
doesConflict = TRUE;
}
}
}
return doesConflict;
}
Boolean TIOResourceConflictResolver::CheckInterruptAssignmentConflict(
TIOResourceConflictResolver::FunctionPossibleAssignment &
checkFunction, TIOResourceConflictResolver::
FunctionPossibleAssignment & thisFunction)
{
Boolean                                      doesConflict = FALSE;
Int                                            thisIndex, checkIndex;
InterruptAssignment                      *thisInterrupt, *checkInterrupt;
if (checkFunction.fInterruptCount == 0 || thisFunction.fInterruptCount ==
0) {
return FALSE;
}
thisInterrupt = thisFunction.fInterruptAssignments;
for (thisIndex = 0; thisIndex < thisFunction.fInterruptCount; thisIndex++,
thisInterrupt++) {
checkInterrupt = checkFunction.fInterruptAssignments;
for (checkIndex = 0; checkIndex < checkFunction.fInterruptCount;
checkIndex++, checkInterrupt++) {
if (thisInterrupt->fCanShare == TRUE &&
checkInterrupt->fCanShare == TRUE) {
continue;
}
if (thisInterrupt->fInterruptSocket ==
checkInterrupt->fInterruptSocket) {
if (fFirstPass == FALSE)
return        TRUE;
CreateResourceConflict
(checkFunction,
IOResourceConflict::kInterrupt);
doesConflict = TRUE;
}
}
}
return doesConflict;
}
void TIOResourceConflictResolver::CreateResourceConflict (
TIOResourceConflictResolver::FunctionPossibleAssignment &
functionInConflict, TIOResourceConflict::EresourceType
resourceConflicting)
{
TIOResourceConflict                            *newResourceInConflict;
TIOFunctionHardwareInterfaceIdentifier          *id =
::Copy(functionInConflict.fFunctionIdentifier);
newResourceInConflict = new TIOResourceConflict;
newResourceInConflict->SetResourceType(resourceConflicting);
newResourceInConflict->SetConflictType(fConflictType);
newResourceInConflict->SetResourceIndex(0);
newResourceInConflict->SetFunctionIdentifier(*id);
if (functionInConflict.fConflicts == NIL)
functionInConflict.fConflicts = new
TDequeOf<TIOResourceConflict>;
functionInConflict.fConflicts->Add(newResourceInConflict);
}
void TIOResourceConflictResolver::ConstructNewAssignment(
TIOResourceConflictResolver::FunctionPossibleAssignment &
thisFunction, TIOResourceConflictResolver::InterruptCollection
*interruptItem, TIOResourceConflictResolver::DMACollection *dmaItem,
TIOResourceConflictResolver::RegisterCollection *registerItem,
TIOResourceConflictResolver::MemoryCollection *memoryItem)
{
// 現在の可能な割り当てと値に基づいて
// 割り当てを構築する
//
TIOFunctionResourceAssignment *newAssignment = new
TIOFunctionResourceAssignment;
int i;
thisFunction.fConstructedAssignment = newAssignment;
if (interruptItem) {
TDequeOf<TIOFunctionResourceAssignment::
TInterruptAssignment> interruptDeque;
TIOFunctionResourceAssignment::TInterruptAssignment
*interruptAssignment;
for (i = 0; i < interruptItem->fInterruptCount; i++) {
interruptAssignment = new
TIOFunctionResourceAssignment::TInterruptAssignment;
interruptAssignment->SetSharability(interruptItem->
InterruptPossible[i].fCanShare);
interruptAssigment->SetInterruptSocket(thisFunction.
fInterruptAssignments[i].fInterruptSocket);
interruptAssignment->SetInterruptUsageMode(
interruptItem->fInterruptPossible[i].
fInterruptMode);
interruptAssignment->SetConstraintNumber(
interruptItem->fInterruptPossible[i].fConstraint);
interruptDeque.Add(interruptAssignment);
}
newAssignment->SetInterruptAssignment(interruptDeque);
interruptDeque.DeleteAll();
}
if (dmaItem) {
TDequeOf<TIOFunctionResourceAssignment::TDMAAssignment>
dmaDeque;
TIOFunctionResourceAssignment::TDMAAssignment
*dmaAssignment;
for (i = 0; i < dmaItem->fDMACount; i++) {
dmaAssignment = new
TIOFunctionResourceAssignment::
TDMAAssignment;
dmaAssignment->SetSharability(dmaItem->
fDMAPossible[i].fCanShare);
dmaAssignment->SetChannelNumber(thisFunction.
fDMAAssignments[i].fDMAChannel);
dmaAssignment->SetDMAUsageMode(dmaItem->
fDMAPossible[i].fDMAMode);
dmaAssignment->SetConstraintNumber(dmaItem->
fDMAPossible[i].fConstraint);
dmaDeque.Add(dmaAssignment);
}
newAssignment->SetDMAAssignment(dmaDeque);
dmaDeque.DeleteAll();
}
if (memoryItem) {
TDequeOf<TIOFunctionResourceAssignment::
TIOMemoryAssignment> memoryDeque;
TIOFunctionResourceAssignment::TIOMemoryAssignment
*memoryAssignment;
for (i = 0; i < memoryItem->fMemoryCount; i++) {
memoryAssignment = new
TIOFunctionResourceAssignment::
TIOMemoryAssignment;
memoryAssignment->SetSharability(memoryItem->
fMemoryPossible[i].fCanShare);
memoryAssignment->SetBaseAddress(thisFunction.
fMemoryAssignments[i].fBaseAddress);
memoryAssignment->SetLength(memoryItem->
fMemoryPossible[i].fLength);
memoryAssignment->
SetMemoryUsageMode(memoryItem->
fMemoryPossible[i].fMemoryMode);
memoryAssignment->SetConstraintNumber(memoryItem->
fMemoryPossible[i].fConstraint);
memoryDeque.Add(memoryAssignment);
}
newAssignment->SetMemoryAssignment(memoryDeque);
memoryDeque.DeleteAll();
}
if (registerItem) {
TDequeOf<TIOFunctionResourceAssignment::
TIORegisterAssignment> registerDeque;
TIOFunctionResourceAssignment::TIORegisterAssignment
*registerAssignment;
for (i = 0; i < registerItem->fRegisterCount; i++) {
registerAssignment = new
TIOFunctionResourceAssignment::
TIORegisterAssignment;
registerAssignment->SetSharability(registerItem->
fRegisterPossible[i].fCanShare);
registerAssignment->SetBaseAddress(thisFunction.
fRegisterAssignments[i].fBaseAddress);
registerAssignment->SetLength(registerItem->
fRegisterPossible[i].fLength);
registerAssignment->
SetConstraintNumber(registerItem->
fRegisterPossible[i].fConstraint);
registerAssignment->
SetRegisterUsageMode(registerItem->
fRegisterPossible[i].fRegisterMode);
registerDeque.Add(registerAssignment);
}
newAssignment->SetIOAssignment(registerDeque);
registerDeque.DeleteAll();
}
return;
}
Boolean TIOResourceConflictResolver::IsAssignmentWithinPlatformLimits(
TIOResourceConflictResolverDoer::FunctionPossibleAssignment &
function)
{
return (IsMemoryAssignmentWithinLimits(function))
&& (IsRegisterAssignmentWithinLimits(function))
&& (IsDMAAssignmentWithinLimits(function))
&& (IsInterruptAssignmentWithinLimits(function));
}
Boolean TIOResourceConflictResolverDoer::IsMemoryAssignmentWithinLimits(
TIOResourceConflictResolverDoer::FunctionPossibleAssignment &
function)
{
TIOFunctionResourceAssignment::TIOMemoryAssignment::BaseAddress
thisMemoryAddress, memoryToCheckAddress;
TIOFunctionResourceAssignment::TIOMemoryAssignment::BlockLength
thisMemoryLength, memoryToCheckLength;
MemoryAssignment          *thisMemory, *checkMemory;
Int                                thisIndex, checkIndex;
if (function.fMemoryCount == 0 || fMemoryLimitCount == 0) {
return TRUE;
}
thisMemory = function.fMemoryAssignments;
for (thisIndex = 0; thisIndex < function.fMemoryCount; thisIndex++,
thisMemory++) {
if (thisMemory->fIsCardMemory == FALSE)
continue;
thisMemoryAddress = thisMemory->fBaseAddress;
thisMemoryLength = thisMemory->fLength;
checkMemory = fMemoryLimit;
for (checkIndex = 0; checkIndex < fMemoryLimitCount;
checkIndex++, checkMemory++) {
if (checkMemory->fIsCardMemory == FALSE)
continue;
memoryToCheckAddress = checkMemory->fBaseAddress;
memoryToCheckLength = checkMemory->fLength;
if ((thisMemoryAddress >= memoryToCheckAddress
&& thisMemoryAddress <
memoryToCheckAddress+memoryToCheckLength)
&& (memoryToCheckAddress >= thisMemoryAddress
&& memoryToCheckAddress <
thisMemoryAddress+thisMemoryLength)) {
return TRUE;
} 
}
}
return FALSE;
}
Boolean TIOResourceConflictResolver::IsRegisterAssignmentWithinLimits(
TIOResourceConflictResolver::FunctionPossibleAssignment & function)
{
TIOFunctionResourceAssignment::TIORegisterAssignment::BaseAddress
thisRegisterAddress, registerToCheckAddress;
TIOFunctionResourceAssignment::TIORegisterAssignment::BlockLength
thisRegisterLength, registerToCheckLength;
RegisterAssignment            *thisRegister, *checkRegister;
Int                                  thisIndex, checkIndex;
if (function.fRegisterCount == 0 || fRegisterLimitCount == 0)  {
return TRUE;
}
thisRegister = function.fRegisterAssignments;
for (thisIndex = 0; thisIndex < function.fRegisterCount; thisIndex++,
thisRegister++) {
thisRegisterAddress = thisRegister->fBaseAddress;
thisRegisterLength = thisRegister->fLength;
checkRegister = fRegisterLimit;
for (checkIndex = 0; checkIndex < fRegisterLimitCount;
checkIndex++, checkRegister++) {
registerToCheckAddress = checkRegister->fBaseAddress;
registerToCheckLength = checkRegister->fLength;
if ((thisRegisterAddress >= registerToCheckAddress
&& thisRegisterAddress <
registerToCheckAddress+registerToCheckLength)
&& (registerToCheckAddress >= thisRegisterAddress
&& registerToCheckAddress <
thisRegisterAddress+thisRegisterLength)) {
return TRUE;
} 
}
}
return FALSE;
}
Boolean TIOResourceConflictResolver::IsDMAAssignmentWithinLimits(
TIOResourceConflictResolver::FunctionPossibleAssignment & function)
{
int                                        thisIndex, checkIndex;
DMAAssignment              *thisDMA;
DMAPossible        *checkDMA;
if (function.fDMACount == 0 || fDMALimitCount == 0) {
return        TRUE;
}
thisDMA = function.fDMAAssignments;
for (thisIndex = 0; thisIndex < function.fDMACount; thisIndex++,
thisDMA++) {
checkDMA = fDMALimit;
for (checkIndex = 0; checkIndex < fDMALimitCount; checkIndex++,
checkDMA++) {
if (thisDMA->fDMAChannel <=
checkDMA->fLowerDMAChannel
&& thisDMA->fDMAChannel >=
checkDMA->fUpperDMAChannel) {
return TRUE;
}
}
}
return FALSE;
}
Boolean TIOResourceConflictResolver::IsInterruptAssignmentWithinLimits(
TIOResourceConflictResolver::FunctionPossibleAssignment & function)
{
int                                          thisIndex, checkIndex;
InterruptAssignment            *thisInterrupt;
InterruptPossible                                    *checkInterrupt;
if (function.fInterruptCount == 0 || fInterruptLimitCount == 0) {
return TRUE;
}
thisInterrupt = function.fInterruptAssignments;
for (thisIndex = 0; thisIndex < function.fInterruptCount; thisIndex++,
thisInterrupt++) {
checkInterrupt = fInterruptLimit;
for (checkIndex = 0; checkIndex < fInterruptLimitCount;
checkIndex++, checkInterrupt++) {
if (thisInterrupt->fInterruptSocket >=
checkInterrupt->fLowerInterruptSocket
&& thisInterrupt->fInterruptSocket <=
checkInterrupt->fUpperInterruptSocket) {
return TRUE;
}
}
}
return FALSE;
}
void TIOResourceConflictResolver::UpdateCardsFromFunctionCollection()
{
TDequeOf<TIOFunctionResourceUsage>                  functionDeque;
TIOFunctionResourceUsage                                  *function;
TSequenceOfIterator<TIOFunctionResourceUsage>        *functionIterator;
TIOCardResourceUsage                                        *card;
TSequenceOfIterator<TIOCardResourceUsage>              *cardIterator;
TArrayOf<FunctionPossibleAssignment>                orderedFunctions;
Int                                                      functionIndex;
FunctionPossibleAssignment                              *newFunction;
//
// 機能コレクションを正しい順序で再構築する
//
orderedFunctions.SetAutoGrowFlag(TRUE);
for (functionIndex = 0; functionIndex < fFunctionCount; functionIndex++) 
orderedFunctions.AtPut(fFunctions[functionIndex].fFunctionIndex,
&fFunctions[functionIndex]);
cardIterator = fCard.CreateSequenceIterator();
for (functionIndex = 0, card = cardIterator->First();card != NIL; card =
cardIterator->Next()) {
card->GetFunctionResourceUsage(functionDeque);
functionIterator = functionDeque.CreateSequenceIterator();
for (function = functionIterator->First(); function != NIL; function =
functionIterator->Next()) {
if (functionIndex >= fFunctionCount) 
// Throws Exception - Internal Error
throw        (TConflictResolverException(
TConflictResolverException::kInternalError));
newFunction = orderedFunctions.At(functionIndex);
if (newFunction == NIL) {
throw        newFunction;
}
if (newFunction->fHaveAssignment &&
newFunction->fConstructedAssignment) {
function->SetAssignment(*newFunction->
fConstructedAssignment);
} else if (newFunction->fConflicts) {
function->SetResourceConflicts(*newFunction->
fConflicts);
}
if (newFunction->fConflicts) {
newFunction->fConflicts->DeleteAll();
delete newFunction->fConflicts;
}
if (newFunction->fConstructedAssignment)
delete newFunction->fConstructedAssignment;
if (newFunction->fDMAChannelNumbers)
delete newFunction->fDMAChannelNumbers;
if (newFunction->fInterruptSocketNumbers)
delete newFunction->fInterruptSocketNumbers;
if (newFunction->fRegisterBaseAddresses)
delete newFunction->fRegisterBaseAddresses;
if (newFunction->fMemoryBaseAddresses)
delete newFunction->fMemoryBaseAddresses;
RemoveConstructedAssignments(*newFunction);
delete newFunction->fFunctionIdentifier;
functionIndex++;
}
card->SetFunctionResourceUsage(functionDeque);
delete functionIterator;
functionDeque.DeleteAll();
}
if (functionIndex != fFunctionCount) {
// 例外をスローする
throw (TconflictResolverException(
TconflictResolverException::kInternalError));
}
delete cardIterator;
delete        fFunctions;
fFunctionCount = 0;
}
void TIOResourceConflictResolver::RemoveConstructedAssignments(
TIOResourceConflictResolver::FunctionPossibleAssignment & function)
{
if (function.fMemoryAssignments) {
function.fMemoryCount = 0;
delete function.fMemoryAssignments;
function.fMemoryAssignments = NIL;
}
if (function.fRegisterAssignments) {
function.fRegisterCount = 0;
delete function.fRegisterAssignments;
function.fRegisterAssignments = NIL;
}
if (function.fDMAAssignments) {
function.fDMACount = 0;
delete function.fDMAAssignments;
function.fDMAAssignments = NIL;
}
if (function.fInterruptAssignments) {
function.fInterruptCount = 0;
delete function.fInterruptAssignments;
function.fInterruptAssignments = NIL;
}
}
【０１９３】
3.  リソースロッククラス
TIOFunctionResourceUsageクラス１１０４は、本発明の原理によれば、リソース割り当てが行われた後、共有リソースへのアクセスを制御するために使用できるクラスを、さらに含んでいる。このクラスはTIOResourceLockEntryクラス１１０６であり、これは入出力機能のための無競合リソース割り当てを取り出すために使用されるGetResourceAssignment()メソッドと、割り当てられたリソースにアクセスするために使用されるAcquire()メンバ関数を含んでいる。Acquire()メソッドは、クラス１１０４から作成されたIOFunctionResourceUsageオブジェクトに関して上述したように、プライベートメソッド(AcquireResourceLock())をコールし、このメソッドは、IOFunctionResourceUsageオブジェクト内のセマフォロック（タイプがTRecoverableSemaphoreの）を、対応する入出力機能に割り当てられたリソースに対して獲得することを試みる。Acquire()メソッドは、クライアントがリソースへの排他的アクセスを要求しているか、共有アクセスを要求しているかを示すパラメータ(EAccessMode)を含んでいる。ロックは一度だけ獲得され、ロックが獲得される前にあらかじめ決めた時間期間が経過すると、例外がスローされる。この例外は、ロックの保有者がだれであるかを示している。Acquire()メソッドのコードは次の通りである。
【０１９４】
void Acquire (const TIOFunctionHardwareInterfaceIdentifier& function,
const EAccessMode mode, const TTime& maximumWait)
{
TIOFunctionResourceUsage        *functionItem;
if ((functionItem = FindFunctionByID (id)) == NIL) {
throw (TConflictResolverException
(TConflictResolverException::kFunctionNotRegistered));
return;
}
functionItem->AcquireResourceLock(mode, maximumWait);
}
【０１９５】
従って、入出力機能のためのリソースにアクセスするには、クライアントはTIOResourceLockEntryクラス１１０６からIOResourceLockEntryオブジェクトをインスタンス生成し、そのオブジェクトのAcquire()メソッドをコールする。ここで注意すべきことは、IOResourceLockEntryオブジェクトを単独でインスタンス生成しても、ロックが暗黙のうちに獲得されないことである。しかし、IOResourceLockEntryオブジェクトを破壊すると、IOResourceLockEntryオブジェクトによって獲得されたリソースは暗黙のうちに解放されることになる。
【０１９６】
IOResourceLockEntryクラス１１０６は、入出力機能のためのリソース割り当てを、IOFunctionResourceUsageオブジェクトを通して取り出すGetResourceAssignment()メソッドも含んでいる。GetResourceAssignment()メソッドは、リソースロックがAcquire()メソッドによって獲得された後コールすることができ、入出力機能のための無競合リソース割り当てを取得する。これらのリソースを使用できるのは、Acquire()メソッドをコールするタスクによってか、あるいはAddInterruptHandlerReference()メソッドとRemoveInterruptHandlerReference()メソッドによって入出力リソース競合リゾルバに登録されていた割り込みハンドラによってだけである。リソースが入出力機能に割り当てられていなければ、GetResourceAssignment()メソッドは例外をスローする。GetResourceAssignment()メソッドは次のような形式になっている。
【０１９７】
void GetResourceAssignment (
TIOFunctionResourceAssignment& function) const;
【０１９８】
上述したように、リソースは、拡張カードが物理的にインストールされていない場合であっても、拡張カード上の入出力機能に割り当てることが可能である。対応するデバイスドライバは、ハードウェアが拡張スロットに物理的にインストールされていることを、リソースを使用する前に確かめなければならない。GetResourceAssignment()メソッドは、TIOFunctionResourceAssignmentクラス１１０８から作成されたオブジェクトからリソース割り当てを取り出し、このオブジェクトは入出力機能のために作成された無競合リソース割り当てを表している。IOFunctionResourceAssignmentオブジェクトは、TIOFunctionResourceAssignmentクラス１１０８からインスタンス生成され、メモリ、入出力レジスタ、割り込みソケット、およびDMAチャネル割り当てなどの、リソース割り当て情報をカプセル化している。このクラスは、いくつかのネストされたクラスを含み、種々の割り当てをカプセル化している。これらのネストされたクラスは図１５を参照して詳しく説明する。リソース割り当てを取り出すために、デバイスドライバクライアントはIOResourceLockEntryオブジェクトを作成し、その作成されたIOResourceLockEntryオブジェクトを通してIOFunctionResourceAssignmentオブジェクトを取り出す。TIOFunctionResourceAssignmentクラス１１０８は単態クラスであるので、開発者によってサブクラス化されないのが通常である。
【０１９９】
TIOFunctionResourceAssignmentクラス１１０８は、特定リソース割り当てのオブジェクトからメモリレンジを読み取るGetMemoryAssignment()メンバ関数と、そのメモリレンジをリソース割り当てのオブジェクトに書き込むSetMemoryAssignment()メンバ関数を含んでいる。GetIOAssignment()メンバ関数とSetIOAssignment()メンバ関数は、それぞれこの割り当てのための入出力レンジをオブジェクトに読み書きする。
【０２００】
GenerateInterrupt()メソッドは、対応する入出力機能がプロセッサに割り込みを引き起こすと第１のブール値（例えば、TRUE）を返し、入出力機能がプロセッサに割り込みを引き起こしていなければ第２のブール値（例えば、FALSE）を返す。GetInterruptAssignment()は、この割り当てのための割り込みソケットに関する情報を返し、SetInterruptAssignment()メソッドはこの割り当てのための割り込みソケットに関する情報を書き出す。
【０２０１】
NeedsDMAChannel()メソッドは、対応する拡張カード上の入出力機能がDMAチャネルを要求していれば第１のブール値（例えば、TRUE）を返し、そうでなければ第２のブール値（例えば、FALSE）を返す。GetDMAAssignment()メソッドは、特定のリソース割り当てのためのDMAチャネルに関する情報を返し、SetDMAAssignment()は、その特定リソース割り当てのためのDMAチャネルに関する情報を書き出す。
【０２０２】
IOResourceLockEntryオブジェクトは、入出力機能に割り当てられたリソースを、その機能が止まったとき管理することも受け持っている。この管理機能を実行するために、デバイスドライバクライアントはTinterruptHandlerReferenceをIOResourceLockEntryオブジェクトに登録し、対応する入出力機能に割り当てられたリソースを、機能が終了したときオブジェクトが自動的に解放できるようにする。TIOResourceLockEntryクラスは単態クラスであるので、開発者によってサブクラス化されないのが通常である。TIOResourceLockEntryクラス１１０６は、AddInterruptHandlerReference()メソッドによって以前に登録された割り込みハンドラレファレンスの登録を解除するRemoveInterruptHandlerReference()メソッドも含んでいる。AddInterruptHandlerReference()メソッドは次のような形式になっている。
【０２０３】
void AddInterruptHandlerReference (const TinterruptHandlerReference&
interruptHandler);
【０２０４】
4.  リソース競合オブジェクトとリソース割り当てクラス
本発明の原理によれば、TIOResourceConflictクラス１１１０は、特定の入出力機能にそのリソース要求を割り当てることができなかった理由を説明した情報をカプセル化している。TIOResourceConflictクラス１１１０は、どのリソースが競合しているリソースであるか、どの割り当て期間が競合している割り当て期間であるか（現行ブートであるか、次回ブートであるか）およびリソースコレクション中の競合リソースのインデックスといった情報をカプセル化している。入出力機能のための無競合割り当てを作成している途中でリソース割り当ての競合が見つかると、リソース競合リゾルバはTIOResourceConflictクラス１１１０からIOResourceConflictオブジェクトをインスタンス生成する。競合が除去され、無競合リソース割り当てが作られると、インスタンス生成されたIOResourceConflictオブジェクトは、その後でリソース競合リゾルバオブジェクトによって内部的に削除される。TIOResourceConflictクラスは単態クラスであるので、開発者によってサブクラス化されないのが通常である。
【０２０５】
TIOResourceConflictクラス１１１０は、代表的なコンストラクタとデストラクタメンバ関数を含んでいるほかに、複数の固有メンバ関数も含んでいる。例えば、TIOResourceConflictクラス１１１０は列挙型リソースタイプ(kMemoryRange, kIORange, kInterruptまたはkDMA)をストアしているプライベート属性を定義している。GetResourceType()メンバ関数はリソースのタイプを読み取り、そのタイプは競合が特定タイプのリソースに存在することを示している。SetResourceType()メンバ関数はリソースのタイプをプライベート属性に書き込む。
【０２０６】
TIOResourceConflictクラス１１１０は、列挙型競合期間指定子(kConflictNowまたはkConflictAfterBoot)をストアするプライベート属性も定義している。GetConflictType()メンバ関数は競合のタイプをプライベート属性から読み取り、競合が現行ブート期間で起こっていれば第１のタイプ(kConflictNow)を返し、競合がこのブート期間後も残存していれば第２のタイプ(kConflictAfterBoot)を返す。SetConflictType()メンバ関数は競合のタイプをプライベート属性に書き出す。
【０２０７】
TIOResourceConflictクラス１１１０のGetResourceIndex()メンバ関数は、競合がそこで発生したリソースのリソースインデックスをプライベート属性から読み取り（インデックスはリソースコレクションの中の特定リソースを示している）、他方、SetResourceIndex()メンバ関数はそのインデックスをプライベート属性に書き込む。このインデックスを使用すると、リソース競合オブジェクトを処理しているメソッドは、どのリソースが競合を引き起こしたかを知ることができる。
【０２０８】
SetFunctionIdentifier()メンバ関数は、競合している入出力機能のTHardwareInterfaceIdentifier値をプライベート属性に書き込み、競合を引き起こした機能を示すようにしている。
【０２０９】
TPossibleIOResourceAssignmentクラス１１１２は、入出力機能用のリソース割り当てで可能な選択（および制約）をカプセル化している。可能な選択と制約は、上述したように、ボード自体から（自動構成拡張ボードの場合）、またはデータベースから（マニュアル構成拡張ボードの場合）取得される。
【０２１０】
TPossibleIOResourceAssignmentクラス１１１２からインスタンス生成されたPossibleIOResourceAssignmentオブジェクトはリソース割り当て情報をカプセル化しているが、この中にはメモリレンジ、入出力レジスタレンジ、割り込みソケットまたは要求ライン、割り込み優先レベルおよびDMAチャネルの可能な割り当てが含まれているが、これらに限定されるものではない。TPossibleIOResourceAssignmentクラス１１１２は単態クラスであるので、開発者によってサブクラス化されないのが通常である。これはいくつかの、ネストされた制約クラスを含んでいるが、これらは、図１６を参照して以下で詳しく説明されている。
【０２１１】
TPossibleIOResourceAssignmentクラス１１１２は複数のメンバ関数を含んでおり、この中には代表的なコンストラクタとデストラクタ関数が含まれている。TPossibleIOResourceAssignmentクラス１１１２は、ネストされた制約オブジェクトにカプセル化されている制約を取得し、設定するための複数のメソッドも含んでいる。これらのメンバ関数の中には、それぞれがメモリ使用の制約をネストされたIOMemoryConstraintオブジェクトに読み書きするためのGetMemoryConstraints()メソッドとSetMemoryConstraints()メソッドが含まれている。
【０２１２】
同様に、GetIOConstraints()メソッドとSetIOConstraints()メソッドは、それぞれが入出力レジスタ使用の制約を、ネストされたIORegisterConstraintオブジェクトのコレクションに読み書きする。
【０２１３】
GetInterruptConstraints()メソッドとSetInterruptConstraints()メソッドは、それぞれが割り込みソケット使用の制約を、IOInterruptConstraintオブジェクトに読み書きし、他方、GetDMAConstraints()メソッドとSetDMAConstraints()メソッドは、それぞれがDMAチャネル使用の制約を、IODMAConstraintオブジェクトのコレクションに読み書きする。
【０２１４】
次に、図１５を参照して説明すると、競合リゾルバフレームワークは、リソース割り当てクラス群をさらに含んでいる。これらのクラスは、図１１を参照して上述したTIOFunctionResourceAssignmentクラス１５０８内にネストされたクラスを含んでいる。ネストされたクラスには、TInterruptAssignmentクラス１５０２、TIOMemoryAssignmentクラス１５００、TIOMemoryUsageModeクラス１５０６、TIORegisterAssignmentクラス１５１２、TDMAAssignmentクラス１５１０およびTDMAUsageModeクラス１５１４が含まれている。
【０２１５】
TInterruptAssignmentクラス１５０２は、個別的入出力機能に割り当てられた割り込みソケットに関する情報をカプセル化している。TInterruptAssignmentクラス１５０２は単態クラスであるので、開発者によってサブクラス化されないのが通常であり、入出力機能の割り込みソケット番号をプライベート属性から読み取るGetInterruptSocket()メソッドおよび入出力機能の割り込みソケット番号をプライベート属性に書き込むSetInterruptSocket()メソッドなどの、複数の固有メンバ関数を含んでいる。
GetParentInterruptHandlerReference()メソッドとSet ParentInterruptHnadlerReference()メソッドは、それぞれ入出力機能の親割り込みハンドラをプライベート属性に読み書きする。
【０２１６】
GetInterruptUsageMode()メソッドとSetInterruptUsageMode()メソッドは、それぞれ入出力機能によって使用される割り込みソケットの使用状況モードを、プライベート属性に読み書きする。IsSharable()メソッドは、入出力機能によって使用される割り込みソケットが他の入出力機能によって共有可能であれば第１の値（例えば、ブール値のTRUE）を返し、SetSharability()メソッドは入出力機能の共有可能性をプライベート属性に書き込む。
【０２１７】
TInterruptAssignmentクラス１５０２は、特定の割り込みソケットの特性に関する情報をカプセル化しているTInterruptUsageModeクラス１５０４と関連付けられている。TInterruptUsageModeクラス１５０４は単態クラスであるので、開発者によってサブクラス化されないのが通常である。
【０２１８】
TInterruptUsageModeクラス１５０４は、GetSocketType()メソッドを含む複数のメンバ関数も含んでいる。GetSocketType()メソッドは、ソケットの列挙型ソケットタイプをプライベート属性から読み取り、ソケットがエッジタイプのソケットであれば第１の値(kEdge)を返し、ソケットがレベルタイプのソケットであれば第２の異なる値(kLevel)を返す。SetSocketType()メソッドはソケットタイプをプライベート属性に書き出す。
【０２１９】
GetSocketState()メソッドはソケット状態をプライベート属性から読み取り、レベルハイまたはエッジハイのタイプときは第１の値(kHigh)を返し、ソケットがレベルローまたはエッジローのときは第２の異なる値(kLow)を返す。SetSocketState()メソッドはソケット状態をプライベート属性に書き出す。
【０２２０】
TIOMemoryAssignmentクラス１５００は、個別的入出力機能に割り当てられたメモリレンジを表しており、TIOFunctionResourceAssignmentクラス１５０８の内側にネストされている。TIOMemoryAssignmentクラス１５００は単態クラスであるので、開発者によってサブクラス化されないのが通常である。TIOMemoryAssignmentクラス１５００はGetBaseAddress()メソッドを含む複数のメンバ関数を含んでいる。GetBaseAddress()メソッドは、割り当てられたメモリレンジのベース（基底）アドレスをプライベート属性から読み取り、SetBaseAddress()メソッドはメモリレンジのベースアドレスを書き出す。GetLength()メソッドは割り当てられたメモリレンジの長さを読み取り、SetLength()メソッドは割り当てられたメモリレンジの長さをプライベート属性に書き込む。GetMemoryUsageMode()メソッドとSetMemoryUsageMode()メソッドは、それぞれ割り当てられたメモリレンジの使用状況モードをプライベート属性に読み書きする。
【０２２１】
IsSharable()メソッドは、入出力機能によって使用されるメモリレンジが他の入出力機能によって共有可能であれば第１の値（例えば、ブール値のTRUE）を返す。SetSharability()メソッドは入出力機能の共有可能性を書き出す。
【０２２２】
TIOMemoryAssignmentクラス１５００はTIOMemoryUsageModeクラス１５０６と関連付けられている。TIOMemoryUsageModeクラス１５０６は、特定のメモリレンジの使用状況に関する情報をカプセル化している。TIOMemoryUsageModeクラス１５０６は単態クラスであるので、開発者によってサブクラス化されないのが通常である。
【０２２３】
TIOMemoryUsageModeクラス１５０６はGetAccessMode()メソッドを含んでいる。このメソッドは、メモリレンジのアクセスモードをプライベート属性から読み取り、メモリがリードオンリメモリ(ROM)であれば第１の値(kReadOnly)を返し、メモリがランダムアクセスメモリ(RAM)であれば第２の異なる値(kWritable)を返す。SetAccessMode()メソッドはメモリレンジのアクセスモードを書き出す。
【０２２４】
GetAccessSize()メソッドはメモリレンジのアクセスサイズをプライベート属性から読み取り、メモリレンジが8ビット、16ビット、8ビットと16ビットの両方、または32ビットメモリレンジとしてアクセス可能かどうかを示す標識を返す。SetAccessSize()メソッドはメモリレンジのアクセスサイズを書き出す。
【０２２５】
TIORegisterAssignmentクラス１５１２は個別的入出力機能に割り当てられた入出力レジスタレンジを表し、TIOFunctionResourceAssignmentクラス１５０８の内側にネストされた単態クラスである。TIORegisterAssignmentクラス１５１２は代表的にコンストラクタとデストラクタメンバ関数を含むほかに、複数の固有メンバ関数を含んでいる。例えば、GetBaseAddress()メソッドとSetBaseAddress()メソッドは、それぞれ特定入出力レジスタレンジのベースアドレスを読み書きする。GetLength()メソッドは入出力レジスタレンジの長さを読み取り、SetLength()メソッドは入出力レジスタレンジの長さを書き込む。IsSharable()メソッドは、入出力機能によって使用される入出力レジスタレンジが他の入出力機能によって共有可能であれば第１の値（例えば、ブール値のTRUE）を返し、SetSharability()メソッドは入出力機能の共有可能性を書き込む。
【０２２６】
TDMAAssignmentクラス１５１０は、個別的入出力機能に割り当てられたDMAチャネルに関する情報をカプセル化している。TDMAAssignmentクラス１５１０は、TIOFunctionResourceAssignmentクラス１５０８の内側にネストされた単態クラスである。TDMAAssignmentクラス１５１０は開発者によってサブクラス化されないのが通常である。TDMAAssignmentクラス１５１０は複数の固有メンバ関数を含んでいる。例えば、GetChannelReference()メソッドとSetChannelReference()メソッドは、それぞれがDMAチャネルハンドルへのレファレンス（参照）を読み書きする。GetDMAUsageMode()メソッドとSetDMAUsageMode()メソッドは、DMAチャネルの使用状況モードをプライベート属性から読み取り、使用状況をプライベート属性に書き込む。IsSharable()メソッドは、入出力機能によって使用されるDMAチャネルが他の入出力機能によって共有可能であれば第１の値（例えば、ブール値のTRUE）を返し、SetSharability()メソッドは入出力機能の共有可能性をプライベート属性に書き込む。
【０２２７】
TDMAAssignmentクラス１５１０は、特定のDMAチャネルの使用状況に関する情報をカプセル化しているTDMAUsageMode()クラス１５１４と関連付けられている。TDMAUsageMode()クラス１５１４は多態クラスであるため、開発者によってサブクラス化されないのが通常であり、単一データ転送単位のサイズをプライベート属性から読み取り、8ビット、16ビット、32ビットまたは8/16ビットの転送が行われているかを示す、あらかじめ決めた値をもつパラメータを返すGetTransferSize()メソッドを含んでいる。SetTransferSize()メソッドは転送サイズを書き込む。
【０２２８】
クラス１５１４のGetCountingMode()メソッドはデータ転送単位をカウントするときのモードを読み取る。このメソッドは、カウントがバイト単位で行われていれば第１の値(kCountByByte)を返し、カウントがワード単位で行われていれば第２の異なる値(kCountByWord)を返す。同様に、TDMAUsageMode()クラス１５１４のSetCountingMode()メソッドは転送単位をカウントするときのモードをプライベート属性に書き込む。GetTransferSpeed()メソッドは、転送のためのタイミング情報をプライベート属性から読み取り、入出力機能がISA互換タイミング、タイプAタイミング、タイプＢタイミング、タイプＣタイミングまたはタイプＦタイミングを、それぞれ使用しているかどうかを示す列挙型標識（例えば、kISACompatible, kTypeA, kTypeB, kTypeCまたはkTypeF）を返す。SetTransferSpeed()メソッドは転送のためのタイミング情報をプライベート属性に書き込む。
【０２２９】
GetTransferMode()メソッドは、入出力機能によって使用されている転送モードを読み取る。GetTransferMode()メソッドは、入出力機能がシングル転送、ブロック転送またはデマンドモード転送を使用していれば、それぞれ入出力機能によって使用されている転送モードを示すために列挙型値（例えば、kSingle, kBlockまたはkDemand）を返す。対応するSetTransferMode()メソッドは、入出力機能の転送モードをプライベート属性に書き込む。GetBusAccessMode()メソッドは、入出力機能がバスマスタ(bus master)であれば第１の列挙型値(kMaster)をプライベート属性から返し、入出力機能がバスマスタでなければ第２の異なる値(kSlave)を返す。SetBusAccessMode()メソッドは入出力機能のマスタまたはスレーブ属性をプライベート属性に書き込む。
【０２３０】
次に、図１６を参照して説明すると、競合リゾルバフレームワークは、図１１を参照して上述したTPossibleIOResourceAssignmentクラス１６０８（クラス１１１０）内にネストされている複数の制約クラスを含んでいる。これらのクラスも、図１５を参照して上述したTIOMemoryUsageMode()クラス１６０６、TinterruptUsageMode()クラス１６１０およびTDMAUsageMode()クラス６１６と関連付けられている。
【０２３１】
図１６に示すように、TPossibleIOResourceAssignmentクラス１６０８はネストされた制約クラスを持ち、その中には、TIOMemoryConstraintクラス１６００、TIORegisterConstraintクラス１６０２、TInterruptConstraintクラス１６１２およびTDMAConstraintクラス１６１４が含まれている。
【０２３２】
TIOMemoryConstraintクラス１６００は、個別的入出力機能によって使用されているメモリロケーションと長さを含むメモリレンジの使用の制約を表している。TIOMemoryConstraintクラスは単態クラスであるので、開発者によってサブクラス化されないのが通常である。TIOMemoryConstraintクラス１６００は複数のメンバ関数を含んでおり、その中には、それぞれメモリレンジの長さをプライベート属性に読み書きするGetLength()メソッドとSetLength()メソッドが含まれている。
【０２３３】
GetLowerBaseAddress()メソッドは、入出力機能に割り当てが可能であるメモリブロックの最下位ベースアドレスを読み取り、SetLowerBaseAddress()メソッドは、入出力機能に割り当てが可能であるメモリブロックの最下位ベースアドレスをプライベート属性に書き込む。
【０２３４】
同様に、GetUpperBaseAddress()メソッドは、入出力機能に割り当てが可能であるメモリブロックの最高位ベースアドレスを読み取り、SetUpperBaseAddress()メソッドは、入出力機能に割り当てが可能であるメモリブロックの最高位ベースアドレスをプライベート属性に書き込む。
【０２３５】
GetBaseIncrement()メソッドは、ベースアドレスのあらかじめ決めたインクリメント値を読み取り、SetBaseIncrement()メソッドは、ベースアドレスのベースアドレスインクリメント値をプライベート属性に書き込む。
【０２３６】
IsSharable()メソッドは、入出力機能によって使用されているメモリレンジが他の入出力機能によって共有可能であれば第１の値（例えば、ブール値のTRUE）をプライベート属性から返し、SetSharability()メソッドは、入出力機能の共有可能性値をプライベート属性に書き込む。同様に、GetMemoryUsageMode()メソッドはメモリレンジの使用状況モードを読み取り、SetMemoryUsageMode()メソッドはメモリレンジの使用状況モードをプライベート属性に書き込む。
【０２３７】
TIORegisterConstraintクラス１６０２は、個別的入出力機能による入出力レジスタレンジの使用の制約を表している。TIORegisterConstraintクラス１６０２は、TPossibleIOResourceAssignmentクラス１６０８の内側にネストされた単態クラスである。
【０２３８】
TIORegisterConstraintクラス１６０２は、入出力レジスタレンジの制約を指定するための複数のメンバ関数を含み、その中には、入出力レンジの長さをプライベート属性から読み取るGetLength()メソッドと入出力レンジの長さをプライベート属性に書き込むSetLength()メソッドが含まれている。GetLowerBaseAddress()メソッドとGetUpperBaseAddress()メソッドは、それぞれ入出力機能に割り当てることができる入出力ブロックの最下位と最高位ベースアドレスをプライベート属性から読み取る。SetLowerBaseAddress()メソッドとSetUpperBaseAddress()メソッドは、それぞれ入出力機能に割り当てることができる入出力ブロックの最下位と最高位ベースアドレスをプライベート属性に書き込む。
【０２３９】
クラス１６０２は、それぞれベースアドレスのベースインクリメント値を別のプライベート属性に読み書きするGetBaseIncrement()メソッドとSetBaseIncrement()メソッドを、さらに含んでいる。IsSharable()メソッドは、入出力機能によって使用されている入出力レンジが他の入出力機能によって共有可能であれば第１の値（例えば、ブール値のTRUE）を返し、SetSharability()メソッドは入出力機能の共有可能性をプライベート属性に書き込む。
【０２４０】
TInterruptConstraintクラス１６１２は、個別的入出力機能による割り込みソケットの使用の制約に関する情報をカプセル化している。TInterruptConstraintクラス１６１２はTPossibleIOResourceAssignmentクラス１６０８の内側にネストされた単態クラスであり、開発者によってサブクラス化されないのが通常である。
【０２４１】
TInterruptConstraintクラス１６１２は、入出力機能の親割り込みハンドラへのレファレンス（参照）を読み取るGetParentInterruptHandlerReference()メソッドと入出力機能の親割り込みハンドラへのレファレンスをプライベート属性に書き込むSetParentInterruptHandlerReference()メソッドを含んでいる。
【０２４２】
GetLowerInterruptSocket()メソッドは、入出力機能に割り当てることができる最低割り込みソケット番号を読み取り、SetLowerInterruptSocket()メソッドは、入出力機能に割り当てることができる最低割り込みソケット番号を書き込む。同様に、GetUpperInterruptSocket()メソッドは、入出力機能に割り当てることができる最高割り込みソケット番号を読み取り、SetUpperInterruptSocket()メソッドは、入出力機能に割り当てることができる最高割り込みソケット番号を書き込む。
【０２４３】
IsSharable()メソッドは、ソケットが共有可能であれば第１の値（例えばブール値のTRUE）を返し、ソケットが共有不能であれば第２の異なる値（例えば、ブール値のFALSE）を返す。SetSharability()メソッドは、ソケットの共有可能性をプライベート属性に書き込む。GetInterruptUsageMode()メソッドは、入出力機能によって使用されている割り込みソケットの使用状況モードを読み取り、SetInterruptUsageMode()メソッドは、入出力機能によって使用されている割り込みソケットの使用状況モードを書き込む。
【０２４４】
TDMAConstraintクラス１６１４は、個別的入出力機能によって使用されているDMAチャネルに関する情報をカプセル化している。TDMAConstraintクラス１６１４は単態クラスであり、TPossibleIOResourceAssignmentクラス１６０８の内側にネストされている。TDMAConstraintクラス１６１４は開発者によってサブクラス化されないのが通常である。
【０２４５】
TDMAConstraintクラス１６１４は複数のメンバ関数を含んでおり、この中には、DMAチャネルハンドルへのレファレンスをプライベート属性から読み取るGetChannelReference()メソッドとDMAチャネルハンドルへのレファレンスをプライベート属性に書き込むSetChannelReference()メソッドを含まれている。
【０２４６】
IsSharable()メソッドは、入出力機能に使用されているDMAチャネルが他の入出力機能によって共有可能であれば第１の値（例えば、ブール値のTRUE）を返し、SetSharability()メソッドは入出力機能の共有可能性を書き込む。GetDMAUsageMode()は入出力機能によって使用されているDMAチャネルの使用状況モードを読み取り、SetDMAUsageMode()は入出力機能によって使用されているDMAチャネルの使用状況モードを書き込む。
【０２４７】
6.  マニュアルモジュールフレームワークのクラス
図１７、１８Ａ、１８Ｂおよび１９は、マニュアルモジュールフレームワークを形成しているクラス群を示している。マニュアルモジュールフレームワークは、コンピュータシステムのマニュアル構成拡張カードとマザーボードの一般的動作を表しているクラス群から提供されている。マニュアルモジュールフレームワークのクラスは、特に、マニュアル構成拡張カードとマザーボードの両方の構成が、あるブートオペレーションから次のブートオペレーションまで持続されることを保証する。ブートオペレーション期間に構成情報をハードウェア構成データベースから取り出すのを受け持っているのが、このフレームワークである。
【０２４８】
概要を説明すると、ブートオペレーション期間に、マニュアルモジュールフレームワークのクラスは、コンピュータシステムにインストールされているマザーボードとマニュアル拡張カードのための構成レコーダオブジェクトをインスタンス生成するのを支援している。より具体的には、ブーティングシステムはマザーボードとマニュアル拡張カードの構成レコーダオブジェクトをインスタンス生成するTManualRecorderRegistryオブジェクトをインスタンス生成する。
【０２４９】
マニュアルモジュールフレームワークは、上述したように、新しい拡張カードを、コンピュータビューアを使用してインストールするのを支援するクラスも含んでいる。マニュアルモジュールフレームワークは、リソース競合リゾルバオブジェクト、およびマザーボードとマニュアル拡張カードに必要なリソースを、構成オプションデータベースから取り出す構成オプションリトリーバオブジェクトと通信するTManualIOCardオブジェクトを用意している。
【０２５０】
次に、図１７を参照して説明すると、マニュアルモジュールフレームワークは、CreateModuleMaker()メソッド、IsRoot()メソッド、NeedsRecognition()メソッドおよびInitiateNestedRecognizer()メソッドを有するTManualConfigurationRecorderクラス１７００を含んでいる。TMotherboardConfigurationRecorderクラス１７０２はTManualConfigurationRecorderクラス１７００から継承しており（つまり、TManualConfigurationRecorderクラスはTMotherboardConfigurationRecorderクラスのサブクラスである）、従って、TManualConfigurationRecorderクラス１７００のメンバ関数の各々を含んでいる。TMotherboardConfigurationRecorderクラス１７０２は、GetExpansionBusRecognizers()メソッド、DoInititateNestedRecognizers()メソッド、RegisterPossibleAssignments()メソッドおよびProduceConflictAssignments()メソッドも含んでいる。
【０２５１】
TManualConfigurationRecorderクラス１７００は、リソース競合リゾルバオブジェクトによって生成された無競合リソース割り当てを、ハードウェア構成データベースに記録する構成レコーダを作成する。マニュアル構成可能コンポーネントの構成レコーダオブジェクトは、コンポーネントのハードウェアモジュールオブジェクトを作成することを受け持ち、このオブジェクトはコンポーネントのハードウェア記述をカプセル化している。レコーダオブジェクトは、コンポーネント上の、コネクタの各々のハードウェア識別子オブジェクトも作成し、そのハードウェア識別子オブジェクトをハードウェアモジュールに追加する。
【０２５２】
TManualConfigurationRecorderオブジェクトはTManualConfigurationRecorderクラス１７００からインスタンス生成され、マニュアルISAカードやローカルバスカードなどの、マニュアルコンポーネントの構成レコーダオブジェクトを構築するために使用される。TManualConfigurationRecorderクラス１７００は抽象基底クラスであるので、個別的マニュアル構成可能入出力拡張カードの特定構成レコーダオブジェクトが、そのクラスからインスタンス生成されるようにサブクラス化されていなければならない。特定のManualConfigurationRecorderオブジェクトはコンピュータビューアによってインストール期間中にインスタンス生成される。ネストされたレコグナイザをシステムブートオペレーション期間に生起する必要のある、マニュアルカードのレコードオブジェクト（SCSIバスなど）は永続的であるManualRecorderRegistryオブジェクトに登録される。ブートオペレーション期間に、ManualRecorderRegistryオブジェクトはカードのレコーダをインスタンス生成し、レコーダオブジェクトのInitiateNestedRecognizers()メソッドを生起して、カードが必要とする、ネストされたレコグナイザをインスタンス生成する。
【０２５３】
TManualConfigurationRecorderクラス１７００の派生クラスはCreateModuleMaker()メソッドを実装していなければならない。CreateModuleMaker()メソッドは、インストール期間にコンピュータビューアによって生起され、カードを表しているHardwareModuleMakerオブジェクトを作成し、カード上の各コネクタを表すTHardwareInterfaceIdentifierオブジェクトを作成し、上記作成されたカードのTHardwareModuleMakerオブジェクトにそれを追加する。
【０２５４】
エッジコネクタの識別子(TUniqueNonActivatableHardwareInterfaceIdentifier)は、オブジェクトの構築期間にコンピュータビューアオブジェクトに渡され、レコーダオブジェクトはその識別子をカードモジュールに追加する。エッジの親はマニュアル入出力カード用に設定されていない。アクチベート可能な機能を表しているコネクタの場合は、対応する識別子はTIOFunctionHardwareInterfaceIdentifierクラスからサブクラス化することによって作成されなければならない。TIOFunctionHardwareInterfaceIdentifierクラスのサブクラスを書く開発者が、HardwareModuleMakerオブジェクトの”other End”または”connection kind”属性を設定する必要がないのは、これらの属性はコンピュータビューアオブジェクトによって設定されるからである。開発者がメーカの”this end”属性を設定しなくてもよいのは、モジュールのデフォルトコネクタ（エッジが代表例）がデフォルトになっているからである。
【０２５５】
IsRoot()メソッドは、デフォルトではFALSEを返し、マザーボード構成レコーダオブジェクトのときだけTRUEを返す。IsRoot()メソッドはマニュアルレコーダレジストリオブジェクトによってコールされ、レコーダオブジェクトがマザーボードに対するものかどうかをチェックする。
【０２５６】
NeedsRecognition()メソッドはデフォルトではFALSEを返し、サブクラスが二次レコグナイザを生起する必要があるときTRUEを返すようにオーバライドすることが可能である。このメソッドは、マニュアルレコーダレジストリオブジェクトによってコールされ、カードがブートオペレーション期間に二次レコグナイザオブジェクトを生成する必要があるかどうかをチェックする。
【０２５７】
InitiateNestedRecognizers()メソッドはカードが必要とする二次レコグナイザオブジェクトをインスタンス生成する。デフォルトでは、このメソッドはなにもしない。開発者は、カードがブートオペレーション期間に二次レコグナイザオブジェクトを生起する必要があるときはこのメソッドをオーバライドしておくべきである。構成レコーダオブジェクトは、認識を必要とする機能の機能識別子をストアしている。サブクラスがこのメソッドをオーバライドする場合は、そのCreateModuleMaker()はInitiateNestedRecognizers()メソッドが必要とする識別子があれば、それらを格納（オブジェクト状態で）しておくべきである。
【０２５８】
TMotherboardConfigurationRecorderクラス１７０２は、コンピュータシステムのマザーボードのための構成レコーダを構築するために使用される。TMotherboardConfigurationRecorderクラス１７０２は抽象基底クラスであるので、特定マザーボード用の構成レコーダを表すようにサブクラス化されていなければならない。TMotherboardConfigurationRecorderクラス１７０２は、マザーボード用のハードウェアモジュールオブジェクトを作成し、マザーボード上の拡張バススロット以外の、各コネクタ用のハードウェア識別子オブジェクトを作成し、上記作成された識別子オブジェクトをマザーボードモジュールに追加し、マザーボード上の各拡張バス（ISA、PCIなど）用のレコグナイザオブジェクトをインスタンス生成し、マザーボードが必要とする、ネストされたレコグナイザオブジェクト（SCSIレコグナイザオブジェクトなど）をインスタンス生成することを受け持っている。
【０２５９】
TMotherboardConfigurationRecorderクラス１７０２は、マザーボードのインストール期間にコンピュータビューアオブジェクトによってインスタンス生成される。マザーボードレコーダオブジェクトがManualRecorderRegistryオブジェクトに永続的に登録されるのは、ネストされたレコグナイザを必要とするバスが常にそこに組み込まれているからである。システムブートオペレーション期間に、
ManualRecorderRegistryオブジェクトはマザーボードレコーダオブジェクトをインスタンス生成し、マザーボードレコーダオブジェクトのInitiateNestedRecognizers()メソッドを生起する。後者のメソッドは、その後、拡張バスおよびネストされたデバイスバスレコグナイザオブジェクトを必要に応じてインスタンス生成する。
【０２６０】
TMotherboardConfigurationRecorderクラス１７０２は複数のメンバ関数も含んでおり、その中には、レコーダオブジェクトがマザーボードに対するものであるかをチェックするためにマニュアルレコーダレジストリオブジェクトによってコールされるIsRoot()メソッドが含まれている。レコーダオブジェクトがマザーボードに対するものであれば、IsRoot()メソッドは第１のあらかじめ決めた値（例えば、ブール値のTRUE）を返す。
【０２６１】
NeedsRecognition()メソッドはマニュアルレコーダレジストリオブジェクトによってコールされ、マザーボードがブートオペレーション期間に生起される二次レコグナイザオブジェクトを要求しているかどうかが判断される。二次レコグナイザオブジェクトを要求していれば、NeedsRecognition()メソッドは第１のあらかじめ決めた値（例えば、ブール値のTRUE）を返す。
【０２６２】
InitiateNestedRecognizers()メソッドは、マザーボード上の、すべての拡張バス（ISA、PCIなど）とデバイスバス（SCSIなど）のためのレコグナイザをインスタンス生成する。InitiateNestedRecognizers()メソッドはGetExpansionBusRecognizers()メソッドも生起し、マザーボード上の拡張バス用のレコグナイザオブジェクトを判断し、前のステップで戻されたTIOCardRecognizerオブジェクトのコレクションにわたって繰り返し、各レコグナイザオブジェクトの該当メソッドを生起して各拡張バスに置かれている、カード上の機能のためのリソース要求をリソース競合リゾルバオブジェクトに登録する。このメソッドはリソース競合リゾルバオブジェクトの該当メソッドも生起してマザーボードと拡張カード上の各機能用の無競合リソース割り当てを生成し、各自動構成可能レコグナイザオブジェクトの該当メソッドを生起して拡張カード用の構成レコーダオブジェクトをインスタンス生成し、必要ならば、DoInitiateNestedRecognizers()メソッドをコールしてマザーボード上の二次レコグナイザオブジェクトをインスタンス生成する。
【０２６３】
RegisterPossibleAssignments()メソッドは開発者によってオーバライドされないが、マザーボード上の機能のための可能なリソース割り当てやリソース割り当ての制約といった、リソース要求をリソース競合リゾルバオブジェクトに登録する。
【０２６４】
DoInitiateNestedRecognizers()メソッドは、デフォルトではなにもしないが、開発者は、必要ならば、マザーボード上の二次レコグナイザオブジェクト（SCSIレコグナイザオブジェクトなど）をインスタンス生成するためにこのメソッドをオーバライドすることができる。構成レコーダオブジェクトは、認識を必要とする機能用の識別子をストアしている。
【０２６５】
GetExpansionBusRecognizers()メソッドは、マザーボード上の、拡張バス用のレコグナイザオブジェクトのコレクションを返すように開発者によって実装されていなければならない。
【０２６６】
TManualRecorderRegistryクラス１７０４はInitiateAllRecognizers()メソッドとRegisterForBootTimeInitiation()メソッドを含んでいる。TManualRecorderRegistryHandleは、ブート期間にインスタンス生成される、ネストされたレコグナイザを必要とするマニュアル構成入出力拡張カードのための構成レコーダの永続的レジストリを表している。カードが、システムブートオペレーション期間にインスタンス生成されるネストされたレコグナイザを要求していれば、カードのインストール期間に、そのカードのためのレコーダオブジェクトがレコーダレジストリデータベースに追加される。システムブートオペレーション期間に、ブーティングシステムはレコーダレジストリデータベースのInitiateAllRecognizers()メソッドを生起する。レコーダレジストリは、その後、そこに登録されているすべてのレコーダオブジェクトにわたって繰り返され、最初にマザーボードレコーダから始まり、登録された各TManualConfigurationRecorderオブジェクトでInitiateNestedRecognizer()メソッドをコールする。
【０２６７】
TManualRecorderRegistryオブジェクトは自身でガーベジコレクション(garbage-collecting) を行う。このオブジェクトは、そのレコーダのすべてをインスタンス生成することを要求されるたびに、最初にガーべジコレクションを実行する。ガーベジコレクションは、ハードウェア構成データベース内の、すべてのTHardwareModuleHandleオブジェクトのコレクションを取得し、そのTManualConfigurationRecorderオブジェクトのすべてにわたって繰り返し、各々のレコーダオブジェクトごとに、ハードウェア構成データベースにハードウェアモジュールがまだ存在するかを確かめることによって処理される。存在しなければ、対応するTManualConfigurationRecorderオブジェクトはレコーダレジストリから自動的に削除される。
【０２６８】
TManualRecorderRegistryクラス１７０４は単態クラスであるので、開発者によってサブクラス化されないのが通常である。上述したメソッドのほかに、クラス１７０４はRegisterForBootTimeInitiation()メソッドも含んでおり、このメソッドは、レコーダレジストリが存在することをブーティングシステムに登録しておき、InitiateAllRecognizers()メソッドがブーティングプロセス期間にコールされるようにする。
【０２６９】
次に、図１８Ａを参照して説明すると、マニュアルモジュールフレームワークは、いくつかの構成オプションリトリーバクラスをさらに含んでいる。これらのクラスの中には、TMotherboardConfigurationOptionRetrieverクラス１８０２とTManualConfigurationOptionRetrieverクラス１８０４が含まれており、その各々は図８を参照して上述したTConfigurationOptionRetrieverクラス１８００のサブクラスであり、従ってTConfigurationOptionRetrieverクラス１８００から継承されている。TMotherboardConfigurationOptionRetrieverクラス１８０２は単態クラスであるため、開発者によってサブクラス化されないのが通常である。
【０２７０】
TMotherboardConfigurationOptionRetrieverクラス１８０２は、可能なリソース割り当て、リソース割り当ての制約およびマザーボードのファクトリ設定状態に対応するデフォルトリソース割り当てなどのリソース要求を、EISAとISA拡張カードの構成ファイルなどの、永続的構成オプションファイルから取り出すときのプロトコルを実装している。これらのデフォルト構成は、コンピュータビューアの援助を得て構成オプションデータベースに追加することも、カードメーカに提供させることも可能である。
【０２７１】
TMotherboardConfigurationOptionRetrieverクラス１８０２は、拡張カードのベンダ固有情報を返すGetVendorInformation()メソッドと拡張カードのタイプを返すGetCardType()メソッドを含んでいる。TMotherboardConfigurationOptionRetrieverクラス１８０２は、拡張カード上の機能の数を返すGetFunctionCount()メソッドと拡張カード上の個別的機能の機能情報を返すGetFunctionInformation()メソッドも含んでいる。
【０２７２】
クラス１８０２のGetPossibleAssignment()メソッドは、拡張カード上の個別機能のためのリソース割り当ての選択を取り出して返し、クラス１８０２のGetDefaultAssignment()メソッドはカードのファクトリ設定状態に対応する個別的機能のためのデフォルトリソース割り当てを返す。
【０２７３】
図１８Ｂを参照して簡単に説明すると、TManualSlotIdentifierクラス１８０８は、ISA、VESAなどの、マニュアルバスのスロットのハードウェア識別子を表しており、THardwareInterfaceIdentifierクラス１８０６のサブクラスである。クラス１８０８からインスタンス生成されたTManualSlotIdentifierオブジェクトは構成情報を構成オプションデータベースから取り出すときのキーとして使用されるSlotNumberをカプセル化している。
【０２７４】
図１８Ａに戻って説明すると、TManualConfigurationOptionRetrieverクラス１８０４からは、マニュアル拡張カードのリソース要件および他の構成情報を永続的構成ファイルから取り出すオブジェクトがインスタンス生成されている。TManualConfigurationOptionRetrieverクラス１８０４は、可能なリソース割り当て、リソース割り当ての制約、およびマニュアル構成入出力拡張カードのファクトリ設定状態に対応するデフォルトリソース割り当てなどの、リソース要求を永続的構成ファイル（EISAタイプとISAタイプの拡張バスとカードの構成ファイルなど）から取り出すときのプロトコルを実装している。TManualConfigurationOptionRetrieverクラス１８０４は単態クラスであるので、開発者によってサブクラス化されないのが通常である。
【０２７５】
TManualConfigurationOptionRetrieverクラス１８０４は、拡張カード上の機能の数を返すGetFunctionCount()メソッドと、拡張カード上の個別的機能の機能情報を返すGetFunctionInformation()メソッドを含んでいる。
【０２７６】
クラス１８０４は、カード上の個別的機能のためのリソース割り当ての選択を返すGetPossibleAssignments()メソッドと、拡張カードのファクトリ設定状態に対応する個別的機能のためのデフォルトリソース割り当てを返すGetDefaultAssignment()メソッドも含んでいる。
【０２７７】
クラス１８０４は、拡張カードのベンダ固有情報を返すGetVendorInformation()メソッドと、カードのタイプを返すGetCardType()メソッドをさらに含んでいる。
【０２７８】
次に、図１９を参照して概要を説明すると、マニュアルモジュールフレームワークはTManualIOCardクラス１９００も含んでいる。TManualIOCardクラス１９００からインスタンス生成されたオブジェクトは、マニュアルISA拡張カード、マニュアルローカルバス拡張カードおよびマザーボードなどの、マニュアル構成拡張カードの動作を表している。TManualIOCardクラス１９００はTManualIOFunctionResourceクラス１９０２と関連付けられている。
【０２７９】
クラス１９０２からインスタンス生成されたManualIOFunctionResourcesオブジェクトは、マニュアル入出力カードまたはマザーボード上の個別的機能のための可能なリソース割り当て、リソース割り当ての制約およびデフォルトリソース割り当てをカプセル化している。ManualIOFunctionResourcesオブジェクトは機能に関するTManualIOFunctionInformationもカプセル化している。TManualIOFunctionResourceクラス１９０２は、TPossibleIOResourceAssignmentクラス１９０６からインスタンス生成されたオブジェクトのデキューであるプライベート属性と、TManualIOFunctionInformationクラス１９０８からインスタンス生成されたオブジェクトであるプライベート属性を含んでいる。
【０２８０】
TPossibleIOResourceAssignmentクラス１９０６は、上述したように特定の機能用の可能なリソース割り当てセット、機能用のデフォルト割り当てセットと制約セットをカプセル化しているオブジェクトを作成するために使用される。TManualIOFunctionInformationクラス１９０８は、マニュアル拡張カードまたはマザーボード上の、入出力機能の機能タイプなどの情報をカプセル化している。
【０２８１】
TManualIOCardクラス１９００は単態クラスであるので、開発者によってサブクラス化されないのが通常である。このクラスからインスタンス生成されたManualIOCardオブジェクトは、汎用カード(generic card)情報などの情報と、ISAカード、ローカルバスカードおよびマザーボードなどのマニュアル構成カードのベンダ固有情報をカプセル化している。ManualIOCardオブジェクトは、カード上の各機能用に１つある、ManualIOFunctionResourceオブジェクトのプライベートデキューも含んでいる。上述したように、マニュアル入出力カードまたはマザーボードのインストール期間に、コンピュータビューアはManualIOCardオブジェクトを使用してリソース競合リゾルバと通信する。
【０２８２】
ManualIOCardオブジェクトのその他の役割は、(1) カード上の機能のための可能なリソース割り当てとリソース割り当ての制約をリソース競合リゾルバオブジェクトに登録すること、(2) リソース競合リゾルバオブジェクトの該当メソッドを生起して、インストールされるカード上の機能のための無競合リソース割り当てを作成すること、(3) ManualIOCardオブジェクトをカード上のデフォルトコネクタオブジェクトに接続すること、および(4) カード上の個別的機能を使用禁止または使用可能にすることである。
【０２８３】
TManualIOCardクラス１９００は複数のメンバ関数を含んでおり、その中には、マニュアル入出力カードまたはマザーボード上の、すべての機能のための可能なリソース割り当てを、リソース競合リゾルバオブジェクトに登録するメソッドであるRegisterPossibleAssignments()メソッドが含まれている。拡張カード上の各機能のための可能なリソース割り当ては、RegisterPossibleAssignment()へのコールの前に該当のPossibleIOResourceAssignmentオブジェクトをインスタンス生成することによってセットアップされていなければならない。
【０２８４】
クラス１９００は、カード上の入出力機能のための、リソース割り当ての制約をリソース競合リゾルバオブジェクトに登録する別のメソッドである、SetFunctionAssignmentConstraints()と、リソース割り当てをもたない入出力機能に関連付けられたリソース割り当て制約を除去する、さらに別のメソッドであるRemoveFunctionAssignmentConstraints()も含んでいる。入出力機能のリソース割り当て制約を登録するメソッドは、入出力機能のためのリソース割り当てを強制的に特定値にするためにクライアントによって使用される。制約は、カード用の可能なリソース割り当てと競合していてはならない。制約が競合していると、このメソッドは例外をスローする。前述したメソッドの各々は、カードまたは機能がリソース競合リゾルバオブジェクトに登録されていないと例外をスローする。
【０２８５】
クラス１９００は、システム内のマザーボードと拡張カード上の入出力機能のための無競合リソース割り当てを、特定のブート期間に生成するメソッドである、ProduceConflictFreeAssignments()も含んでいる。このブート期間は、今回のブートオペレーション(kThisBoot)または次回のブートオペレーション（kNextBoot）のためにリソース割り当てを生成するようにリソース競合リゾルバオブジェクトに指示する。このメソッドは、現在リソース割り当てのない、すべての入出力機能のためにIOFunctionResourceAssignmentオブジェクトを生成する。リソース競合が起こっていると、このメソッドはIOResourceConflictオブジェクトを作成し、このリソース割り当てを作成している途中でリソース競合が見つかると、例外をスローする。
【０２８６】
クラス１９００は、Slot idで示されたカード上の、すべての入出力機能のための無競合リソース割り当てを取得するためにコールされるメソッドである、GetCardResourceUsage()をさらに含んでいる。無競合リソース割り当ては、ProduceConflictFreeAssignments()メソッドへの以前のコールによって作成される。GetCardResourceUsage()メソッドは、カードがリソース競合リゾルバオブジェクトに登録されていないと例外をスローする。
【０２８７】
クラス１９００は、特定の拡張カードのための、すべてのリソース割り当て（IOCardResourceUsageオブジェクトにカプセル化されている）を除去するためにコールされる別のメソッドである、RemoveCardResourceUsage()も含んでいる。このメソッドは、拡張カードがコンピュータシステムから除かれるときコールされるのが代表的であり、このメソッドはリソースが使用中であると例外をスローする。
【０２８８】
クラス１９００のGetFunctionAssignment()メソッドは入出力機能のための無競合リソース割り当てを返す。入出力機能のユニークなHardwareInterfaceIdentifierは、リソース割り当てを取得するためにキーとして渡される。カードの構成レコーダオブジェクトはTIOFunctionHardwareInterfaceIdentifierクラスからサブクラス化することによって機能識別子を作成する。このメソッドは、ハードウェアがコンピュータシステムに物理的にインストールされていなくても、カードのためのリソース割り当てを返し、リソース割り当てが作成されていないか、あるいはその入出力機能のためのリソース割り当てを作成中に競合が起こると、例外をスローする。このメソッドは、機能がリソース競合リゾルバオブジェクトに登録されていないときにも例外をスローする。このメソッドは、レコグナイザとコントロールパネルによってのみコールされる。
【０２８９】
クラス１９００のGetResourceConflicts()メソッドは、入出力機能のためのリソース割り当ての競合を返す。入出力機能のユニークなHardwareInterfaceIdentifierは、リソース競合を取得するためにキーとして使用される。このメソッドは、機能がリソース競合リゾルバオブジェクトに登録されていないと例外をスローする。このメソッドはレコグナイザオブジェクトとコントロールパネルオブジェクトによってのみコールされる。
【０２９０】
クラス１９００のRemoveFunctionAssignment()メソッドは、入出力機能のためのリソース割り当て（IOFunctionResourceAssignmentオブジェクトにカプセル化されている）を除去するためにコールされる。このメソッドは、入出力機能がコンピュータシステムから除かれるときコールされる。コール側は、リソースが対応するハードウェアによって応答されていないことをアサートする。このメソッドは、リソースが使用中である場合や機能がリソース競合リゾルバオブジェクトに登録されていない場合に例外を引き起こす。
【０２９１】
クラス１９００のRemoveFunctionResourceUsage()メソッドは、入出力機能に関連付けられたリソース使用状況（TIOFunctionResourceUsageオブジェクトにカプセル化されている）を除去するためにコールされる。RemoveFunctionResourceUsage()メソッドは、入出力機能がシステムから除かれるときコールされる。コール側は、リソースが対応するハードウェアによって応答されていないことをアサートする。このメソッドは、リソースが使用中であると例外を引き起こす。このメソッドは機能がリゾルバに登録されていない場合にも例外をスローする。
【０２９２】
Attach()メソッドは、ManualIOCardオブジェクトを、カード上のコネクタ、代表例ではデフォルト（エッジ）コネクタのハードウェアインタフェース識別子と結びつける。DisableFunction()メソッドは、マニュアルカードまたはマザーボード上の既存機能を使用禁止にするためにコールされる。コール側は機能が電気的に切り離されていることをアサートする。他方、EnableFunction()メソッドは、マニュアルカードまたはマザーボード上の、以前に使用禁止にされた機能を使用可能にするためにコールされる。
【０２９３】
GetType()メソッドはマニュアル構成カードのタイプを返し、SetType()メソッドは
カードタイプをプライベート属性に書き込む。GetVendorInformation()メソッドはベンダ情報を返し、SetVendorInformation()メソッドはベンダ情報をプライベート属性に書き込む。
【０２９４】
GetFunctionResources()メソッドはカード上の機能のためのManualIOFunctionResourcesオブジェクトを読み取り、SetFunctionResources()はManualIOFunctionResourcesオブジェクトを、カード上の機能の内部デキューに書き込む。
【０２９５】
TManualIOFunctionResourcesクラス１９０２は単態クラスであるので、開発者によってサブクラス化されないのが通常である。TManualIOFunctionResourcesクラス１９０２は複数のメンバ関数を含んでおり、その中には、機能のための可能なリソース割り当てを読み取るGetPossibleAssignments()メソッドと機能のための可能なリソース割り当てを書き込むSetPossibleAssignments()メソッドが含まれている。
【０２９６】
GetDefaultAssignment()メソッドは機能のためのデフォルトリソース割り当てを読み取り、SetDefaultAssignment()メソッドは機能のためのデフォルトリソース割り当てを書き込む。デフォルトリソース割り当ては、カード上の機能の工場設定状態に対応している。
【０２９７】
GetAssignmentConstraint()メソッドは機能のためのリソース割り当ての制約を読み取り、SetAssignmentConstraint()メソッドは機能のためのリソース割り当ての制約を書き込む。
【０２９８】
TManualIOFunctionResourcesクラス１９０２はGetFunctionInformation()メソッドとSetFunctionInformation()メソッドも含んでいる。GetFunctionInformation()メソッドは機能のTManualIOFunctionInformation()を読み取り、SetFunctionInformation()メソッドは機能のTManualIOFunctionInformation()を書き込む。
【０２９９】
TManualIOFunctionResourcesクラス１９０２はGetFunctionStatus()メソッドとSetFunctionStatus()メソッドも含んでいる。GetFunctionStatus()メソッドはカード上の機能が使用禁止になっていれば第１の列挙型値(kDisabled)を返す。SetFunctionStatus()メソッドは機能のステータス（状況）を書き出し、入出力機能が使用禁止になっているときは、リソース競合リゾルバオブジェクトはその入出力機能のためのリソース割り当てを生成せず、これらのリソースはシステム内の他の入出力機能に割り振ることができる。使用禁止にされた入出力機能がシステムに電気的に存在し、その使用禁止の入出力機能によって使用されているリソースが他の入出力機能に割り当てられると、問題が発生することがある。ユーザは、入出力機能が使用禁止にされる前に電気的に切り離されていることを確かめておく必要がある。
【０３００】
TManualIOFunctionInformationクラス１９０８は単態クラスであるので、開発者によってサブクラス化されないのが通常であり、複数のメンバ関数を含んでいる。その中には、機能によって表されている入出力オペレーションを示す機能タイプを読み取るGetFunctionType()メソッドと機能タイプを設定するSetFunctionType()メソッドが含まれている。
ISAバスフレームワークのクラス
図２０、２１Ａ、２１Ｂおよび２２は、ISAバスフレームワークを形成するクラス群を示している。ISAバスフレームワークは、ISAベースのマシンにインストールされたマザーボードと拡張カード上に実装されたデバイス用のオペレーティングシステムデバイスドライバを動的にブートするとき使用される、複数のクラスを含んでいる。
【０３０１】
まず、図２０を参照して説明すると、図示のISAフレームワークはTMCACardRecognizerクラス２００２、TEISACardRecognizerクラス２００６、TPCICardRecognizerクラス２００８、TMotherboardRecognizerクラス２０１０、TPCMCIACardREcognizerクラス２０１４、TPlugNPlayISACardRecognizerクラス２０１２およびTManualIOCardRecognizerクラス２０１６を含んでいる。
【０３０２】
図２０に示すように、TMotherboardRecognizerクラス２０１０はTIOCardRecognizerクラス２００４から派生し、システムのマザーボードのレコグナイザを表している。MotherboardRecognizerオブジェクトはTMotherboardRecognizerクラス２０１０からインスタンス生成され、マザーボード上の機能を判断し、その機能の可能なリソース割り当てをリソース競合リゾルバオブジェクトに登録する。MotherboardRecognizerオブジェクトは、コンピュータのマザーボードのための構成レコーダオブジェクトをインスタンス生成することも受け持っている。
【０３０３】
TMotherboardRecognizerクラス２０１０は複数のメンバ関数を含んでおり、この中には、DoBoot()メソッドと、マザーボード上の各機能のための可能なリソース割り当てをリソース競合リゾルバオブジェクトに登録するためにコールされるメソッド(RegisterPossibleAssignments())が含まれている。マザーボードの機能のための可能なリソース割り当ては構成オプションデータベースから取り出される。
【０３０４】
TMotherboardRecognizerクラス２０１０は、マザーボードのための該当構成レコーダオブジェクトをインスタンス生成するためにコールされるメソッド(InstantiateRecorders())も含んでいる。
【０３０５】
TManualIOCardRecognizerクラス２０１６は、従来のISAおよびローカルバスカードのような、システム内の全マニュアル入出力カードのためのレコグナイザオブジェクトがこのクラスからインスタンス生成されている。これらのレコグナイザオブジェクトは、どのマニュアル入出力カードがコンピュータシステムに存在するかを判断し、その可能なリソース割り当てをリソース競合リゾルバオブジェクトに登録する。これは、システム内の各マニュアル入出力カードのための該当構成レコーダオブジェクトをインスタンス生成することも受け持っている。
【０３０６】
図２０に示すように、TManualIOCardRecognizerクラス２０１６は図７を参照して上述したTIOCardRecognizerクラス７００から派生している。ManualIOCardRecognizerオブジェクトは、TIOCardRecognizerSetオブジェクト（TIOCardRecognizerSetクラス２０００からインスタンス生成されている）に示されているレコグナイザ群に従ってブーティングシステムによってインスタンス生成され、マニュアル構成入出力カードのための可能なリソース割り当てをリソース競合リゾルバオブジェクトに登録する。TManualIOCardRecognizerオブジェクトは、コンピュータ内のマニュアル入出力カードのための構成レコーダオブジェクトをインスタンス生成することも受け持ち、TManualIOCardRecognizerクラス２０１６のメンバ関数であるDoBoot()メソッドを生起した後、破棄することができる。
【０３０７】
TManualIOCardRecognizerクラス２０１６は複数のメンバ関数を含んでおり、その中には、従来のISAまたはローカルバスカードのような、マニュアル入出力カード上の機能のための可能なリソース割り当てをリソース競合リゾルバオブジェクトに登録するメソッド(RegisterPossibleAssignments())が含まれている。このような機能のための可能なリソース割り当ては、前述したように構成オプションデータベースから取り出される。
【０３０８】
TManualIOCardRecognizerクラス２０１６は、どのマニュアル構成入出力拡張カードがシステムに存在するかを判断し、マニュアル構成拡張カードの各々ための該当構成レコーダオブジェクトをインスタンス生成するためにコールされるメソッド(InstantiateRecorders())も含んでいる。マニュアル構成カードは前述したようにハードウェア構成データベースをサーチすることにより判断される。
【０３０９】
TPlugNPlayISACardRecognizerクラス２０１２は、システム内の、すべてのPlug & Play ISAカードのためのレコグナイザオブジェクトを表している。同じように、TMCACardRecognizerクラス２００２、TEISACARDRECOGNIZERクラス２００６およびTPCMCIACardRecognizerクラス２０１４は、MCAカード、EISAカードおよびPCMCIAカードを表しているオブジェクトをインスタンス生成するために使用される。TPlugNPlayISACardRecognizerクラス２０１２、TMCACardRecognizerクラス２００２、TEISACARDRECOGNIZERクラス２００６およびTPCMCIACardRecognizerクラス２０１４からインスタンス生成されたオブジェクトは、どのPlug & Play ISAカード、MCAカード、EISAカードおよびPCMCIAカードがコンピュータシステムに存在するかを判断し、それぞれの可能なリソース割り当てをリソース競合リゾルバオブジェクトに登録する。オブジェクト２００２、２００６、２００８、２０１２および２０１４は、各ISAカードが無競合リソース割り当てをもつように構成し、コンピュータシステム内の各ISAカードのための該当構成レコーダオブジェクトをインスタンス生成することも受け持っている。
【０３１０】
クラス２００２、２００６、２００８、２０１２および２０１４はTIOCardRecognizerクラス２００４から派生し、システム内の、すべてのISA拡張カードのためのレコグナイザを表している。オブジェクトは、IOCardRecognizerSetオブジェクト内の情報を使用して、ブーティングシステムによってインスタンス生成され、これらのオブジェクトはISAカードのための可能なリソース割り当てをリソース競合リゾルバオブジェクトに登録する。対応するレコグナイザオブジェクトは、コンピュータシステム内の、すべてのISAカードのための構成レコーダオブジェクトをインスタンス生成し、リソース競合リゾルバオブジェクトによって計算された無競合リソース割り当てをもつようにISAカードを構成することも受け持っている。レコグナイザオブジェクトは、レコグナイザクラス２００２、２００６、２００８、２０１２および２０１４のメンバ関数であるDoBoot()メソッドを生起した後で破壊することができる。
【０３１１】
TPlugNPlayISACardRecognizerクラス２０１２、TMCACardRecognizerクラス２００２およびTEISACardRecognizerクラス２００６は複数のメンバ関数を含んでおり、その中には、Plug & Play ISAカードのための可能なリソース割り当てをリソース競合リゾルバオブジェクトに登録するメソッド(RegisterPossibleAssignments())が含まれている。可能なリソース割り当てはカードから取り出される。
【０３１２】
クラス２００２、２００６、２００８、２０１２および２０１４は、システム内の対応するISAカードを認識し、システム内の各ISAカードのための該当構成レコーダオブジェクトをインスタンス生成するためにコールされるメソッド(InstantiateRecorders())も含んでいる。各ISAカードには、カードをISAカードとしてユニークに識別している識別コードがストアされているリードオンリメモリが含まれている。従って、各ISAカードは、カードのリードオンリメモリにストアされているユニークなカード識別コードをカードから取り出すことで認識することができる。カードは、リソース割り当てでプログラムすることも可能であり、この機能を使用すると、リソース競合リゾルバオブジェクトによって計算された無競合リソース割り当てをもつようにISAカードを構成することができる。
【０３１３】
RegisterPossibleAssignments()メソッドとInstantiateRecorders()メソッドは次のような形式になっている。
【０３１４】
virtual void RegisterPossibleAssignments (const TIOConflictResolverHandle&
resolver);
virtual void InstantiateRecorders (const TIOConflictResolverHandle&
resolver,
const THardwareModuleMaker&
parentDevice,
const short slotIndex,
const short slotCount,
const THardwareInterfaceIdentifer&
parentInterface,
const TInterruptHandlerReference&
parentHandler);
【０３１５】
カードの構成情報は、コンピュータビューアオブジェクトと共に表示されるカードアイコンをダブルクリックすることで見ることができる。ユーザがカードアイコンでダブルクリックすると、カードの構成情報は、カードがプラグインされているスロットのTHardwareInterfaceIdentifierオブジェクトから取り出される。マザーボードについては、構成情報はマザーボードのために作成された特殊なTHardwareInterfaceIdentifierオブジェクトから取り出される。カードの構成情報は、対応するレコグナイザオブジェクトによってスロットのTHardwareInterfaceIdentifierオブジェクトにストアされている。マニュアル入出力カードについては、構成情報も、カードビューアオブジェクトによってTHardwareInterfaceIdentifierオブジェクトにストアされている。
【０３１６】
マニュアル入出力カードのリソース割り当ては、カードビューアオブジェクトを使用して変更することができる。リソース割り振りが変更されると、新たに追加されたカードの場合と同じようにTManualIOCardオブジェクトによる競合がないかがチェックされる。ISAバスフレームワークは、ユーザが自動構成可能カードの構成をマニュアルで変更できるようにするメカニズムをサポートしていない。
【０３１７】
カードの該当構成レコーダオブジェクトが見つからないと、バスオブジェクトはカードの構成レコーダオブジェクトがコンピュータシステムで使用可能になるのを待っている、新しいスレッドを生成する。このスレッドは、バスオブジェクトが壊された後でも生存したままになっている。カードの構成レコーダオブジェクトが使用可能のときは、これはインスタンス生成される。スレッドが生存しているアドレス空間は、システムがシャットダウンするまで壊されないものと想定されている。
【０３１８】
次に、図２１Ａおよび図２１Ｂを参照して説明すると、ISAフレームワークは構成レコーダオブジェクト群をさらに含んでいる。このオブジェクト群には、特定のボードを表しているサブクラスが派生している、元の複数の基底クラスが含まれている。例えば、TManualIOCardConfigurationRecorder基底クラス２１００は、TSampleManualIOCardConfigurationRecorderクラス２１０４と名付けられた、特定カードの派生サブクラスをもち、特定マニュアル入出力カード（例えば、従来のISAカードまたはマニュアル構成ローカルバスカード）の構成レコーダオブジェクトはそのサブクラスからインスタンス生成されている。構成レコーダオブジェクトは、マニュアル入出力カードを登録し、その構成情報をハードウェア構成データベースに記録することを受け持っている。
【０３１９】
ManualIOCardConfigurationRecorderオブジェクトは、ISAカードやローカルバスカードのように、ISAアーキテクチャをもつコンピュータシステム内のマニュアル入出力カードの構成アクセスマネージャである。その結果、ManualIOCardConfigurationRecorderオブジェクトはカード上のハードウェアを直接に取り扱うメソッドを含んでいる。
【０３２０】
TSampleManualIOCardConfigurationRecorderクラス２１０４は、TManualIOCardRecognizerオブジェクトによってシステムブートオペレーション期間にインスタンス生成される。このクラスは、ユーザが、上述したようにコンピュータビューアオブジェクトの支援を得て新しいマニュアル入出力カードを追加したときにもインスタンス生成される。SampleManualIOCardConfigurationRecorderオブジェクトは、TManualIOCardConfigurationRecorderクラス２１００の純粋メンバ関数であるDoBoot()メソッドを生起した後で破壊することができる。その結果、TManualIOCardConfigurationRecorderクラス２１００から派生する各クラスはDoBoot()メソッドを実装していなければならない。DoBoot()メソッドは、ISAマシン内のマニュアル入出力カードの構成レコーダオブジェクトをインスタンス生成するためにManualIOCardRecognizerオブジェクトによって生起される。このメソッドは、新しいマニュアル入出力カードの構成レコーダをインスタンス生成するためにカードビューア(Card Viewer)によっても生起される。クラス２１００のDoBoot()メソッドは次のような形式になっている。
【０３２１】
virtual void DoBoot (const TManualIOCard& card,
const TCollection<TManualIOFunctionResources>& funcs,
const THardwareIntefaceIdentifier& slot id) = 0
【０３２２】
このメソッドは、(1) 入出力カードを表しているTHardwareModuleMakerオブジェクトを作成し、(2) カード上の各コネクタを表すTHardwareInterfaceIdentifierオブジェクトを作成して、コネクタと関連付けられたリソース（親TInterruptHandler、InterruptSoketNumberなど）をそのオブジェクトにストアし、(3) 上で作成されたTHardwareInterfaceIdentifierオブジェクトを、受け渡されたTHardwareModuleMakerオブジェクトに追加し、(4) カード(THardwareModuleMaker)をコンピュータハードウェア構成データベースに登録する。
【０３２３】
マザーボード構成レコーダクラス２１０８と２１１２の構築方法とその動作の仕方は、それぞれマニュアル入出力カードの構成レコーダクラス２１００および２１０４と同じである。
【０３２４】
フレームワークは、Plug N Playカード、PCIカード、PCMCIAカード、MCAカードおよびEISAカードのような、他のISAカードのための構成レコーダオブジェクトをインスタンス生成するために使用される、他のクラスを含んでいる。例えば、TPlugNPlayISACardConfigurationRecorderクラス２１０２は抽象基底クラスであるので、個別Plug & Play ISAカードのための構成レコーダオブジェクトがそれからインスタンス生成されるようにするには、その前にサブクラス化されていなければならない。図２１Ａに示すように、このようなサブクラスとしては、特定のカード用に手直しされるTSamplePlugNPlayISACardConfigurationRecorderクラス２１０６がある。TSamplePlugNPlayISACardConfigurationRecorderクラス２１０６からインスタンス生成されるPlugNPlayISACardConfigurationRecorderオブジェクトは、Plug & Play ISAカードの構成アクセスマネージャである。TSamplePlugNPlayISACardConfigurationRecorderクラスは、カードのための対応するPlugNPlayISACardRecognizerオブジェクトによってブートオペレーション期間にインスタンス生成される。SamplePlugNPlayISACardConfigurationRecorderオブジェクトは、TPlugNPlayISACardConfigurationRecorderクラス２１０２のメンバ関数である、そのDoBoot()メソッドを生起した後壊すことが可能である。TPlugNPlayISACardConfigurationRecorderクラス２１０２から派生する各クラスはDoBoot()メソッドを実装していなければならない。DoBoot()メソッドは、システム内のPlug & Play ISAカードの構成レコーダオブジェクトをインスタンス生成するためにPlugNPlayISACardRecognizerオブジェクトによって生起される。クラス２１０２のDoBoot()メソッドは、(1) Play & Plug ISAカードを表しているTHardwareModuleMakerオブジェクトを作成し、(2) カード上の各コネクタを表すTHardwareInterfaceIdentifierオブジェクトを作成して、コネクタと関連付けられたリソース（親TInterruptHandler、InterruptSoketNumberなど）をそのオブジェクトにストアし、(3) 上で作成されたTHardwareInterfaceIdentifierオブジェクトを、受け渡されたTHardwareModuleMakerオブジェクトに追加し、(4) カード(THardwareModuleMaker)をコンピュータハードウェア構成データベースに登録する。残りのクラス２１１０、２１１４、２１１６、２１２０、２１１８，２１２２、２１２４、２１２６は同じような働き方をする。
【０３２５】
次に、図２２を参照して説明すると、ISAバスフレームワークは、TManualIOCardオブジェクトがインスタンス生成される、元のTManualIOCardクラス２２００も含んでいる。TManualIOCardオブジェクトは、ISAベースのマシン内のISAカード、ローカルバスカードまたはシステムボードデバイスのような、マニュアル構成入出力コンポーネントの動作を表している。このオブジェクトは、汎用カードおよびベンダ固有情報などの、カードの情報をカプセル化している。このオブジェクトは、TManualIOCardRecognizerオブジェクト、TMotherboardRecognizerオブジェクトまたはカードビューアオブジェクトによってインスタンス生成して、対応する構成レコーダオブジェクトに渡すことができる。
【０３２６】
TManualIOCardクラス２２００は複数のメンバ関数を含んでおり、その中には、システムに追加されるカードのためのリソース割り当て案をチェックし、カードのリソース割り振りに競合が起こっていないことを確かめるDetectResourceConflict()メソッドが含まれている。競合が起こっていなければ、このメソッドは第１の列挙型値(kNoConflict)を返す。リソース競合が起こっていて、そのリソース競合が次回のブートオペレーションのとき解決可能であれば、このメソッドは第２の異なる値(kNoConflictAfterBoot)を返す。競合が起こっていて、それが自動的に解決できないときは、このメソッドは第３の値(kConflict)を返す。このメソッドは、インストール期間に渡されたIOResourceAssignmentsオブジェクトのコピーをとり、リソース割り当て案を競合している機能に関する情報を、メソッドの競合引数に入れて返す。リソース割り当て案は、競合を検出するために既存のリソース割り当てと比較されるが、リソース割り当て案自体は、当然のことながら、可能なリソース割り当てと競合してはならない。このメソッドは次のような形式になっている。
【０３２７】
virtual ConflictResult DetectResourceConflict (const TIOCardResourceUsage&
proposal, TCollection<TIOResourceConflict> conflicts);
【０３２８】
別のメソッドである、GetPossibleConflictFreeAssignments()は、現在利用可能である無競合リソース割り当ておよびリブートオペレーションが実行された後利用可能になる無競合リソース割り当てに関する情報を取得するためにコールされる。現在利用可能なTIOResourceAssignmentsをIOCardResourceUsage空きリソースコレクションから選択すると、GetPossibleConflictFreeAssignments()メソッドは第１の値(kNoConflict)を返す。リブートオペレーションの後で利用可能になるIOCardResourceUsageリソースコレクションからTIOResourceAssignmentsを選択すると、GetPossibleConflictFreeAssignments()メソッドは第２の値(kNoConflictAfterBoot)を返す。このメソッドは次のような形式になっている。
【０３２９】
virtual void  GetPossibleConflictFreeAssignments (const
TIOCardResourceUsage& possibles,
TCollection<TIOCardResourceUsage>& freeNow,
TCollection<TIOCardResourceUsage>& freeAfterBoot) const;
【０３３０】
Install()メソッドは、追加された新しいカードの構成情報、または既存カードの構成情報の変更でハードウェア構成データベースを更新する。このメソッドは対応するTHardwareInterfaceIdentifierの該当値を親オブジェクトにストアする。このメソッドは前述のDetectResourceConflict()メソッドを生起した後でコールするようにすれば、リソース割り当てがストアされる前に潜在的なリソース競合を検出することができる。このメソッドは、その前にコールされたDetectResourceConflict()メソッドが、リソース割り当ての競合が見つかったことを示す列挙型値(kConflict)を返すと、例外をスローする。
【０３３１】
クラス２２００のInvokeRecorder()メソッドは、リソース割り当ての競合が検出されたとき該当構成レコーダオブジェクトをインスタンス生成するためにコールされる。このメソッドは、リソース割り当てに競合が発生すると例外をスローする。例えば、以前にコールしたDetectResourceConflict()メソッドが、解決不能な競合が見つかったことを示す列挙型値(kConflict)または解決可能な競合が見つかったことを示す値(kNoConflictAfterBoot)を返すと、例外がスローされる。
【０３３２】
TManualIOCardクラス２２００は、マニュアル構成カードのタイプを返すGetType()メソッドとカードタイプをプライベート属性に書き込むSetType()メソッドをさらに含んでいる。クラス２２００のGetVendorInformation()メソッドはベンダ情報を返し、SetVendorInformation()メソッドはベンダ情報を別のプライベート属性に書き込む。
【０３３３】
クラス２２００のSetSlotIdentifier()メソッドは、カードがプラグインされているスロットのTHardwareInterfaceIdentifierをプライベート属性に書き込み、GetBusType()メソッドはボード上のバスタイプを示す列挙型値kManualIOCardタイプを返す。
【０３３４】
Plug and Play ISAカードを表しているTPlugNPlayISACardクラス２２０２は複数のメンバ関数を含んでおり、その中には、カードで使用されているPlug & Playバージョン番号を読み取るGetPlugNPlayVersionNumber()メソッド、カードで使用されているPlug & Playバージョン番号を設定するSetPlugNPlayVersionNumber()メソッド、カードの改訂番号を読み取るGetCardRevisionNumber()メソッドおよびカードの改訂番号を設定するSetCardRevisionNumber()メソッドが含まれている。
【０３３５】
クラス２２０２は、カードのタイプを読み取るGetCardType()メソッド、カードのタイプを設定するSetCardType()メソッド、同一タイプの２カードを区別するために使用される、カードのシリアル番号を読み取るGetSerialNumber()メソッドおよびカードのシリアル番号を設定するSetSerialNumber()メソッドを、さらに含んでいる。
【０３３６】
また、カードに割り当てられたカード選択番号をPlug & Play隔離フェーズ期間に読み取るGetCardSelectNumber()メソッド、カードのカード選択番号を設定するSetCardSelectNumber()メソッド、カードからベンダ固有情報を読み取るGetVendorInformation ()メソッド、カードのベンダ固有情報を書き込むSetVendorInformation()メソッド、カードがプラグインされているスロットの識別コードを設定するSetSlotIdentifier()メソッドおよび列挙型kPlugNPlayISA値を返すGetBusType()メソッドも含まれている。
【０３３７】
概要を説明すると、TPlugNPlayISACardクラス２２０２からインスタンス生成されるTPlugNPlayISACardオブジェクトは、システム内のPlug & Play ISAカードの動作を表している。各々のPlug & Play ISAカードごとに、カードを表すTPlugNPlayISACardオブジェクトと、カード上の機能のためのTPlugNPlayISAFunctionResourcesオブジェクトのコレクションが作成され、TPlugNPlayISACardConfigurationRecorderオブジェクトに渡される。
【０３３８】
同様に、TPCICardクラス２２０４はシステム内のPCIカードを表している。これは、カードバージョン番号、タイプ、バス番号、ベンダ情報およびスロットidを含む、TPlugNPlayISACardオブジェクトと類似のデータをカプセル化している。これらの値を設定し、プライベート属性から取得するために類似のメソッドが使用されている。
【０３３９】
次に、図２３を参照して説明すると、ISAバスフレームワークは、TPlugNPlayISAFunctionResourcesクラス２３１０とTManualIOFunctionResourcesクラス２３０６も含んでいる。TPlugNPlayISAFunctionResourcesクラス２３１０はPlug & Play ISAカード上の個別機能によって使用されるシステムリソースを表している。図２３に示すように、TPlugNPlayISAFunctionResourcesクラス２３１０はTIOFunctionResourcesクラス２３１４のサブクラスである。
【０３４０】
TPlugNPlayISAFunctionResourcesクラス２３１０は複数のメンバ関数を含んでおり、その中には、それぞれが機能タイプを読み取り、プライベート属性に設定するGetFunctionType()メソッドとSetFunctionType()メソッドが含まれている。機能タイプはその機能によって表された入出力オペレーションを示している。
【０３４１】
クラス２３１０は、互換デバイスタイプを読み取るGetCompatibleType()メソッドと互換デバイスタイプを設定するSetCompatibleType()メソッドも含んでいる。互換デバイスタイプが存在することは、他のデバイスが、機能が置かれているデバイスと互換性をもつことを示している。
【０３４２】
TIOFunctionResourcesクラス２３１４はネストされたクラスを含み、これらのクラスは機能が必要とする種々のリソースに関する情報をカプセル化している。そのようなクラスとしては、入出力レジスタレンジに関する情報をカプセル化しているTIORegisterRange２３０４、機能が必要とするメモリレンジに関する情報をカプセル化しているTIOMemoryRange２３００、割り込みソケットに関する情報をカプセル化しているTInterruptInformation２３０２、およびDMAチャネルに関する情報をカプセル化しているTDMAInformation２３０８がある。
【０３４３】
次に、図２４を参照して説明すると、ISAバスフレームワークは、図示のように、Plug & Play ISAタイプのカードがプラグインされているスロットのTHardwareInterfaceIdentifierオブジェクトを表しているTISASlotWithPlugNPlayISACardIdentifierクラス２４０８と、マニュアル構成タイプのカードがプラグインされているスロットのTHardwareInterfaceIdentifierオブジェクトを表しているTISASlotWithManualISACardIdentifierクラス２４０６をさらに含んでいる。両方のクラス２４０６と２４０８はTISASlotIdentifierクラス２４０４から派生している。TISASlotIdentifierクラス２４０４はISAスロットのTHardwareInterfaceIdentifierを表している。TISASlotIdentifierクラス２４０４は複数のメンバ関数を含んでおり、その中には、それぞれがカードによって使用されている機能リソースを読み取り、設定するGetFunctionResources()メソッドとSetFunctionResources()メソッドが含まれている。クラス２４０４はスロットの識別子を読み取り、設定するGetSlotID()メソッドとSetSlotID()メソッドも含んでいる。
【０３４４】
ISAバスフレームワークは、TConfigurationRecorderLocatorクラス２４００、TManualIOPossibleResourceAssignmentRetrieverクラス２４０２およびTMotherboardIdentifierクラス２４１０も含んでいる。TMotherboardIdentifierクラス２４１０は、マザーボードデバイスの構成情報をストアするためにマザーボードのために作成されたTHardwareInterfaceIdentifierオブジェクトを表している。TMotherboardIdentifierクラス２４１０は、それぞれがカードによって使用されている機能リソースを読み取り、プライベート属性に設定するGetFunctionResources()メソッドとSetFunctionResources()メソッドを含んでいる。TMotherboardIdentifierクラス２４１０は、それぞれがカードオブジェクトを読み取り、設定するGetCard()メソッドとSetCard()メソッドも含んでいる。
【０３４５】
TManualIOPossibleResourceAssignmentRetrieverクラス２４０２は、マニュアルISAカード、ローカルバスカードまたはマザーボードデバイスなどの、特定マニュアル構成入出力カード上の機能のためのデフォルト入出力割り当ておよび可能な入出力リソース割り当て情報を取り出すことを受け持つオブジェクトをインスタンス生成する。ユーザがコンピュータビューアでカードアイコンをスロットアイコンにドラッグすると、カードのTHardwareModuleから取得されたTHardwareModuleSignatureは、制約を構成オプションデータベースから取り出すために使用される。
【０３４６】
以上、特定のシステム環境における好適実施形態を中心にして本発明を説明してきたが、当業者ならば理解されるように、本発明は、本発明の精神と範囲内で変更や改良を加え、他の異なるハードウェアおよびソフトウェア環境で実施することが可能である。
【符号の説明】
【０３４７】
２００  コンピュータシステム
２０２  コンピュータブートシステム
２０４  ハードウェアコンフィギュレーションデータベース
２０６  コンフィギュレーションオプションデータベース
２０８  マザーボードコンフィギュレーションレコーダ
２１０  マザーボードコンフィギュレーションレコグナイザ
２１４  カードコンフィギュレーションレコーダ
２１６  バス／カードレコグナイザ
２２０  リソース競合リゾルバ
２２２  システムバス
【図１】
2010015595.tif 000003
【図２】
2010015595.tif 000004
【図３】
2010015595.tif 000005
【図４】
2010015595.tif 000006
【図５】
2010015595.tif 000007
【図６】
2010015595.tif 000008
【図７】
2010015595.tif 000009
【図８】
2010015595.tif 000010
【図９】
2010015595.tif 000011
【図１０】
2010015595.tif 000012
【図１１】
2010015595.tif 000013
【図１２】
2010015595.tif 000014
【図１３】
2010015595.tif 000015
【図１４Ａ】
2010015595.tif 000016
【図１４Ｂ】
2010015595.tif 000017
【図１５】
2010015595.tif 000018
【図１６】
2010015595.tif 000019
【図１７】
2010015595.tif 000020
【図１８Ａ】
2010015595.tif 000021
【図１８Ｂ】
2010015595.tif 000022
【図１９】
2010015595.tif 000023
【図２０】
2010015595.tif 000024
【図２１Ａ】
2010015595.tif 000025
【図２１Ｂ】
2010015595.tif 000026
【図２２】
2010015595.tif 000027
【図２３】
2010015595.tif 000028
【図２４】
2010015595.tif 000029