Lions' 本読み (89)

#台風そん なエントリ日曜日版です。なかなか体調が回復してないようで着手は夕方近くだったりしてます。明日は体調的に出社できるのかどうなのか。
それは良いとして今回は 14 章の xswap 云々の掘削を。
渡す引数は手続きのコメントに記述があるんですが引用は略。ただ、一番目の引数についてはプロセス構造体配列要素へのポインタとなっていて、これと繋がっているユーザ構造体なデータ領域一式 (データセグメント) がスワップアウト対象となります。テキストセグメントはここではスルーされているのもポイント。
呼び出し元は以下の手続きの以下の箇所です。

  • 1906 newproc
  • 2024 sched
  • 2285 expand
  • 4478 xalloc

一番上の newproc 手続きから呼び出された場合のみ ff (free flag?) なる引数に 0 が渡される形になっていますが、これはおそらく coremap に確保されていないので解放することはできない、というのが理由だと思われます。
以下に newproc の関連箇所の一部を引用。

1893    n = rip->p_size;          /* p_size 属性はデータセグメントのサイズ */
                                  /* rip は親プロセスのプロセス構造体のポインタ */
1894    a1 = rip->p_addr;
1896    a2 = malloc(coremap, n);
1902    if(a2 == NULL) {
1903            rip->p_stat = SIDL;   /* 親プロセスの状態は SIDL */
1904            rpp->p_addr = a1;     /* データセグメントは親子共有 */
1905            savu(u.u_ssav);
1906            xswap(rpp, 0, 0);
1907            rpp->p_flag =| SSWAP;
1908            rpp->p_stat = SRUN;
1909    }

確かに上の実装を見るに解放しちゃうと親プロセスにご迷惑がかかります。
逆にそれ以外の場合であれば coremap から領域を確保している、が前提のはずなのでスワップアウトするのであれば領域の解放が必須ですね。

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

あと三番目の引数ですが例えば expand 手続きから呼び出されるケイスが良い例なのでしょうか。この手続きはデータセグメントのサイズを拡張する手続きになってます。実装を順に見て行きますと

2273    p = u.u_procp;
2274    u = p->p_size;
2275    p->p_size = newsize;
2276    a1 = p->p_addr;

プロセス構造体のポインタを確保してデータセグメントのサイズを退避して引数で受けとった新たなサイズを設定しています。で、現状のデータセグメントの先頭アドレスを a1 に退避しておいて (一部略してます) 以下

2282    a2 = malloc(coremap, newsize);

別場所に newsize な領域を確保にいってます。成功した場合は退避した a1 から a2 に中身をコピーして a1 を解放して sureg して終了してます (ざっくりですが)。問題は領域確保に失敗した場合の処理です。以下。

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

xswap 手続きに n を渡してます。これがどーゆーことなのかというと xswap の中で解放する領域サイズを以下なカンジで計算してて

4374    if(os == 0)
4375            os = rp->p_size;

デフォルトだと渡したプロセス構造体オブジェクトの p_size 属性の値になってしまう形になってます。expand から xswap を呼び出す場合、上に引用した通りでスデに新しい領域のサイズが設定されてしまっているので、明示的に拡張前のものを渡してさしあげる必要がある、という事な模様。

だんだん慣れてきたカンジ

なのでエントリを改めて xalloc についても調べてエントリ入れれるよう努力してみます。