MI_SWITCH(9)

名称
mi_switch, cpu_switch, cpu_throw - 別のスレッドコンテキストへのスイッチ

書式
<sys/param.h> <sys/proc.h> void mi_switch(void) void cpu_switch(void) void cpu_throw(void)

解説
mi_switch() 関数はマシン非依存なスレッドコンテキストスイッチの前処理を実装しています。 横取り不可能なカーネルモード実行の方針の結果として、カーネル内の数少ない 区別された場所からのみ呼び出されます。 いくつかの主な mi_switch の使用は以下に挙げられます。

1.  sleep(9), tsleep(9) および msleep の中から、あるリソースが利用可能になるのを待つために 現在のスレッドが自発的に CPU を放棄するとき。

2.  トラップ (例えば、システムコール、デバイス割り込み) の取り扱いの後で、 カーネルがユーザモード実行のために戻る準備のとき。 通常この場合は、現在のプロセスのシグナル配置の中の変化の検出の後で マシン依存のトラップハンドリングコードによって取り扱われるか、 より高い優先度のスレッドが実行可能になったかもしれないときです。 後者のイベントはマシン定義の need_resched() の呼び出しによるマシン非依存のスケジューリングルーチンによって伝達されます。

3.  シグナルハンドラコード ((issignal) 9 を参照) の中で、プロセスを停止させるシグナルが届けられた場合。

4.  スレッドが thread_exit(9) の中で終了し、プロセッサの制御が次の実行可能のスレッドに渡されることが 可能なとき。

5.  thread_suspend_check(9) 中で、全体としてのプロセスの停止状態のために、 スレッドが実行を停止する必要がある 場合。

mi_switch() はプロセス構造体の中に現在のプロセスが実行された時間量を記録して、 そのスレッドに割当てられている CPU の時間リミット ((getrlimit) 2 を参照) に照らしてこの値を検査します。 ソフトリミットの超過はそのプロセスに SIGXCPU シグナルが配信される結果を招き、一方ハードリミットの超過は SIGKILL を引き起こします。 これらの管理上の仕事が完了した後で、 mi_switch() は実際にプロセスコンテキストスイッチを行なうマシン依存ルーチン cpu_switch() に制御を引き渡します。

cpu_switch() は優先度キューデータ構造において、 実行準備のできているプロセスの中から選択します。 優先度キューは、キュー先頭構造体である配列 qs[NQS] で構成されます。 個々のキュー先頭構造体により、 同じ優先度の実行可能なプロセスのリストを識別します (<sys/proc.h> を参照)。 単一の語 whichqs は、空ではないキューが分かるビットマスクを含み、 素早くプロセスを選択することを助けます。 cpu_switch() は最も高い優先度を持つキュー上のリスト (qs の中の低いインデックスが高い優先度を示す) から最初のプロセスを削除しなければならず、グローバル変数 curproc にそのプロセス構造体のアドレスを割当てなければなりません。 実行キュー上に利用可能なプロセスがない場合には、 cpu_switch() は “idle” ループに移行することになっています。 idle ループは割り込みを許可する必要があります。 これにより、やがてプロセスが実行キュー上に再び現れます。 cpu_switch() がこの発生を待っている間は変数 curproc は NULL であるべきです。

mi_switch() および当然 cpu_switch() は splhigh() で呼び出されるべきであることに注意してください。

関連項目
issignal(9), spl(9), tsleep(9), wakeup(9)