xv6-rev6 読み (9)

Lions' 本では proc は struct proc 型の配列になっておりましたが xv6 では multil processor ってことで proc.c で以下な定義になっております。
# proc は struc proc 型の配列、というのは変わりないですが

struct {
  struct spinlock lock;
  struct proc proc[NPROC];
} ptable;

ちなみに Lions' 本というか v6 な unix の user 構造体が無いですね。しかも proc 構造体の属性もかなり違う模様。。
Linux だと user 構造体なナニは task_struct 構造体にあたるのかどうか。

あら

proc.c に sched という手続きがあるな。呼び出し元はいずれも proc.c で定義されてる手続きで

  • exit() 手続き
  • yield() 手続き
  • sleep() 手続き

v6 だと sched() から sleep() が呼ばれるみたいなんですが、逆ッスね。それぞれで find-grep してみたんですが

  • exit() は沢山すぎで略
  • yield() は trap() から呼び出されている模様
  • sleep() は bio.c の bget() から呼び出されている模様

という、むむむな結果。ただ、sched から呼び出されている swtch は以下な記述で

  swtch(&proc->context, cpu->scheduler);

これって scheduler な手続きから呼び出される swtch の逆だな。

      swtch(&cpu->scheduler, proc->context);

そもそも xv6 の cpu->scheduler な context 構造体は何が格納されているのか、という話ですね。定義なコメントが以下。

  struct context *scheduler;   // swtch() here to enter scheduler

あ、これって #0 なプロセスの、なのかな。マルチプロセサなナニはスルーってことで良いですか? (を

なるほど

xv6 では Lions' 本曰くの #0 なナニが cpu->scheduler に保管されてて

  • scheduler から呼び出される swtch 手続きで選択した RUNNABLE なナニを動かして #0 なソレを cpu->scheduler に保存
  • それ以外から呼び出される swtch 手続きでは #0 を起こすことで scheduler なプロセスが再び動きだす

ということなのか。
scheduler の以下な記述で swtch 以下は実行されない、ってカン違いしてたんですが、んな訳ゃないんですが。当たり前と言えば当たり前なのでしょうけど。

      swtch(&cpu->scheduler, proc->context);
      switchkvm();

      // Process is done running for now.
      // It should have changed its p->state before coming back.
      proc = 0;
    }

こうしてきちんと見てみるに x86 アーキテクチャって凄いなぁ。