-/* kern_synch.c 3.6 %H% */
+/* kern_synch.c 4.8 %G% */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/inode.h"
#include "../h/vm.h"
#include "../h/pte.h"
-
+#include "../h/inline.h"
+#include "../h/mtpr.h"
#define SQSIZE 0100 /* Must be power of 2 */
#define HASH(x) (( (int) x >> 5) & (SQSIZE-1))
sleep(chan, pri)
caddr_t chan;
{
- register struct proc *rp;
- register s, h;
+ register struct proc *rp, **hp;
+ register s;
rp = u.u_procp;
s = spl6();
if (chan==0 || rp->p_stat != SRUN || rp->p_rlink)
panic("sleep");
- rp->p_stat = SSLEEP;
rp->p_wchan = chan;
rp->p_slptime = 0;
rp->p_pri = pri;
- h = HASH(chan);
- rp->p_link = slpque[h];
- slpque[h] = rp;
+ hp = &slpque[HASH(chan)];
+ rp->p_link = *hp;
+ *hp = rp;
if(pri > PZERO) {
- if(rp->p_sig && issig()) {
- rp->p_wchan = 0;
+ if(ISSIG(rp)) {
+ if (rp->p_wchan)
+ unsleep(rp);
rp->p_stat = SRUN;
- slpque[h] = rp->p_link;
- VOID spl0();
+ (void) spl0();
goto psig;
}
- VOID spl0();
- if(runin != 0) {
- runin = 0;
- wakeup((caddr_t)&runin);
- }
+ if (rp->p_wchan == 0)
+ goto out;
+ rp->p_stat = SSLEEP;
+ (void) spl0();
swtch();
- if(rp->p_sig && issig())
+ if(ISSIG(rp))
goto psig;
} else {
- VOID spl0();
+ rp->p_stat = SSLEEP;
+ (void) spl0();
swtch();
}
+out:
splx(s);
return;
return(rval);
}
+/*
+ * Remove a process from its wait queue
+ */
+unsleep(p)
+register struct proc *p;
+{
+ register struct proc **hp;
+ register s;
+
+ s = spl6();
+ if (p->p_wchan) {
+ hp = &slpque[HASH(p->p_wchan)];
+ while (*hp != p)
+ hp = &(*hp)->p_link;
+ *hp = p->p_link;
+ p->p_wchan = 0;
+ }
+ splx(s);
+}
+
/*
* Wake up all processes sleeping on chan.
*/
wakeup(chan)
register caddr_t chan;
{
- register struct proc *p, *q;
- register i;
+ register struct proc *p, **q, **h;
int s;
s = spl6();
- i = HASH(chan);
+ h = &slpque[HASH(chan)];
restart:
- p = slpque[i];
- q = NULL;
- while(p != NULL) {
- if (p->p_rlink || p->p_stat != SSLEEP)
+ for (q = h; p = *q; ) {
+ if (p->p_rlink || p->p_stat != SSLEEP && p->p_stat != SSTOP)
panic("wakeup");
- if (p->p_wchan==chan && p->p_stat!=SZOMB) {
- if (q == NULL)
- slpque[i] = p->p_link;
- else
- q->p_link = p->p_link;
+ if (p->p_wchan==chan) {
p->p_wchan = 0;
+ *q = p->p_link;
p->p_slptime = 0;
- /* OPTIMIZED INLINE EXPANSION OF setrun(p) */
- p->p_stat = SRUN;
- if (p->p_flag & SLOAD) {
-#ifndef FASTVAX
- p->p_link = runq;
- runq = p->p_link;
-#else
- setrq(p);
-#endif
- }
- if(p->p_pri < curpri)
- runrun++;
- if(runout != 0 && (p->p_flag&SLOAD) == 0) {
- runout = 0;
- wakeup((caddr_t)&runout);
+ if (p->p_stat == SSLEEP) {
+ /* OPTIMIZED INLINE EXPANSION OF setrun(p) */
+ p->p_stat = SRUN;
+ if (p->p_flag & SLOAD)
+ setrq(p);
+ if(p->p_pri < curpri) {
+ runrun++;
+ aston();
+ }
+ if(runout != 0 && (p->p_flag&SLOAD) == 0) {
+ runout = 0;
+ wakeup((caddr_t)&runout);
+ }
+ /* END INLINE EXPANSION */
+ goto restart;
}
- /* END INLINE EXPANSION */
- goto restart;
- }
- q = p;
- p = p->p_link;
+ } else
+ q = &p->p_link;
}
splx(s);
}
-#ifdef FASTVAX
/*
* Initialize the (doubly-linked) run queues
* to be empty.
for (i = 0; i < NQS; i++)
qs[i].ph_link = qs[i].ph_rlink = (struct proc *)&qs[i];
}
-#endif
/*
* Set the process running;
setrun(p)
register struct proc *p;
{
- register caddr_t w;
register s;
s = spl6();
default:
panic("setrun");
+ case SSTOP:
case SSLEEP:
- if (w = p->p_wchan) {
- wakeup(w);
- splx(s);
- return;
- }
+ unsleep(p); /* e.g. when sending signals */
break;
case SIDL:
- case SSTOP:
break;
}
p->p_stat = SRUN;
if (p->p_flag & SLOAD)
setrq(p);
splx(s);
- if(p->p_pri < curpri)
+ if(p->p_pri < curpri) {
runrun++;
+ aston();
+ }
if(runout != 0 && (p->p_flag&SLOAD) == 0) {
runout = 0;
wakeup((caddr_t)&runout);
register p;
p = (pp->p_cpu & 0377)/16;
- p += PUSER + pp->p_nice - NZERO;
+ p += PUSER + 2*(pp->p_nice - NZERO);
if(p > 127)
p = 127;
- if(p < curpri)
+ if(p < curpri) {
runrun++;
+ aston();
+ }
pp->p_usrpri = p;
return(p);
}
mpid = 0;
goto retry;
}
- for(rpp = &proc[0]; rpp < &proc[NPROC]; rpp++) {
+ for(rpp = proc; rpp < procNPROC; rpp++) {
if(rpp->p_stat == NULL && p==NULL)
p = rpp;
if (rpp->p_pid==mpid || rpp->p_pgrp==mpid)
rip = u.u_procp;
rpp->p_stat = SIDL;
rpp->p_clktim = 0;
- rpp->p_flag = SLOAD | (rip->p_flag & SPAGI);
+ rpp->p_flag = SLOAD | (rip->p_flag & (SPAGI|SDETACH|SNUSIG));
if (isvfork) {
rpp->p_flag |= SVFORK;
rpp->p_ndx = rip->p_ndx;
rpp->p_textp = isvfork ? 0 : rip->p_textp;
rpp->p_pid = mpid;
rpp->p_ppid = rip->p_pid;
+ rpp->p_pptr = rip;
rpp->p_time = 0;
rpp->p_cpu = 0;
+ rpp->p_siga0 = rip->p_siga0;
+ rpp->p_siga1 = rip->p_siga1;
+ /* take along any pending signals, like stops? */
if (isvfork) {
rpp->p_tsize = rpp->p_dsize = rpp->p_ssize = 0;
rpp->p_szpt = clrnd(ctopt(UPAGES));
rpp->p_rssize = 0;
rpp->p_wchan = 0;
rpp->p_slptime = 0;
- rpp->p_aveflt = rip->p_aveflt;
- rate.v_pgin += rip->p_aveflt;
- rpp->p_faults = 0;
+ rpp->p_pctcpu = 0;
+ rpp->p_cpticks = 0;
n = PIDHASH(rpp->p_pid);
p->p_idhash = pidhash[n];
pidhash[n] = rpp - proc;
for(n=0; n<NOFILE; n++)
if(u.u_ofile[n] != NULL) {
- u.u_ofile[n]->f_count++;
- if(!isvfork && u.u_vrpages[n])
- u.u_ofile[n]->f_inode->i_vfdcnt++;
+#ifdef UCBIPC
+ if (u.u_pofile[n] & ISPORT)
+ u.u_oport[n]->pt_count++;
+ else {
+#endif
+ u.u_ofile[n]->f_count++;
+ if(!isvfork && u.u_vrpages[n])
+ u.u_ofile[n]->f_inode->i_vfdcnt++;
+#ifdef UCBIPC
+ }
+#endif UCBIPC
}
u.u_cdir->i_count++;
if (procdup(rpp, isvfork))
return (1);
- spl6();
+ (void) spl6();
rpp->p_stat = SRUN;
setrq(rpp);
- spl0();
+ (void) spl0();
/* SSWAP NOT NEEDED IN THIS CASE AS u.u_pcb.pcb_sswap SUFFICES */
/* rpp->p_flag |= SSWAP; */
rip->p_flag &= ~SKEEP;