プリエンプション
古いUnixでは、システムコールを発行してカーネル内のコードを実行している時は、他のプロセスにコンテキストスイッチすることはない(I/O待ちなどで自分からBlockしない限り)。
Linuxなんかだと、configでプリエンプションを有効にしておけば、カーネル内のコードを実行中でもコンテキストスイッチが発生する。これにより、システムのレスポンスの向上が期待できる。Xnuでも同じことができる。
プリエンプションはASTを使って切り替えている。ast_on(AST_PREEMPT | AST_URGENT)のようにして、プリエンプションをスケジュールする。スケジュール後、遅延してASTハンドラ(ast_taken())が動作しプリエンプションが行なわれる。プリエンプションを禁止(CPU_PREEMPTION_LEVEL!=0)にするとlocore.s内のルーチンからi386_astintr()が呼ばれなくなりコンテキストスイッチが発生しなくなる。
[関連関数]
disable_preemption()
mp_disable_preemption()
mp_enable_preemption()
preemption_enabled()
Linuxなんかだと、configでプリエンプションを有効にしておけば、カーネル内のコードを実行中でもコンテキストスイッチが発生する。これにより、システムのレスポンスの向上が期待できる。Xnuでも同じことができる。
プリエンプションはASTを使って切り替えている。ast_on(AST_PREEMPT | AST_URGENT)のようにして、プリエンプションをスケジュールする。スケジュール後、遅延してASTハンドラ(ast_taken())が動作しプリエンプションが行なわれる。プリエンプションを禁止(CPU_PREEMPTION_LEVEL!=0)にするとlocore.s内のルーチンからi386_astintr()が呼ばれなくなりコンテキストスイッチが発生しなくなる。
[関連関数]
disable_preemption()
プリエンプション禁止状態にする。
自CPUのcpu_data_t内のcpu_preemption_levelをインクリメントする。0の時がプリエンプト可能状態。
enable_preemption()プリエンプションを許可状態にする。
mp_disable_preemption()
mp_enable_preemption()
preemption_enabled()
プリエンプション可能な状態か返す。
プリエンプションレベル(get_preemption_level())が0で割り込みも許可状態であればTRUE。
プリエンプションレベル(get_preemption_level())が0で割り込みも許可状態であればTRUE。