めのん@ひとりプログラミング同好会

このブログはすべてフィクションであり、実在の人物、団体とは一切関係ありません

Zig版ASP3カーネルのタスクに関するこまごま

こんばんは、めのんです!

前回予告したとおり、今回はタスクに関するこまごました内容を見ていくことにします。

最初は前回も登場したレディキューから見ていくことにしましょう。

///
///  レディキュー
///
///  レディキューは,実行できる状態のタスクを管理するためのキューであ
///  る.実行状態のタスクも管理しているため,レディ(実行可能)キュー
///  という名称は正確ではないが,レディキューという名称が定着している
///  ため,この名称で呼ぶことにする.
///
///  レディキューは,優先度ごとのタスクキューで構成されている.タスク
///  のTCBは,該当する優先度のキューに登録される.
///
pub var ready_queue: [TNUM_TPRI]queue.Queue = undefined;

コメントにもあるように、レディキューには実行可能状態のタスクと実行状態のタスクが登録されています。 タスク優先度ごとの配列になっていて、ぞれぞれ別のキューを持っています。 タスク優先度が高い(値が小さい)レディキューから順に探索して、最初に見つかったタスクが実行状態になります。

この探索を高速に行うための工夫がされていています。 それがサーチ用のビットマップです。

///
///  レディキューサーチのためのビットマップ
///
///  レディキューのサーチを効率よく行うために,優先度ごとのタスクキュー
///  にタスクが入っているかどうかを示すビットマップを用意している.ビッ
///  トマップを使うことで,メモリアクセスの回数を減らすことができるが,
///  ビット操作命令が充実していないプロセッサで,優先度の段階数が少な
///  い場合には,ビットマップ操作のオーバーヘッドのために,逆に効率が
///  落ちる可能性もある.
///
var ready_primap: prio_bitmap.PrioBitmap(TNUM_TPRI) = undefined;

ビットマップというと画像を思い浮かべる方がいらっしゃるかもしれませんが、ここでいうビットマップは画像ではありません。 これについては次回以降に深掘りできたらと考えています。

レディキューを探索して見つけたタスクはp_schedtskに格納されます。

///
///  実行すべきタスク
///
///  実行すべきタスクのTCBを指すポインタ.実行できるタスクがない場合は
///  nullにする.
///
///  p_runtskは,通常はp_schedtskと一致しているが,非タスクコンテキス
///  ト実行中は,一致しているとは限らない.割込み優先度マスク全解除で
///  ない状態の間とディスパッチ禁止状態の間(すなわち,dspflgがfalseで
///  ある間)は,p_schedtskを更新しない.
///
pub var p_schedtsk: ?*TCB = undefined;

コメントにもあるdspflgは次のように定義されています。

///
///  タスクディスパッチ可能状態
///
///  割込み優先度マスク全解除状態であり,ディスパッチ許可状態である
///  (ディスパッチ禁止状態でない)ことを示すフラグ.ディスパッチ保留
///  状態でないことは,タスクコンテキスト実行中で,CPUロック状態でなく,
///  dspflgがtrueであることで判別することができる.
///
pub var dspflg: bool = undefined;

そして、ディスパッチ許可状態を表すフラグの定義も見てみましょう。

///
///  ディスパッチ許可状態
///
///  ディスパッチ許可状態であることを示すフラグ.
///
pub var enadsp: bool = undefined;

ディスパッチ許可状態というのは、ena_dspやdis_dspといったサービスコールで制御します。

実際にディスパッチが行われると、実行状態のタスクはp_runtskに格納されます。

///
///  実行状態のタスク
///
///  実行状態のタスク(=プロセッサがコンテキストを持っているタスク)
///  のTCBを指すポインタ.実行状態のタスクがない場合はnullにする.
///
///  サービスコールの処理中で,自タスク(サービスコールを呼び出したタ
///  スク)に関する情報を参照する場合はp_runtskを使う.p_runtskを書き
///  換えるのは,ディスパッチャ(と初期化処理)のみである.
///
pub var p_runtsk: ?*TCB = undefined;

カーネルを一通り読むためには今回見たような要素の理解は不可欠です。 Zigを勉強するという意味では、とくに見所はないんですけどね。

今回はほとんどソースコードをペタペタ引用して貼っただけに近くなってしまいました。 次回はもうちょっと中身のある内容にできたらいいなと思います!

それでは!!