次に、指定した仮想CPUを、実行可能状態から待機状態に遷移させるsedf_sleep関数の動きを見てみましょう(リスト2)。まず、指定された仮想CPUがアイドルドメインのものであった場合は、要求を無視し(B1)、指定された仮想CPUに、待機状態を示すフラグを立てておきます(B2)。
指定された仮想CPUが、まさに実行中の仮想CPUであった場合(B3)、その仮想CPUが動作している実CPUに対し、再スケジューリングのためのソフトウェア割り込み*(SCHEDULE_SOFTIRQ)を要求します(B4)。また、ソフトウェア割り込み要求を受けた実CPUでは、ソフトウェア割り込みハンドラとしてドメインスケジューラ__enter_scheduler()が実行されます。
指定された仮想CPUが実行中でなかった場合、その仮想CPUをrunnableqキューもしくはwaitqキューから抜き取ります(B5)。また、もしextraqにつながっていたならば、extraqキュー(penaltyキュー、utilizationキューの両方)から外してしまいます(B6、B7)。
最後に、指定した仮想CPUを、待機状態から実行可能状態に遷移させるsedf_wake関数の動きを見てみましょう(リスト3)。この関数は、sedf_sleep関数の逆の動作を行います。まず、指定された仮想CPUがアイドルドメインのものであった場合、無視します(C2)。また、指定された仮想CPUがすでに実行可能状態にある場合、起床処理は不要なので、何も処理せずに終了します(C3)。この判断は、runnableqキューかwaitqキュー上に、指定された仮想CPUが登録されているか否かで行っています。この部分をもう少し細かく見てみましょう。
C4では、待機状態を示すフラグを落としています。また、起床した仮想CPUのデッドラインが未設定であった場合は、このタイミングで設定します(C6、この仮想CPUの周期がいま始まったものとして設定します)。
次に、extraqキューの設定を行います。起床した仮想CPUの周期がまだ始まっていない場合(C7)、補償時間および有効利用時間で動作させることを試みます。仮想CPUの属するドメインが補償時間を使って動作中であった場合(C8)、再度penaltyキューに登録します(C9、extraq_add_sort_update関数)。また、ドメインが有効利用時間を使う設定であった場合、その仮想CPUをutilizationキューにも登録します(C10、extraq_check_add_unblocked関数)。
仮想CPUが周期中に起床した場合(C11)、その仮想CPUに補償時間を与え、penaltyキューに登録します(C12、unblock_short_extra_support関数)。短い時間の待機は、I/O完了待ちであったと判断し、補償時間を与えるようになっているのです。このとき、同時にutilizationキューにもつないでおきます(C15、extraq_check_add_unblocked関数)。
長時間待機状態にあった仮想CPUが起床した場合は、補償時間は与えません。単純に行うべき仕事がなく停止していたと判断し、新たに周期とデッドラインを再設定します(C14、unblock_long_cons_b関数)。この場合も、ほかに動作するものがないときに実行権を与えるutilizationキューには登録しておきます(C15、extraq_check_add_unblocked関数)。
extraqキューに続いて、runnableqキュー、waitqキューの設定を行います。起床した仮想CPUの周期がまだ始まっていなければ、waitqキューに登録し(C16)、周期が始まっていればrunnableqキューに登録します(C17)。
仮想CPUの起床によってプリエンプトが必要になったならば(C18)、ソフトウェア割り込みを利用して再スケジューリング要求を行います(C19)。発生条件については「プリエンプション」の節にて、すでに説明してありますね ;-)。そちらを参照してください。
最後に、sedfスケジューラの主な関数と、パラメータをまとめておきます(表2、3)。
関数名 | 説明 |
---|---|
sedf_do_schedule() | 次に動作すべき仮想CPUを選択する |
sedf_sleep() | 指定した仮想CPUを、スケジューリング対象から外す |
sedf_wake() | 指定した仮想CPUを、スケジューリング対象にする |
sedf_adjdom() | 指定したドメインのスケジューリング用パラメータを変更する。または、取得する |
sedf_set_affinity() | 仮想CPUを割り付ける実CPUを変更する |
sedf_alloc_task() | sedfスケジューラ固有データ構造の確保 |
sedf_add_task() | sedfスケジューラ固有データ構造の初期化 |
sedf_free_task() | sedfスケジューラ固有データ構造の解放 |
ドメイン | 周期 | 割り当て時間 | 有効利用時間 | 補足説明 |
---|---|---|---|---|
ドメイン0 | 20ミリ秒 | 15ミリ秒 | 利用 | 割り当て時間保証 |
ドメインU | 100ミリ秒 | 自動計算 | 優先利用 | ベストエフォート |
ソフトウェア割り込みに関しては、割り込みの回に説明。
Copyright © ITmedia, Inc. All Rights Reserved.