# /* * Copyright 1973 Bell Telephone Laboratories Inc */ #include "../param.h" #include "../user.h" #include "../proc.h" #include "../text.h" #include "../systm.h" #include "../file.h" #include "../inode.h" #include "../buf.h" #define PS 0177776 struct { int integ; }; sleep(chan, pri) { register *rp, s; u.u_dsleep = 0; s = PS->integ; rp = u.u_procp; if(pri >= 0) { if(issig()) goto psig; rp->p_wchan = chan; rp->p_stat = SWAIT; rp->p_pri = pri; spl0(); if(runin != 0) { runin = 0; wakeup(&runin); } swtch(); if(issig()) { psig: aretu(u.u_qsav); return; } } else { rp->p_wchan = chan; rp->p_stat = SSLEEP; rp->p_pri = pri; spl0(); swtch(); } PS->integ = s; } wakeup(chan) { register struct proc *p; register n, c; loop: c = chan; n = 0; for(p = &proc[0]; p < &proc[NPROC]; p++) if(p->p_wchan == c) { if(runout!=0 && (p->p_flag&SLOAD)==0) { runout = 0; n++; } p->p_wchan = 0; p->p_stat = SRUN; runrun++; } if(n) { chan = &runout; goto loop; } } sched() { struct proc *p1; register struct proc *rp; register a, n; /* * find user to swap in * of users ready, select one out longest */ goto loop; sloop: runin++; sleep(&runin, PSWP); loop: spl6(); n = -1; for(rp = &proc[0]; rp < &proc[NPROC]; rp++) if(rp->p_stat==SRUN && (rp->p_flag&SLOAD)==0 && rp->p_time > n) { p1 = rp; n = rp->p_time; } if(n == -1) { runout++; sleep(&runout, PSWP); goto loop; } /* * see if there is core for that process */ spl0(); rp = p1; a = rp->p_size; if((rp=rp->p_textp) != NULL) if(rp->x_ccount == 0) a =+ rp->x_size; if((a=malloc(coremap, a)) != NULL) goto found2; /* * none found, * look around for easy core */ spl6(); for(rp = &proc[0]; rp < &proc[NPROC]; rp++) if((rp->p_flag&(SSYS|SLOCK|SLOAD))==SLOAD && rp->p_stat == SWAIT) goto found1; /* * no easy core, * if this process is deserving, * look around for * oldest process in core */ if(n < 3) goto sloop; n = -1; for(rp = &proc[0]; rp < &proc[NPROC]; rp++) if((rp->p_flag&(SSYS|SLOCK|SLOAD))==SLOAD && (rp->p_stat==SRUN || rp->p_stat==SSLEEP) && rp->p_time > n) { p1 = rp; n = rp->p_time; } if(n < 2) goto sloop; rp = p1; /* * swap user out */ found1: spl0(); rp->p_flag =& ~SLOAD; xswap(rp, 1, 0); goto loop; /* * swap user in */ found2: if((rp=p1->p_textp) != NULL) { if(rp->x_ccount == 0) { if(swap(rp->x_daddr, a, rp->x_size, B_READ)) goto swaper; rp->x_caddr = a; a =+ rp->x_size; } rp->x_ccount++; } rp = p1; if(swap(rp->p_addr, a, rp->p_size, B_READ)) goto swaper; mfree(swapmap, (rp->p_size+7)/8, rp->p_addr); rp->p_addr = a; rp->p_flag =| SLOAD; rp->p_time = 0; goto loop; swaper: panic("swap error"); } swtch() { static int *p; register i, n; register struct proc *rp; if(p == NULL) p = &proc[0]; savu(u.u_rsav); retu(proc[0].p_addr); loop: rp = p; p = NULL; n = 127; for(i=0; i<NPROC; i++) { rp++; if(rp >= &proc[NPROC]) rp = &proc[0]; if(rp->p_stat==SRUN && (rp->p_flag&SLOAD)!=0) { if(rp->p_pri < n) { p = rp; n = rp->p_pri; } } } if(p == NULL) { p = rp; idle(); goto loop; } rp = p; retu(rp->p_addr); sureg(); if(rp->p_flag&SSWAP) { rp->p_flag =& ~SSWAP; aretu(u.u_ssav); } return(1); } newproc() { int a1, a2; struct proc *p, *up; register struct proc *rpp; register *rip, n; for(rpp = &proc[0]; rpp < &proc[NPROC]; rpp++) if(rpp->p_stat == NULL) goto found; panic("no procs"); found: /* * make proc entry for new proc */ p = rpp; 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_textp = rip->p_textp; rpp->p_pid = ++mpid; rpp->p_ppid = rip->p_pid; rpp->p_time = 0; /* * make duplicate entries * where needed */ 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++; /* * swap out old process * to make image of new proc */ savu(u.u_rsav); rpp = p; u.u_procp = rpp; rip = up; n = rip->p_size; a1 = rip->p_addr; rpp->p_size = n; a2 = malloc(coremap, n); if(a2 == NULL) { rip->p_stat = SIDL; rpp->p_addr = a1; savu(u.u_ssav); xswap(rpp, 0, 0); rpp->p_flag =| SSWAP; rip->p_stat = SRUN; } else { rpp->p_addr = a2; while(n--) copyseg(a1++, a2++); } u.u_procp = rip; return(0); } expand(newsize) { int i, n; register *p, a1, a2; p = u.u_procp; n = p->p_size; p->p_size = newsize; a1 = p->p_addr; if(n >= newsize) { mfree(coremap, n-newsize, a1+newsize); return; } savu(u.u_rsav); a2 = malloc(coremap, newsize); if(a2 == NULL) { savu(u.u_ssav); xswap(p, 1, n); p->p_flag =| SSWAP; swtch(); /* no return */ } p->p_addr = a2; for(i=0; i<n; i++) copyseg(a1+i, a2++); mfree(coremap, n, a1); retu(p->p_addr); sureg(); }