Lions' 本読み (41)

ええと備忘まで、残ってる課題が以下らしい。

  • 数日前の課題
    • savu(u.u_ssav) の目的とか副作用とかを確認
    • expand 手続きと estabur 手続きの関連
    • 381p の aretu と u.u_ssav に関する調査について確認
  • newproc 手続き確認
  • exec 手続き確認
  • readi 手続き確認

とりあえず上から順に。

savu(u.u_ssav) の目的とか副作用とかを確認

上から順に確認してみます。まず newproc 手続きで以下。

1902    if(a2 == NULL) {
1903            rip->p_stat = SIDL;
1904            rpp->p_addr = a1;
1905            savu(u.u_ssav);
1906            xswap(rppp, 0, 0);
1907            rpp->p_flag =| SSWAP;
1908            rip->p_stat = SRUN;
1909    } else {

スワップアウト時の処理ですね。次に出てくるのは 2238 club なナニです。

2240    if(rp->p_flag&SSWAP) {
2241            rp->p_flag =& ~SSWAP;
2242            aretu(u.u_ssav);
2243    }

はいはい、そーゆーことなのか。でもこれって newproc の中で云々の時にどんな挙動になるのかな。とりあえずここでは置いといて先に進みます。
次は expand 手続きで以下。

2283    if(a2 == NULL) {
2284            savu(u.u_ssav);
2285            xswap(p, 1, n);
2286            p->p_flag =| SSWAP;
2287            swtch();
2288            /* リターンしない */
2289    }

ここは以前確認したんですよね。
そしてもう一箇所は xalloc 手続き。

4474 out:
4475    if(xp->x_count == 0) {
2276            savu(u.u_rsav);
2277            savu(u.u_ssav);
2278            xswap(u.u_procp, 1, 0);
2279            u.u_procp->p_flag =| SSWAP;
2280            swtch();
2281            /* リターンしない */
2282    }

ここは expand と同じパターンですね。xswap はあまりきちんと確認してないですね。ちなみに xswap は newproc から呼び出された場合のみ領域の開放をしない旨の記述を 374p で発見。以下です。

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

あら、コメントに_カレントプロセスをスワップアウトする_という記述がありますね。新しいプロセス用のメモリを確保しようとして失敗した場合にどんな状態になるのか、がまだイメージできてない。
つうか期せずして newproc 確認になってたりするあたりがアレだなぁ。

swtch の 2238 club なコメントがポイント高い模様。

2231     * 新しいプロセスがスワップアウトされていて
2232     * 停止していたならば、スタックレベルを最近の savu(u_ssav) の
2233     * 呼び出しに設定する。これは、aretu の呼び出しの
2234     * 直後に実行されるリターンが
2235     * savu を実行した最後のルーチンから実際にリターンする
2236     * ということを意味している。

てか_新しいプロセス_というのは swtch される、という意味での新しいプロセスになるので微妙。なんとなく xswap を確認したところでは p_flag から SLOAD および SLOCK を落としてますね。
と、いうことは sched で

1961    if(rp->p_stat==SRUN && (rp->p_flag&SLOAD)==0 &&

という網にカカります。メモリが確保できればスワップインして云々、ということなのかどうなのか。なんとなく順に列挙してみるに

  • 1903 : 親 (カレント) プロセスの p_stat 属性を SIDL にして sched でスワップアウトされる対象から外す
  • 1904 : 親 (カレント) プロセスの user 構造体のアドレスを子プロセスの p_addr 属性に格納
  • 1905 : u.u_ssav に r5 および r6 を格納
  • 1906 : 子プロセスをスワップアウトする
    • ここで子プロセスの p_flag から SLOAD および SLOCK を落として sched がスワップイン対象としてチョイスできるようにしている模様
  • 1907 : 子プロセスの p_flag 属性に SSWAP を立てる
  • 1908 : 親 (カレント) プロセスの p_stat 属性を SRUN にする
    • 親 (カレント) プロセスがここでスワップアウトの対象になる、という理解で良いのかな

なんとなく外してはいない感触なんですが、どうなんでしょ。

まとめると

  • expand とか xalloc とかでスワップアウトする場合、制御が再開する時にはこれらの手続きの呼び出し元に戻る形となる
    • 契機は swtch 手続き
  • newproc でスワップアウトする場合、新しいプロセスは sched で領域を確保してスワップインする形となる

という事なのかどうなのか。