Skip to main content

Module scheduler

Module scheduler 

Source
Expand description

§優先度ベースのプリエンプティブ・ラウンドロビン・スケジューラ

このモジュールは、各CPUコアごとに独立したランキューを持つ(Per-Core SMP)、優先度ベースのプリエンプティブ・ラウンドロビン・スケジューラの実装を提供します。 EL1カーネルスレッドとEL0ユーザープロセスの両方のマルチプロセス環境をサポートしています。

Structs§

CoreRunqueue
各コアで動作するプロセスのランキュー構造体。
Process
プロセス制御ブロック (PCB)。プロセスのメタデータ、実行コンテキスト、スタック情報を保持します。

Enums§

Priority
プロセスのスケジュール優先度を表す列挙型。
ProcessState
プロセスの状態を表す列挙型。

Statics§

NEXT_PID 🔒
次に割り当てるべきプロセスIDを管理するアトミックカウンタ。
PREEMPT_COUNTS 🔒
各コアごとのプリエンプション禁止カウンタ。 preempt_count == 0 の時のみプリエンプション(強制タスク切り替え)が許可されます。
RUNQUEUES 🔒
各コア固有のランキュー (Per-Core Runqueues)。 各コアが独立してランキューに対する排他制御(Mutex)を行います。
ZOMBIES 🔒
終了したプロセスの「墓場」。 exit() は現在実行中のプロセスのカーネルスタック上で動作するため、 その場で Process をドロップすると自身のスタックを解放してしまい、Use-After-Free が発生します。 そのため、一度この墓場領域に退避させ、別のプロセスへのコンテキストスイッチが行われた後 (そのスタックから外れた後)に、reap_zombies() を通じて安全にメモリを解放します。

Functions§

core_id
現在実行中のCPUコアのID (0〜3) を取得します。 mpidr_el1 レジスタからアフィニティレベル0を取得します。
current_sp 🔒
現在のスタックポインタ (SP) の値を取得します。
decrement_wait_ticks
待機状態 (Waiting) にある全プロセスの待ち時間チック数をデクリメントします。 チック数が0になったプロセスは実行可能状態 (Ready) に戻ります。
enter_userspace 🔒
exit
呼び出し元のプロセスを終了させます。
get_current_page_table
現在の CPU コアで実行されているプロセスの TTBR0 ページテーブル物理アドレスを取得します。
get_current_process_id
現在実行中のプロセスのPIDを取得します。 try_lock が失敗した場合は None を返します。
get_current_process_name
現在実行中のプロセスの名前を取得します。 try_lock が失敗した場合は None を返します。
get_process_page_table
指定した PID を持つプロセスの TTBR0 ページテーブル物理アドレスを取得します。
init
スケジューラの初期化処理。 起動コア (Core 0) 用の初期プロセス kernel_main を登録し、他のコアのランキューを空で初期化します。
is_current_process_critical
パニックハンドラ等から、現在のプロセスが主要なシステムプロセス(PID 0 または gui_shell など)であるかどうかを判定します。 デッドロックを防ぐため、try_lock を使用します。
is_preempt_enabled
現在のコアでプリエンプションが許可されている(preempt_count == 0)かを判定します。
preempt_disable
現在のコアのプリエンプションを一時的に禁止します(カウントをインクリメント)。
preempt_enable
プリエンプション禁止を解除します(カウントをデクリメント)。 カウントが 0 に戻り、かつ再スケジュール要求(need_resched)があれば即座に切り替えを実行します。
reap_zombies 🔒
現在のスタックポインタ (SP) がそのスタック上に存在しないゾンビプロセス(終了済みプロセス)を解放します。 まだスタックが使用中のプロセス(exit直後の自分自身など)は、次回以降のクリーンアップに持ち越します。
register_idle_process
アイドルプロセス (idle_core) を特定のコアに登録し、そのコアの初期プロセスとします。
schedule 🔒
スケジューリングのコア処理。 飢餓防止(starvation_count)を考慮した、優先度ベースのプリエンプティブ・ラウンドロビンアルゴリズムを適用し、 最もスコアの高い Ready 状態のプロセスを選択してコンテキストスイッチを行います。
scheduler_tick
タイマー割り込み(Tick)から毎チック呼び出され、プロセスの残りタイムスライスを管理します。
should_preempt
現在のコアでプリエンプション(強制切り替え)を実行すべき状態かを判定します。
sleep
指定した期間(タイマーチック数)だけ、呼び出し元のプロセスを待機状態 (Waiting) に移行させます。
spawn
カーネル空間 (EL1) で実行される新しいプロセス (カーネルスレッド) を生成し、 ロードバランシングに基づいてプロセス数が最も少ないコアのランキューに登録します。
spawn_on_core
特定のコアをターゲットにしてカーネルプロセス (カーネルスレッド) を生成します。
spawn_user
ユーザー空間 (EL0) で動作する新しいユーザープロセスを生成し、 ロードバランシングに基づいてプロセス数が最も少ないコアのランキューに登録します。
spawn_user_on_core
指定したコアをターゲットにして、ユーザー空間 (EL0) で動作するユーザープロセスを生成します。
spawn_with_arg
引数 usize を1つ取るカーネルプロセス (カーネルスレッド) を生成し、 ロードバランシングに基づいてプロセス数が最も少ないコアのランキューに登録します。
spawn_with_arg_on_core
コアと引数 usize を指定してカーネルプロセス (カーネルスレッド) を生成し、 対象コアのランキューに登録します。
stack_contains 🔒
指定されたスタックポインタ (SP) が、メモリ領域に含まれるかを判定します。
switch_context 🔒
tick
定期的に呼び出され(タイマー割り込みなど)、待機状態 (Waiting) にあるプロセスのチック数を更新し、 必要に応じて schedule() を実行してコンテキストスイッチを行います。
trampoline 🔒
コンテキストスイッチで最初に起動するトランポリン関数。 レジスタ x19 からエントリポイント、x20 から引数を受け取り、対象の関数を実行します。 実行が終了したスレッドは、exit() を呼び出して自身を終了させます。
user_trampoline 🔒
ユーザープロセスのトランポリン関数。 switch_context から ret で呼ばれ、SP_EL1 をカーネルスタックに、 SP_EL0 をユーザースタックに設定した上で、enter_userspace を用いて EL0 に降下します。
yield_now
呼び出し元のプロセスを一時的に実行可能状態 (Ready) に戻し、即座に再スケジュールを実行して CPUを他のプロセスに譲ります(コオペラティブ・マルチタスク)。