-/* kern_synch.c 3.5 %H% */
+/* kern_synch.c 4.2 %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"
#define SQSIZE 0100 /* Must be power of 2 */
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 (rp->p_wchan == 0)
+ goto out;
+ rp->p_stat = SSLEEP;
+ (void) spl0();
if(runin != 0) {
runin = 0;
wakeup((caddr_t)&runin);
}
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;
seconds = 0;
if (seconds) {
pp->p_flag |= STIMO;
- if ((sec = pp->p_clktim-seconds) < 0)
- sec = 0;
+ sec = pp->p_clktim-seconds;
pp->p_clktim = seconds;
}
bcopy((caddr_t)u.u_qsav, (caddr_t)lqsav, sizeof (label_t));
}
pp->p_flag &= ~STIMO;
bcopy((caddr_t)lqsav, (caddr_t)u.u_qsav, sizeof (label_t));
- pp->p_clktim += sec;
+ if (sec > 0)
+ pp->p_clktim += sec;
+ else
+ pp->p_clktim = 0;
splx(n);
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) {
+ if (p->p_stat == SSLEEP) {
+ /* 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;
+ p->p_link = runq;
+ runq = p->p_link;
#else
- setrq(p);
+ setrq(p);
#endif
+ }
+ if(p->p_pri < curpri)
+ runrun++;
+ if(runout != 0 && (p->p_flag&SLOAD) == 0) {
+ runout = 0;
+ wakeup((caddr_t)&runout);
+ }
+ /* END INLINE EXPANSION */
+ goto restart;
}
- if(p->p_pri < curpri)
- runrun++;
- if(runout != 0 && (p->p_flag&SLOAD) == 0) {
- runout = 0;
- wakeup((caddr_t)&runout);
- }
- /* END INLINE EXPANSION */
- goto restart;
- }
- q = p;
- p = p->p_link;
+ } else
+ q = &p->p_link;
}
splx(s);
}
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;
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)
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;
if (procdup(rpp, isvfork))
return (1);
- spl6();
+ (void) spl6();
rpp->p_stat = SRUN;
setrq(rpp);
spl0();