Lions' 本読み (76)
諸々掘削してて停滞気味だったのですがそろそろ先に進むことに。
fork
ちょっとだけメモ。というか忘れないように書き取り。
以下の部分ですが
3333 found: 3334 if(newproc()) { 3335 u.u_ar0[r0] = p1->p_pid; 3336 u.u_cstime[0] = 0; 3337 u.u_cstime[1] = 0; 3338 u.u_stime = 0; 3339 u.u_cutime[0] = 0; 3340 u.u_cutime[1] = 0; 3341 u.u_utime = 0; 3342 return; 3343 } 3344 u.u_arp[R0] = p2->p_pid;
親プロセスには子プロセスの pid が、子プロセスには親プロセスの pid が戻る形になっているはず。p1 は今の、p2 は新たなプロセス構造体のポインタが格納されてます。
そして newproc では proc な配列要素の空きを見つけてコピーを作って SRUN な状態にしといた上で 0 で戻ります。コピーされた新たな proc 配列要素なオブジェクトはそのうち swtch でカレントプロセスとして選ばれた後に 1 で戻ります。この時に 3335 以降の命令が実行されて fork の呼び出し元に戻る、というのが現時点の理解です。おそらく合ってるはず。
sbreak
これは今で言う sbrk ってことで良いのかな。ちょっとずれた領域の中身を調整するあたりが微妙なのでマンガを描いてみたらなんとなく分かった。
ポイントとしては領域サイズが減る場合は d の値が負、というあたりでしょうか。
まず領域サイズが減るケイスな記述が以下。
3376 a = u.u_procp->p_addr + n - u.u_ssize; 3377 i = n; 3378 n = u.u_ssize; 3379 while(n--) { 3380 copyseg(a-d, a); 3381 a++; 3382 } 3383 expand(i); 3384 return;
ええと、イメージ的には以下なカンジ、になるのかどうか。
<--- -d ---> a-d | +----------------------+----+-----+ ssize <----- i -----> +----------------+-----+ ssize | a
上側が元のデータセグメントなイメージで下側がサイズ減された後のイメージになります。次はサイズが増える場合の記述が以下。
3387 expand(n); 3388 a = u.u_procp->p_addr + n; 3389 n = u.u_ssize; 3390 while(n--) { 3391 a--; 3392 copyseg(a-d, a); 3393 } 3394 while(d--) 3395 clearseg(--a);
で、その時のイメージが以下なカンジ。この時の d の値は正です。
a-d | +----------------+-----+ ssize <---- d ---> a | +----------------------+----+-----+ ssize <----------> 初期化必要?
copyseg の引数の記述が同じカンジなので目が回っちゃったカンジ。つうか日中対応でへろへろなのかも。
体力てきに余裕があったら 13 章以降に進みます。