UNIX V6のnewproc()の実装
fork()
の内部で呼ばれて、新しいプロセスを生成する関数
もっと詳しく書いてる
sys/ken/slp.cnewproc()
{
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");
この辺で、親を子に複製している
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);
}