generated at
UNIX V6のnewproc()の実装

fork() の内部で呼ばれて、新しいプロセスを生成する関数
もっと詳しく書いてる


sys/ken/slp.c
newproc() { int a1, a2; struct proc *p, *up; register struct proc *rpp; register *rip, n; p = NULL; retry:
この辺で新しいpidの決定
mpidはglobal変数でnewprocするたびにインクリメント
sys/ken/slp.c
mpid++; if(mpid < 0) { mpid = 0; goto retry; } for(rpp = &proc[0]; rpp < &proc[NPROC]; rpp++) { if(rpp->p_stat == NULL && p==NULL) p = rpp; if (rpp->p_pid==mpid) goto retry; } if ((rpp = p)==NULL) panic("no procs");
この辺で、親を子に複製している
rpp が新しい子プロセスになるUNIX V6のproc構造体
sys/ken/slp.c
rip = u.u_procp; up = rip; rpp->p_stat = SRUN; rpp->p_flag = SLOAD; rpp->p_uid = rip->p_uid; rpp->p_ttyp = rip->p_ttyp; rpp->p_nice = rip->p_nice; rpp->p_textp = rip->p_textp; rpp->p_pid = mpid; rpp->p_ppid = rip->p_pid; rpp->p_time = 0;
sys/ken/slp.c
for(rip = &u.u_ofile[0]; rip < &u.u_ofile[NOFILE];) if((rpp = *rip++) != NULL) rpp->f_count++; if((rpp=up->p_textp) != NULL) { rpp->x_count++; rpp->x_ccount++; } u.u_cdir->i_count++; savu(u.u_rsav); rpp = p; u.u_procp = rpp; rip = up; n = rip->p_size; a1 = rip->p_addr; rpp->p_size = n;
sys/ken/slp.c
a2 = malloc(coremap, n); if(a2 == NULL) { // mallocに失敗. スワップする rip->p_stat = SIDL; // 親プロセスをidle状態に rpp->p_addr = a1; savu(u.u_ssav); xswap(rpp, 0, 0); rpp->p_flag =| SSWAP; rip->p_stat = SRUN; // 親プロセスをrun状態に } else { // mallocに成功。a2は物理アドレス rpp->p_addr = a2; while(n--) copyseg(a1++, a2++); // データセグメントをコピー } u.u_procp = rip; return(0); }