プログラミングインタフェース

ディスパッチ応答時間

リアルタイムアプリケーションをスケジューリングする際にもっとも重要な要素は、リアルタイムスケジューリングクラスを用意することです。標準のタイムシェアリングのスケジューリングクラスはどのプロセスも平等に扱い、優先順位の概念に制限があります。したがって、リアルタイムアプリケーションには適しません。リアルタイムアプリケーションは、プロセスの優先順位が絶対的なものとして受け取られるスケジューリングクラスを必要とします。リアルタイムアプリケーションはまた、プロセスの優先順位がアプリケーションの明示的な操作でしか変更されないスケジューリングクラスを必要とします。

ディスパッチ応答時間」とは、プロセスの操作開始の要求にシステムが応答するまでの時間を指します。アプリケーションの優先順位を尊重するように特別に作成されたスケジューラを使用すると、ディスパッチ応答時間を制限したリアルタイムアプリケーションを開発できます。

次の図に、あるアプリケーションが外部イベントからの要求に応答するまでの時間を示します。

図 12–2 アプリケーション応答時間

この図は、制限されない優先順位の逆転を示しています。

全体のアプリケーション応答時間には、割り込み応答時間、ディスパッチ応答時間、およびアプリケーションの応答時間が含まれます。

アプリケーションの割り込み応答時間には、システムの割り込み応答時間とデバイスドライバ独自の割り込み処理時間が含まれます。割り込み応答時間は、システムが割り込みを無効にして実行する必要がある最長の間隔によって決まります。SunOS では、この時間を最小限にするために、通常はプロセッサの割り込みレベルを上げる必要がない同期プリミティブを使用しています。

割り込み処理中、ドライバの割り込みルーチンはまず、優先順位が高いプロセスを呼び起こし、そのプロセスが終了すると戻ります。割り込まれたプロセスよりも優先順位が高いプロセスが現在ディスパッチ可能であることを検出すると、システムは (優先順位が高い) プロセスをディスパッチします。優先順位が低いプロセスから高いプロセスへコンテキストを切り換える時間は、ディスパッチ応答時間に含まれます。

図 12–3 に、システムの内部イベントのディスパッチ応答時間とアプリケーション応答時間を示します。アプリケーション応答時間は、システムが内部イベントに応答するまでに必要な時間のことです。内部イベントのディスパッチ応答時間とは、あるプロセスが優先順位がより高いプロセスを呼び起こすまでに必要な時間のことです。このディスパッチ応答時間には、システムが優先順位がより高いプロセスをディスパッチするまでに必要な時間も含まれます。

アプリケーション応答時間とは、ドライバが次の作業を完了するまでに必要な時間のことです。 つまり、優先順位がより高いプロセスを呼び起こし、優先順位が低いプロセスから資源を解放し、優先順位がより高いタスクをスケジューリングし直し、応答を計算し、タスクをディスパッチすることです。

ディスパッチ応答時間のインターバルの間に割り込みが入って処理されることがあります。この処理でアプリケーション応答時間は増えますが、ディスパッチ応答時間の測定には影響を与えません。したがって、この処理はディスパッチ応答時間の保証には制限されません。

図 12–3 内部ディスパッチ応答時間

この図は、内部ディスパッチ応答時間のコンポーネント、 呼び起こしとディスパッチを示します。

リアルタイム SunOS に用意されている新しいスケジューリング手法を使用すると、システムのディスパッチ応答時間を指定された範囲に限定できます。次の表に示すように、プロセス数を制限するとディスパッチ応答時間が改善されます。

表 12–1 リアルタイムシステムディスパッチ応答時間

ワークステーション 

制限されたプロセス数 

任意のプロセス数 

SPARCstation 2 

動作中のプロセスが 16 個未満の場合は、システム内で 0.5 ミリ秒未満 

1.0 ミリ秒 

SPARCstation 5 

0.3 ミリ秒未満 

0.3 ミリ秒 

スケジューリングクラス

SunOS のカーネルは、プロセスを優先順位によってディスパッチします。スケジューラ (またはディスパッチャー) は、スケジューリングクラスの概念をサポートしています。クラスは、リアルタイム (RT)、システム (sys)、およびタイムシェアリング (TS) として定義されます。各クラスには、プロセスをディスパッチするための固有のスケジューリング方式があります。

カーネルは、もっとも優先順位が高いプロセスを最初にディスパッチします。デフォルトでは、リアルタイムプロセスが sysTS のプロセスよりも優先されます。システム管理者は、TSRT のプロセスの優先順位が重なり合うように設定することもできます。

次の図に、SunOS カーネルから見たクラスの概念を示します。

図 12–4 スケジューリングクラスのディスパッチ優先順位

この図は、リアルタイム、カーネル、およびタイムシェアリングのプロセスからのソフトウェア割り込みよりも優先順位が高いハードウェアシステム割り込みを示します。

ハードウェア割り込みは優先順位がもっとも高いので、ソフトウェアでは制御できません。割り込みを処理するルーチンは、割り込みが生じるとただちに直接ディスパッチされ、その際には現在のプロセスの優先順位は考慮されません。

リアルタイムプロセス (RT) は、ソフトウェアではもっとも高い優先順位をデフォルトで持ちます。RT クラスのプロセスは、優先順位とタイムカンタム (time quantum) 値を持ちます。RT プロセスは、厳密にこれらのパラメータに基づいてスケジューリングされます。RT プロセスが実行可能である限り、SYSTS のプロセスは実行できません。固定優先順位スケジューリングでは、クリティカルプロセスを完了まで事前に指定された順序で実行できます。この優先順位は、アプリケーションで変更されない限り変わりません。

RT クラスのプロセスは、有限無限を問わず親プロセスのタイムカンタムを継承します。有限タイムカンタムを持つプロセスは、タイムカンタムの有効期限が切れるまで実行されます。有限タイムカンタムを持つプロセスはまた、入出力イベントを待つ間ブロックされるか、またはより高い優先順位を持つ実行可能なリアルタイムプロセスに横取りされるまで実行されます。無限タイムカンタムを持つプロセスは、プロセスが終了するか、ブロックされるか、または横取りされるまで実行されます。

SYS クラスは、ページング、STREAMS、スワッピングなどの特殊なシステムプロセスをスケジューリングするために存在します。通常のプロセスのクラスは SYS クラスには変更できません。プロセスの SYS クラスは、プロセスの開始時にカーネルによって確立された固定優先順位を持っています。

優先順位がもっとも低いのは、タイムシェアリング (TS) クラスです。TS クラスのプロセスは、各タイムスライスを数百ミリ秒として動的にスケジューリングされます。TS スケジューラは、次の値に基づいて、ラウンドロビン方式でコンテキストを切り換えることによって、すべてのプロセスに平等な機会を提供します。

デフォルトのタイムシェアリング方式では、優先順位が低いプロセスに長いタイムスライスが与えられます。

子プロセスは fork(2) を通じて、親プロセスのスケジューリングクラスと属性を継承します。exec(2) を実行しても、プロセスのスケジューリングクラスと属性は変わりません。

各スケジューリングクラスは、異なったアルゴリズムによってディスパッチされます。クラスに依存するルーチンはカーネルによって呼び出され、CPU のプロセススケジューリングが決定されます。カーネルはクラスから独立しており、優先順位がもっとも高いプロセスを待ち行列内から取り出します。各クラスは、自分のクラスのプロセスの優先順位値を計算しなければなりません。この値は、そのプロセスのディスパッチ優先順位変数に入れられます。

次の図に示すように、各クラスのアルゴリズムは独自の方法で優先順位がもっとも高いプロセスを選択して、グローバル実行待ち行列に入れます。

図 12–5 カーネルディスパッチ待ち行列

この図は、制限されない優先順位の逆転を示しています。

各クラスには、そのクラスのプロセスに適用される優先順位レベルのセットがあります。クラス固有のマッピングによって、この優先順位がグローバル優先順位のセットに割り当てられます。グローバルスケジューリング優先順位マッピングセットは、0 で始まっていたり、連続したりしている必要はありません。

デフォルトでは、タイムシェアリング (TS) プロセスのグローバル優先順位の値は -20 から +20 までの範囲です。このようなグローバル優先順位の値はカーネルの 0 から 40 までに割り当てられており、一時的な割り当ては 99 まであります。リアルタイム (RT) プロセスのデフォルトの優先順位は 0 から 59 までの範囲で、カーネルの 100 から 159 までに割り当てられます。カーネルのクラスに依存しないコードは、待ち行列内のグローバル優先順位のもっとも高いプロセスを実行します。

ディスパッチ待ち行列

ディスパッチ待ち行列は、同じグローバル優先順位を持つプロセスが直線的にリンクしたリストです。各プロセスには起動時に、クラス固有な情報が付けられます。プロセスは、グローバル優先順位に基づく順番で、カーネルのディスパッチテーブルからディスパッチされます。

プロセスのディスパッチ

プロセスがディスパッチされると、メモリー管理情報、レジスタ、スタックとともに、プロセスのコンテキストがメモリー内に割り当てられます。コンテキストマッピングが完了したあと、実行が始まります。メモリー管理情報はハードウェアレジスタの形式をしており、現在実行中のプロセスのために仮想メモリー変換を実行するときに必要となるデータが入っています。

プロセスの横取り

より高い優先順位を持つプロセスがディスパッチ可能になると、カーネルはコンピュータ操作に割り込んで強制的にコンテキストを切り換え、現在実行中のプロセスを横取りします。より高い優先順位のプロセスがディスパッチ可能になったことをカーネルが見つけると、プロセスはいつでも横取りされます。

たとえば、プロセス A が周辺デバイスから読み取りを行なっているとします。プロセス A はカーネルによって休眠状態に置かれます。次に、カーネルはより優先順位の低いプロセス B が実行可能になったのに気づきます。すると、プロセス B がディスパッチされ、実行が始まります。ここで周辺デバイスが割り込みを送信し、デバイスドライバの処理に入ります。デバイスドライバはプロセス A を実行可能にして戻ります。ここで、カーネルは割り込まれたプロセス B に戻るのではなく、B の処理を横取りして、呼び起こされたプロセス A の実行を再開します。

もう 1 つの重要な例としては、複数のプロセスがカーネル資源を争奪する場合があります。たとえば、優先順位の高いリアルタイムプロセスが優先順位の低いプロセスが持っている資源を待っていると仮定します。このとき、優先順位の低いプロセスがその資源を解放すると、カーネルは優先順位の低いプロセスを横取りして、優先順位の高いプロセスの実行を再開します。

カーネル優先順位の逆転

優先順位の逆転は、優先順位の高いプロセスが 1 つまたは複数の優先順位の低いプロセスによって長時間ブロックされた場合に生じます。SunOS のカーネルで相互排他ロックなどの同期プリミティブを使用すると、優先順位の逆転につながることがあります。

ブロック化」とは、あるプロセスが 1 つまたは複数のプロセスが資源を手放すのを待たなければならない状態のことです。このブロック化が継続すると、使用レベルが低いものでもデッドラインに間に合わないことがあります。

相互排他ロックによって優先順位が逆転する問題については、SunOS のカーネルで基本的な優先順位継承方式を実装することによって対応しています。この方式では、優先順位の低いプロセスが優先順位の高いプロセスの実行をブロックすると、優先順位の低いプロセスが優先順位の高いプロセスの優先順位を継承することになります。この継承のため、プロセスがブロック化されている時間の上限が設定されます。この方式はカーネルの動作であり、プログラマがシステムコールやインタフェースの実行によって講じる解決策ではありません。ただし、この場合でもユーザーレベルのプロセスは優先順位の逆転を生じることがあります。

ユーザー優先順位の逆転

ユーザー優先順位が逆転する問題とその対処方法については、『マルチスレッドのプログラミング』「相互排他ロック属性」の節を参照してください。