実時間応答は、一定の条件を満たした場合に保証されます。この節ではその条件を明らかにし、問題を生じたりシステムを無効にしたりしてしまう重大な設計上のエラーをいくつか説明します。
ここでは、システムの応答時間を遅くさせる可能性のある問題を取り上げます。その中にはワークステーションをハングさせてしまうものもあります。それほど重大ではないエラーとしては、優先順位の反転やシステムの過負荷 (処理が多すぎる) などがあります。
Solaris の実時間プロセスには、次のような特色があります。
「スケジューリング」で説明しているように、実時間スケジューリングクラスで動作します。
「メモリロッキング」で説明しているように、プロセスのアドレス空間内のすべてのメモリをロッキングします。
「共用ライブラリ」で説明しているように、静的にリンクされたプログラム、または動的結合が前もって完了しているプログラムから生じます。
この章では、実時間操作を単一スレッドのプロセスとして説明しますが、説明の内容はマルチスレッドプロセスにも当てはまります (マルチスレッドプロセスの詳細は、『マルチスレッドのプログラミング』を参照してください)。スレッドの実時間スケジューリングを保証するには、結合スレッドとして扱われなければならず、スレッドの LWP が実時間スケジューリングクラスで実行されなければなりません。メモリのロッキングと初期の動的結合は、プロセス内のすべてのスレッドについて有効です。
プロセスが最も高い優先順位を持つ場合は、次のようになります。
実行可能になると保証されているディスパッチ中の潜在的な時間期間の間、プロセッサを得る (「ディスパッチ中の潜在的な時間」を参照)
最も優先順位が高い実行可能なプロセスである限り、実行を継続する
実時間プロセスは、システム上の他のイベントのために、プロセッサの制御を失ったり、プロセッサの制御を得られなかったりすることがあります。そのようなイベントの例としては、外部イベント (割り込みなど)、資源不足、外部イベント待ち (同期入出力)、より高い優先順位のプロセスによる横取りなどがあります。
実時間スケジューリングは通常、open(2) や close(2) など、システムの初期化と終了を行うサービスには適用されません。
この節で説明する問題は程度は異なりますが、どれもシステムの応答時間を遅くさせます。遅れが大きいと、アプリケーションがクリティカルデッドラインを逃してしまうことがあります。
実時間処理は、システム上で実時間アプリケーションを実行している他の有効なアプリケーションの操作に対しても大きな影響を及ぼします。実時間プロセスの優先順位は高いので、タイムシェアリングプロセスはかなりの時間、実行を妨げられます。表示に対してキーボードで応答するなどの対話型操作は著しく遅くなります。
SunOS 5.0 から 5.8 のシステムの応答が、入出力イベントのタイミングを制限することはありません。これは、実行がタイムクリティカルなプログラムセグメントには、同期入出力呼び出しを入れてはいけないということです。時間制限が非常に長いプログラムセグメントでも、同期入出力を行わないでください。たとえば、大量の記憶領域の入出力の際に読み取りや書き込み操作を行うと、その間システムはハングしてしまいます。
よくあるアプリケーションの誤りは、入出力を実行してエラーメッセージのテキストをディスクから取得することです。この処理は、独立した実時間ではないプロセスまたはスレッドから実行しなければなりません。
割り込みの優先順位は、プロセスの優先順位に左右されません。プロセスの優先順位を設定しても、プロセスの動作によって生じるハードウェア割り込みの優先順位は設定されません。つまり、実時間プロセスによって制御されるデバイスについての割り込み処理は、必ずしもタイムシェアリングプロセスによって制御される他のデバイスについての割り込み処理よりも前に実行されるとは限りません。
タイムシェアリングプロセスでは、動的にリンクされる共用ライブラリを使用すると、メモリ量をかなり節約できます。このようなタイプのリンクは、ファイルマッピングの形で実装されます。動的にリンクされたライブラリルーチンは、暗黙の読み取りを行います。
実時間プログラムでは、プログラムを起動する際に、環境変数 LD_BIND_NOW を非 NULL に設定すると、共用ライブラリを使用しても動的結合が行われないようにできます。このようにすると、プログラムの実行前に動的結合が実行されます。詳細は、『リンカーとライブラリ』を参照してください。
実時間プロセスが必要とする資源を、タイムシェアリングプロセスが取得すると、実時間プロセスをブロッキングできます。優先順位の反転とは、優先順位の高いプロセスが優先順位の低いプロセスによってブロッキングされる際に生じる状態です。「ブロッキング」とは、あるプロセスが、1 つまたは複数のプロセスが資源の制御を手放すのを待っている状態を指します。このブロッキングが長引くと、たとえ低レベル資源についてでも、デッドラインを逃してしまうことがあります。
図 8-1 の場合を例にとると、優先順位の低いプロセスが共用資源を保持しているために、その共用資源を使用したい優先順位の高いプロセスがブロッキングされています。この優先順位の低いプロセスは、中間の優先順位を持つプロセスによって横取りされます。この状態は長く続く場合があり、実際には優先順位の高いプロセスが資源を待たなければならない時間は、優先順位の低いプロセスによって危険領域が実行されている継続時間だけではなく、中間のプロセスがブロッキングされるまでの時間によって決まるので、どれだけ長く続くかわかりません。中間のプロセスは、いくつ関与していてもかまいません。
この問題とその対処方法については、『マルチスレッドのプログラミング』の「相互排他ロック属性」の節で説明しています。
ページは、ロッキングカウントが 65535 (0xFFFF) に達すると、メモリ内に永久にロッキングされます。0xFFFF の値は実装時に定義されており、将来のリリースで変更される可能性があります。このようにしてロッキングされたページのロッキングは解除できません。
ランナウェイ実時間プロセスは、システムを停止させたり、システムが停止したように見えるほどシステムの応答を遅くしたりすることがあります。
SPARCTM システム上にランナウェイプロセスがある場合は、Stop-A キーを押します。この手順を何回も繰り返さなければならない場合があります。この手順がうまく機能しない場合や SPARC 以外のシステムの場合は、電源を切ってからしばらく待ち、もう一度電源を入れてください。
優先順位の高い実時間プロセスが CPU の制御を手放さない場合、無限ループを強制的に終了させなければ、システムの制御は得られません。このようなランナウェイプロセスは、Control-C キーを入力しても応答しません。ランナウェイプロセスよりも高い優先順に設定されているシェルを使用しようとしても失敗します。
非同期入出力操作がカーネルへの待ち行列に入った順序で行われるという保証はありません。また、非同期操作が実行された順序で呼び出し側に戻されるという保証もありません。
aioread(3AIO) 呼び出しの高速シーケンスのために単一のバッファが指定されている場合、最初の呼び出しが行われてから最後の結果が呼び出し側にシグナルとして送信されるまでの間のバッファの状態については、保証されていません。
1 つの aio_result_t 構造体は、一度に 1 つの非同期読み取りまたは書き込みだけに使用してください。
SunOS 5.0 から 5.8 には、ファイルを確実に物理的に連続して割り当てる機能は用意されていません。
通常のファイルについては、read(2) と write(2) の操作は常にバッファリングされます。アプリケーションは mmap(2) と msync(3C) を使用して、二次記憶領域とプロセスメモリ間の入出力転送を直接実行できます。