EN JA
MI_SWITCH(9)
MI_SWITCH(9) FreeBSD Kernel Developer's Manual MI_SWITCH(9)

名称

mi_switch, cpu_switch, cpu_throw別のスレッドのコンテキストに切り替える

書式

#include < sys/param.h>
#include < sys/proc.h>

void
mi_switch( void);

void
cpu_switch( void);

void
cpu_throw( void);

解説

mi_switch() 関数は、スレッドのコンテキストスイッチのマシン独立な前段階を実装しています。それは、プリエンプティブ可能でないカーネルモード実行の方式の結果としてカーネルコードの少数の区別された場所からのみ呼び出されます。次のように mi_switch の様々な主な用途を列挙することができます:
  1. cv_wait(9), mtx_lock(9) または tsleep(9) のような関数の内部で、いくつかのリソース、またはロックが利用可能になるのを待つ (ウェートする) ために、現在のスレッドが、自発的に CPU を放棄するとき。
  2. トラップ (例えば、システムコール、デバイスの割り込み) を操作した後で、カーネルがユーザモードの実行に返る準備するとき。通常、この場合は、現在のプロセスのシグナル処理の変更の検出の後、または高い優先度のスレッドが実行するために利用可能なとき、マシン依存のトラップ処理コードによって操作されます。後者のイベントは、マシンで定義された need_resched() を呼び出すことによって、マシン独立のスケジューリングルーチンによって通信されます。
  3. シグナルハンドリングコード ( issignal(9) を参照) で、プロセスを停止するシグナルが配信される場合。
  4. スレッドが thread_exit(9) で死に、プロセッサの制御を次の実行可能なスレッドに渡すとき。
  5. スレッドが全体としてプロセスのサスペンション (suspension) 状態のために実行を停止する必要のある thread_suspend_check(9) で。

mi_switch() は、現在のスレッドがプロセス構造体で実行している時間の量を記録し、プロセスに割り付けられた CPU 時間の制限 ( getrlimit(2) を参照) とこの値をチェックします。ソフト制限を越えることは、プロセスに配信される SIGXCPU シグナルの結果となり、一方、ハード制限を越えることは、 SIGKILL を引き起こします。

スレッドがまだ TDS_RUNNING 状態であるなら、 mi_switch() は、すぐ再び実行したいと仮定する、実行キューにそれを戻します。それが他の状態の 1 つであり、KSE スレッドが有効にされているなら、関連する KSE は、それらが次にスケジュールされるのを可能にするために、同じグループからあらゆるより高い優先スレッドを利用可能とします。

これらの管理上のタスクが終了した後に、 mi_switch() は、実際のスレッドのコンテキストスイッチを実行する、マシン依存のルーチン cpu_switch() に制御を引き渡します。

cpu_switch() は、最初に現在のスレッドのコンテキストを保存します。次に、次を実行するスレッドを決定するために choosethread() を呼び出します。最後に、それは、新しいスレッドの保存されたコンテキストを読み込み、新しいスレッドを実行し始めます。

cpu_throw() は、古いスレッドのコンテキストを保存しないことを除いて、 cpu_switch() に似ています。カーネルに、保存する古いスレッドのコンテキストがないとき、ブート CPU 以外の CPU が、それらの最初のタスクスイッチを実行するとき、またはカーネルが現在のスレッドを終了し、新しいスレッドに切り替わるとき、 thread_exit() のような、古いスレッドの状態にカーネルが、関心がないとき、この関数は、役に立ちます。

runqueue(9) を保護するために、これらのすべての関数は、保持されている sched_lock ミューテックス (mutex) で呼び出されなければなりません。

November 24, 1996 FreeBSD