RunQueue
1. 概要
RunQueueにはRUNNING状態のプロセスがつながれる。スケジューラがプロセスの実行を管理するのに使用する。
2. RunQueueの構造
RunQueueの構造を図1に示す。
2.1 CPU毎のRunQueue
RunQueueはCPU毎に存在する。Running状態のプロセスはシステム内のいずれかのCPUに割り当てられ、対応するCPUのRunQueue(struct runqueue)に入れられる。
2.2 struct runqueue
struct runqueueがRunQueueの管理構造体。
struct runqueueはActive,Expiredの2種類のリストを持ち、ここにRUNNINGプロセスがつながれる。Active,Expiredリストはactive,expiredポインタによって指される。struct runqueue内のprio_array_t arrays[2]が2本のリストの管理テーブルの実体で、active,expiredポインタはそれぞれarray[0],[1]のどちらかを指すようになっている。Active,Expiredリストは定期的に入れ替わるが、この時はarray[0],[1]内のプロセスを移動させるのではなく、active,expiredのポイント先を入れ換えるだけよいようになっている。
フィールド |
意味 |
---|---|
nr_running |
RUNNINGプロセス数(active,expiredにつながれている総プロセス数) |
active |
CPU時間が残っているRUNNINGプロセスが保持される。優先度毎にリストがある。 |
expired |
CPU時間を使い切ったRUNNINGプロセスが保持される。優先度毎にリストがある。 |
expired_timestamp |
expireに初めてプロセスを移動した時間。 active<->expireの入れ換えをしたり、IDLE状態になるとクリアされる。 |
2.3 Active,Expiredリスト
Activeリストは、現QuantumでまだCPU時間が残っているプロセスがチェーンされ、ExpiredリストにはCPU時間を使い切ったプロセスがチェーンされる。スケジューラはActiveリスト内のプロセス間でスケジューリングを行う。
CPU時間を使い切ったプロセスはExpiredリストに移動されスケジューリングの対象外となり、ここで、全RUNNINGプロセスがCPU時間を使い切るのを待つ。
Activeリストの全プロセスがCPU時間を使いきってActiveリストが空になると、Active,Expiredリストを入れ換えて、新たにCPU時間が割り当てられ(*1)、スケジューリングが再開される。
Linux2.2 ではActive,Expireリストはなく、リストが一つだったので、スケジューリングの際、CPU時間を使い切ったRUNNINGプロセスを毎回読み 飛ばしていた。CPU時間が残っているプロセスと使いきったプロセスの区別を軽くするために用意された。
2.4 struct prio_array
Active,Expiredリストの管理構造体であるstruct prio_arrayの構造を図2に示す。
図2 struct prio_array
struct prio_arrayは単純な1本のリストではなくプロセスの優先度毎(0-139)にリストを持ち、RUNNING状態のプロセス(struct task_struct)は自分の動的優先度に該当するリストにつながれる。優先度毎にリストを持つことで最高優先度のプロセスを高速に取りだせる。
nr_activeにはPrio0〜139のリストにチェーンされているプロセスの総数が格納されている。
bitmapはPrio0〜139のリストの使用/未使用ビットマップでリストにプロセスがチェーンされている場合はビットが立つようになっており、最高優先度のプロセスを高速に取り出すことができる。
3. 関連関数
enqueue_task(struct task_struct *p, prio_array_t *array)dequeue_task(struct task_struct *p, prio_array_t *array)