OS自作入門 -Advent32-

NO IMAGE

Step9 優先度スケジューリング 前半戦

step8にてスレッドの実装が完了した。これまでの方式は「ラウンドロビン方式」でありキューを使ったFIFOの仕組みで動作している。これを優先度をつけたスレッドにして優先度順にスレッドを実行するようにしていこう。

優先度ベースのスケジューリング

スレッドのスリープ

それぞれのスレッドが独立しているならいいが、依存関係にあったり同期をとる必要があるようなスレッドは「待ち」が発生する。今回はまずこの「スレッドの待ち」状態を作成する。

作り方の方針としては、レディー・キューからスレッドを抜けば実行されなくなるので待ち状態となる。再びレディーキューに追加すればスケジューリングされることおになる。というようなものにする。

スレッドが待ち状態に入ることを スリープ と呼ぶ。反対に実行可能な状態(レディーキューに積まれているとき)を レディー と呼ぶ。

優先度とプリエンプション

step8までのスレッドの機構では、スレッドの実行はシステム・コールを契機にして順番に実行されるようになっている。スレッドがシステム・コールを呼ぶと、別スレッドに切り替わるようになっている。そのためスレッドの動作が再開するのは、別のスレッドの実行が一通り終わった後ということになる。しかし、これでは困ることがある。緊急度の高いスレッドの実行がある場合である。必ず一定時間内に処理を開始することができるかどうか、時間保証が行えるかどうかをOSの リアルタイム性 と呼ぶ。これまでのラウンドロビン方式では、スレッドに関係なく後発のスレッドには待ちが発生するのでリアルタイム性を保証することはできない。そのため、スレッドに「優先度」をつけ「優先度の高いスレッドが動作可能になった場合には、優先度の低いスレッドの動作は中断して、優先度の高いスレッドを動作させる」というスケジューリングをする必要がある。

このようにあるスレッドの動作が突如中断され、別のスレッドに強制的に切り替わることを プリエンプション と呼ぶ。(逆のことは ノン・プリエンティブ と呼ぶ)

アイドル・スレッド

やることがないときにCPUを省電力モードにするための アイドル・スレッド というものがある。

これまではやることがなくなった場合には、システム・ダウン状態に移行していた。これを防ぐために、最も低い優先度で「無駄な処理」を常に動かしておけば良い。さらにstep7でやったように、CPUの省電力モードに移行する処理を入れて、

while(1) {
  (省電力モードに移行);
}

という内容のスレッドを実行しておけば良い。すなわちアイドル・スレッドで省電力モードに移行することで、割込みが発生するまで待機することになる(省電力モードのwakeupは割込みドリブン)。


少々短いが次回から実装に入るので今日はここまで。珍しく解説が短いstepだったな。何かで読んだがstep8が一番難しいとのことで山場は切り抜けているはずだと信じたい。