0.4 カーネルプリミティブ

 Linuxカーネルを理解するためには、最初にカーネルの動きをつかさどる機能を知ることが重要でしょう。Linuxカーネル内では、さまざまな処理が非同期に動作します。この動作を制御する機構を見ていきましょう。本書のPart 1の話題です。

0.4.1 プロセススケジューラ

 Linuxカーネルはマルチタスク環境を提供します。Linux上では複数のプロセスが並列に実行されます。並列とはいっても、実際にはCPU数以上のプロセスが本当に同時実行されるわけではありません。複数のプロセスに対し、実行権を交互に与えるため、いかにも同時に実行しているように見えるのです。

 このようなプロセスを管理する機能はプロセススケジューラと呼ばれています(図0-3)。Linuxカーネルのプロセススケジューラは、プロセス間のスケジューリングの公平性を確保しつつ、なるべくスループットを落とさずに、応答性を確保できるような仕組みを採用しています。

 「第1章 プロセススケジューリング」では、その設計方針から実装までを含めて説明します。

0.4.2 割り込み処理と遅延処理

 ハードウェアからの事象は、割り込みという形でLinuxカーネルに伝えられます。Linuxカーネルは、発生した割り込みに応じた割り込み処理を実行します。

 割り込みは、主にハードウェアを制御するデバイスドライバと、時計の機能が利用しています。割り込みが発生すると、Linuxカーネルはいったんそのとき実行していた処理を中断し、割り込み処理を起動します。割り込み処理はその要因となった割り込みに対応した処理を行い、割り込み処理が完了すると、Linuxカーネルは中断していた処理を何事もなかったかのように再開します。

 割り込み処理自体の応答性の向上と、システム全体に与える負荷を軽減する目的で、Linuxカーネルではソフト割り込みと呼ばれる割り込み処理を遅延させる仕組みが実装されています。伝統UNIXは応答性を確保するために、割り込みレベルという概念を用いていますが、Linuxカーネルは別のアプローチとなっています。

 「第2章 割り込み」、「第3章 遅延処理」では、Linux独特の実装方式を説明します。

0.4.3 時計

 Linuxカーネルは自身の時計を持っています。ハードウェアから一定周期で発生する割り込みを捕らえ、割り込み処理として時計処理を動かします。時計処理では、時刻の計算のほかに、各種時限処理を行います。時限処理とは、一定時間の経過後に指定された処理を実行する機能で、ネットワークプロトコルスタックや、デバイスドライバが多用しています。Linuxカーネルの時限処理は、効率を重視した非常に凝った実装になっています。

 「第4章 時計」において、正確に時間を守るための仕組みを説明します。

0.4.4 システムコール

 システムコールは、アプリケーションがカーネルに対して要求を行うための唯一の手段です。アプリケーションから見ると、システムコールは魔法のライブラリ関数のように見えます。

 システムコールを発行すると、アプリケーションの実行を一時中断し、Linuxカーネルコードの実行を開始します。Linuxカーネルの実装では、システムコール処理はプロセスのコンテキストの延長で実行されます(システムコールがプロセス間通信として実現されているOSも存在します)。システムコール処理が完了するとアプリケーションの実行を再開します。システムコールが失敗した場合は、通常の関数のようにエラーコードを返します。

 Linuxカーネルは、CPUが提供する保護機能を利用して、ユーザープロセスからLinuxカーネルが配置されているメモリを直接アクセスできないようにしています。システムコールは、CPUの実行レベルを変更し、カーネルコードの実行を許しますが、アクセス手順は厳格に定義されており、カーネルコードやカーネルデータは自由に参照/変更できません。

 「第5章 システムコール」において、二種類のシステムコールの発行方法を解説します。旧来のシステムコール発行の仕組みに加え、新しいx86 CPUがサポートするsysenter命令を用いた高速なシステムコール発行が可能です。

0.4.5 同期と排他

 カーネル内には、上に述べたさまざまな実行の流れが存在します。複数の流れが同時に存在し、おのおのが独立して動作しています。これら複数の流れは、状況によって協調して動作する必要もあります。そのため、Linuxカーネルは、排他や同期を取るための機能を数種類用意しており、目的に応じて使い分けています。

 複数のプロセスが同一資源を操作するような場合は、セマフォを利用するのが便利です。マルチプロセッサ環境時に、CPU間で同時に参照されるデータを保護するためには、スピンロックと呼ばれている機構を利用するのが最も一般的です。さらにLinuxカーネルでは、CPU間にまたがる資源排他を効率的に行うRCU(Read CopyUpdate)やシーケンスカウンタロックという機構も導入しています。

 「第6章 同期と排他」において、排他機構をひとつひとつについて、その動きを解説します。