generated at
fork()
子プロセス用のメモリ領域を確保して、そこに親プロセスの内容を複製する
親プロセスを複製して、子プロセスを作成する

CoWとかはある



具体的に何が複製されるのか
fork()した時点では、テキスト領域はコピーされず、同じものを参照する


UNIX V6でのfork()の実装
Cのライブラリ関数 fork() の実装
ユーザーが fork() を呼ぶとこれが呼ばれる
source/s4/fork.s
.globl _fork, cerror, _par_uid _fork: mov r5,-(sp) mov sp,r5 sys fork / ここでfork syscallを呼ぶ。つまり↓のfork()が呼ばれる br 1f bec 2f jmp cerror 1: mov r0,_par_uid clr r0 2: mov (sp)+,r5 rts pc .bss _par_uid: .=.+2
kernel内の fork() の実装
sys fork 経由で呼ばれる
これは親プロセスと、子プロセスで各1回ずつ呼ばれる
sys/ken/sys1.c
fork() { register struct proc *p1, *p2; p1 = u.u_procp; // u.u_procpはproc構造体へのptr for(p2 = &proc[0]; p2 < &proc[NPROC]; p2++) if(p2->p_stat == NULL) // proc[]の中で空きエントリを探す goto found; u.u_error = EAGAIN; goto out; found: if(newproc()) { // プロセスの生成. 親は0(=false). 子は1 u.u_ar0[R0] = p1->p_pid; u.u_cstime[0] = 0; u.u_cstime[1] = 0; u.u_stime = 0; u.u_cutime[0] = 0; u.u_cutime[1] = 0; u.u_utime = 0; return; } u.u_ar0[R0] = p2->p_pid; // p2(子プロセス)のpidを入れる. out: u.u_ar0[R7] =+ 2; }
r0 に入れた値が、返り値になる
親ではfork()#62ece0751982700000dafc8fなので子のpid
これはCのライブラリ関数 fork() でもそのまま返される
子ではfork()#62ece0751982700000dafc86なので、親のpid
これはfork()#62ecdf8e1982700000dafc6fでクリアされるので、Cのライブラリ関数fork()の返り値は0になる
clr命令はそのレジスタの内容を0にする