コンテキストスイッチ
コンテキストスイッチ (context switch) とは、複数のプロセスが1つのCPUを共有できるように、CPUの状態(コンテキスト)を保存したり復元したりする過程のことである。コンテキストスイッチはマルチタスクオペレーティングシステムに不可欠な機能である。通常コンテキストスイッチは多くの計算機処理を必要とするため、オペレーティングシステムの設計においてはコンテキストスイッチを最適化することが重要である。
コンテキストスイッチの発生するケース
マルチタスキング
マルチタスク・オペレーティングシステムにおいては、実行中のプロセスは途中でCPUを明け渡し、他のプロセスも実行されるようにする必要がある。このプロセスの切り替えの際にコンテキストスイッチが発生する。
プリエンプティブなマルチタスクOSでは、スケジューラーが各プロセスを「タイムスライス」と呼ばれるある短い時間ずつ走行させる。 しかし、プロセスがその時間内にCPUを明け渡さなかった場合(明け渡すとは、例えばI/Oを行ってその完了を待つ場合など)、タイマ割り込みが発生し、OSが別のプロセスを走行させるようスケジュール設定しコンテキストスイッチが発生する。これによりCPUが計算ばかりするアプリケーションに占有されないようにするのである。
割り込み処理
割り込みが発生した時には、現在のプロセスの実行を停止して割り込みハンドラを実行する必要があるため、コンテキストスイッチが発生する。
リアルタイムOSの場合、プリエンプティブなタスクが実行中に割り込みが発生した時は、割り込み処理が終了しても停止させたタスクに実行権が戻るとは限らない。 割り込み処理終了時に停止させたタスクよりプライオリティの高いタスクが実行可能となっている場合はディスパッチが行われプライオリティの高いタスクを優先して処理するのが一般的である。
ユーザーモードとカーネルモードの切り替え
ユーザーモードとカーネルモード間の遷移が必要となった場合、コンテキストスイッチが発生する。システムコールはカーネルモードで実行されるので、これらの関数が呼び出される際にはまずカーネルのコンテキストを読み出し、システムコールを実行して、それから元のユーザーモードのコンテキストを復元する必要がある。
コンテキストスイッチの手順
コンテキストスイッチでは、実行中のプロセスの状態を何らかの方法で保存し、後にそのプロセスを再開する際にその状態を復元して、正常に実行を継続できるようにしなければならない。
プロセスの状態には、そのプロセスが使用し得る全てのレジスタ(特にプログラムカウンタ)や、プロセスの実行に必要となるオペレーティングシステム固有の情報が含まれる。多くの場合、これらのデータは1つのデータ構造として保存される。
プロセスを切り替えるためには、実行中のプロセスの状態を表すデータ構造を作成し、保存しなければならない。このデータは、カーネルメモリ上にあるプロセスごとに割り当てられるスタックか、あるいはオペレーティングシステムによって定義された固有のデータ構造に保存される。
様々な実装例
コンテキストスイッチはソフトウェアかハードウェアで実行される。インテルの80386やその後継CPUはハードウェアがコンテキストスイッチをサポートしていて、そのための特別なデータセグメント(タスク・ステート・セグメント、TSS)を用意している。タスクスイッチが発生すると(明示的にタスクを切り替える命令を実行するか、割り込みが発生したとき)、CPUは自動的に新しいコンテキストをTSSからロードする。このようにハードウェアでコンテキストスイッチを行うと高速だと思われるかもしれないが、Windowsを含めた主なOSはこの機能を使っていない。これは主にふたつの理由によるものである。まずハードウェアによるコンテキストスイッチは全部のレジスタをセーブしない(汎用レジスタだけで、浮動小数点レジスタもセーブしない)。もうひとつの理由は性能の問題である。
アーキテクチャによっては複数のコンテキストを同時に保持するハードウェアも存在する。その場合コンテキストをメモリに格納したりメモリから復帰させたりといったことをする必要がない。極端なケースとしてバレルプロセッサアーキテクチャではマシンサイクル毎にスレッド間でスイッチしながら動作する。