Nsys/sys/nsys/ken/slp.c
#include "/sys/nsys/param.h"
#include "/sys/nsys/user.h"
#include "/sys/nsys/proc.h"
#include "/sys/nsys/text.h"
#include "/sys/nsys/systm.h"
#include "/sys/nsys/file.h"
#include "/sys/nsys/inode.h"
#include "/sys/nsys/buf.h"
#define PS 0177776
struct {
int integ;
};
sleep(chan, pri)
{
int s;
register *rp;
s = PS->integ;
if(pri >= 0) {
if(issig())
goto psig;
rp = u.u_procp;
rp->p_wchan = chan;
rp->p_stat = SWAIT;
rp->p_pri = pri;
spl0();
if(runin != 0) {
runin = 0;
wakeup(&runin);
}
swtch();
if(issig()) {
psig:
spl0();
u.u_rsav[0] = u.u_qsav[0];
u.u_rsav[1] = u.u_qsav[1];
retu(u.u_procp->p_addr);
return;
}
} else {
rp = u.u_procp;
rp->p_wchan = chan;
rp->p_stat = SSLEEP;
rp->p_pri = pri;
spl0();
swtch();
}
PS->integ = s;
}
wakeup(chan)
{
register struct proc *p;
register i;
int n;
loop:
n = 0;
p = &proc[0];
for(i=0; i<NPROC; i++) {
if(p->p_wchan == chan) {
if(runout!=0 && (p->p_flag&SLOAD)==0) {
runout = 0;
n++;
}
p->p_wchan = 0;
p->p_stat = SRUN;
runrun++;
}
p++;
}
if(n) {
chan = &runout;
goto loop;
}
}
#define NDIS 5
cookies[NDIS]
{
20,
30,
10,
5,
2
};
sched()
{
static struct proc *p1, *p2;
register struct proc *rp;
int a;
p1 = p2 = &proc[0];
/*
* find user to swap in
*/
loop:
spl6();
rp = p1;
for(a=0; a<NPROC; a++) {
rp++;
if(rp >= &proc[NPROC])
rp = &proc[0];
if(rp->p_stat==SRUN && (rp->p_flag&SLOAD)==0) {
p1 = rp;
goto found;
}
}
runout++;
sleep(&runout, PSWP);
goto loop;
/*
* find core for that user
*/
found:
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;
/*
* if none, find user to
* swap out
*/
spl6();
rp = p2;
for(a=0; a<NPROC; a++) {
rp++;
if(rp >= &proc[NPROC])
rp = &proc[0];
if((rp->p_flag&(SSYS|SLOCK|SLOAD))==SLOAD &&
rp->p_stat == SWAIT) {
rp->p_ndis = 0;
goto found1;
}
}
for(a=0; a<NPROC; a++) {
rp++;
if(rp >= &proc[NPROC])
rp = &proc[0];
if((rp->p_flag&(SSYS|SLOCK|SLOAD))==SLOAD &&
rp->p_cook == 0 &&
(rp->p_stat==SRUN || rp->p_stat==SSLEEP)) {
rp->p_ndis++;
if(rp->p_ndis >= NDIS)
rp->p_ndis--;
goto found1;
}
}
runin++;
sleep(&runin, PSWP);
goto found;
/*
* swap user out
*/
found1:
spl0();
rp->p_flag =& ~SLOAD;
p2 = rp;
xswap(rp, 1, 0);
goto found;
/*
* 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 = p1->p_textp;
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;
rp = p1;
mfree(swapmap, (rp->p_size+7)/8, rp->p_addr);
rp = p1;
rp->p_addr = a;
rp->p_flag =| SLOAD;
rp->p_cook = cookies[rp->p_ndis];
goto loop;
swaper:
panic("swap error");
}
swtch()
{
static int *p;
register i, n;
register struct proc *rp;
if(p == 0)
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)==SLOAD) {
if(rp->p_pri < n) {
p = rp;
n = rp->p_pri;
}
}
}
if(p == NULL) {
p = rp;
idle();
goto loop;
}
retu(p->p_addr);
sureg();
if(p->p_flag&SSWAP) {
p->p_flag =& ~SSWAP;
u.u_rsav[0] = u.u_ssav[0];
u.u_rsav[1] = u.u_ssav[1];
retu(p->p_addr);
}
return(1);
}
newproc()
{
int a1, a2, n;
struct proc *p, *up;
register struct proc *rpp;
register *rip;
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_ttyp = rip->p_ttyp;
rpp->p_textp = rip->p_textp;
rpp->p_pid = ++mpid;
rpp->p_ppid = rip->p_pid;
rpp->p_ndis = 0;
rpp->p_cook = cookies[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);
u.u_procp = p;
rip = up;
n = rip->p_size;
a1 = rip->p_addr;
p->p_size = n;
a2 = malloc(coremap, n);
if(a2 == NULL) {
up->p_stat = SIDL;
p->p_addr = a1;
savu(u.u_ssav);
xswap(p, 0, 0);
p->p_flag =| SSWAP;
up->p_stat = SRUN;
} else {
p->p_addr = a2;
while(n--)
copyseg(a1++, a2++);
}
u.u_procp = up;
return(0);
}
expand(newsize)
{
int i, n, a1, a2;
int *p;
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();
}