Lions' 本読み (91)

昨晩 #台風そん でもごもごしてて expand で興味深い記述を見つけてますので、今日はそのあたりを掘削してみる方向にて。
手続き定義のコメントてきには以下になります。

2258  * コアがない場合、サイズの要求を調整したあと、
2259  * プロセスがスワップアウトされるように手配する。
2260  * プロセスが目覚めたとき、十分なコアが割り当てあっれるだろう。

ちなみに問題になってる箇所の実装は以下なカンジでして

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

ここで言われてる_サイズの要求を調整_とは何にあたるのか。

よくよく見てみると

肝心なのは上で引用してる部分よりもさらに上。初期設定してる最初らへんで以下。

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

これで

  • p にはプロセス構造体オブジェクトのポインタ
  • n には拡張前のデータセグメントのサイズ
  • p->p_size には拡張後のサイズ
  • a1 には現時点のデータセグメントのポインタ

が、格納されていることになります。xswap でスワップアウトされるサイズは拡張前のサイズで保存されますが、sched でスワップインする時にはデータセグメントは以下の命令で復帰されます。

2042    if(swap(rp->p_addr, a, rp->p_size, B_READ))
2043            goto swaper;
2044    mfree(swapmap, (rp->p_size+7)/8, rp->p_addr);
2045    rp->p_addr = a;

2044 で分かる通り、この時点での rp->p_addr はスワップ領域のアドレスが格納されてます。これを swap 命令で a に読み込むんですがサイズは rp->p_size になってて、上述の通りこれは expand に渡される newsize なナニが格納されてます。
これで実質てきに expand な処理が終了したといっても過言ではなくてあとは rp->p_addr が指してた swapmap なナニを解放して、rp->p_addr が a という coremap から取得した領域を指すようになってますね。すばらです。