Lions' 本読み (44)

そろそろまたばたばたしそうなのですが、宿題がなんとか片付いて欲しい。
と言いつつ newproc 確認に着手。

なんとなく fork を見てみる

今の fork は

FORK(2)                    Linux Programmer's Manual                   FORK(2)

NAME
       fork - create a child process

SYNOPSIS
       #include <unistd.h>

       pid_t fork(void);

というプロトタイプで 0 が戻るのは子プロセスで親プロセスには子プロセスの pid が戻る形になっているはず。ところが v6 の fork は以下な実装になってて

3333 found:
3334    if(newproc()) {
3335            u.u_ar0[r0] = p1->p_pid;
(中略
3343    }
3344    u.u_ar0[R0] = p2->p_pid;

親には子の、子には親のプロセス id が戻る形になっているのかどうなのか。てか、添字の変数名が異なるあたりも微妙。

v6 の fork

以下にざっくり情報を列挙。

  • proc な配列を走査して p_stat 属性が NULL な要素を探す。
    • プロセス ID がカブらないような配慮をしている
    • 見つからない場合 panic してますが、fork 側で先んじて確認してるのでコメントの通り、panic はしない模様
  • 見つけた proc エントリの初期化
    • up = rip = u.u_procp でカレントプロセスなオブジェクトを確保
    • 属性の初期化の実施 (基本的に親プロセスのコピー)
  • 必要に応じてエントリの参照を二重にする、のブロック
    • オープンしてるファイル構造体 (5507 で定義されている) の参照カウントを増分
    • ユーザ構造体の p_textp 属性 (text 構造体は 4306 で定義されている) の参照カウントおよびロードされている参照数な属性を増分
    • ユーザ構造体の u_cdir 構造体 (inode 構造体は 5659 で定義されている) の参照カウントな属性を増分
  • 新しいプロセスの設定
    • ここで生成されたプロセスを swtch で見つけてもらって newproc が 1 を戻す工作 (savu(u.u_rsav))
    • 新しいプロセスのオブジェクトの参照を rpp と u.u_procp に代入 (u.u_procp = rpp = p)
    • 親プロセスのオブジェクトの参照を rip に代入
    • 新しいプロセス用の領域を親プロセスの領域サイズを元に生成
  • 新しいプロセス用の領域が確保できない場合、カレントプロセス (親プロセス) をスワップアウト
    • ここは 325p に詳細な解説あり
  • 確保できた場合、コピーする
  • 子プロセスを指していた u.u_procp を元に戻して return(0) する

問題は newproc で生成されかけた新たなプロセスがスワップインする瞬間の処理はどこなのか、というナニ。スワップアウトされてる状態としては

  • p_addr 属性は親プロセスのソレ
  • p_flag 属性は SSWAP

ええとでも、これがどうやって生き返るのかがやっぱり分からん。

xswap 手続きちょろっと確認

呼び出しなナニが以下。

1906            xswap(rpp, 0, 0);

第三引数が 0 だとこの中から呼び出している swap 手続きに渡す引数が呼び出し元 (newproc の) rpp-p_size になる模様。また、第二引数が 0 でない場合は第一引数な領域を解放してますね。

4382    if(ff)
4383            mfree(coremap, os, rp->p_addr);

これ、そもそも領域が確保されていないので、なのか。
でもこの状態って

  • p_stat が SRUN
  • p_flag が SLOAD で SSWAP

という非常にアレゲなことになってるんですが、よくよく見てみるに p_flag 属性は xswap で (SLOAD|SLOCK) を除去してました。ので、swtch だの sched だので取り出し対象になってますね。あ、取り出されるのは sched 限定なのかな。
ここ、もう少し確認必要なカンジですが今日はこれで力尽きます。

残りの課題

以下です。

  • exec 手続き確認
  • readi 手続き確認
  • xswap 手続き確認
  • newproc でスワップアウトされてしまった子プロセスが起床する瞬間のナニを確認