-/* kern_synch.c 3.1 %H% */
+/* kern_synch.c 3.14 %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"
-#ifdef FASTVAX
-asm(" .globl _eintr");
-#endif
#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 (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;
* (see trap1/trap.c)
*/
psig:
-#ifndef FASTVAX
longjmp(u.u_qsav);
-#else
- asm(".set U_SSAV,140");
- asm("movl _u+U_SSAV,fp");
- asm("movl _u+U_SSAV+4,sp");
- asm("movl _u+U_SSAV+8,r11");
- u.u_error = EINTR;
- asm("jmp _eintr");
-#endif
/*NOTREACHED*/
}
+/*
+ * Sleep on chan at pri.
+ * Return in no more than the indicated number of seconds.
+ * (If seconds==0, no timeout implied)
+ * Return TS_OK if chan was awakened normally
+ * TS_TIME if timeout occurred
+ * TS_SIG if asynchronous signal occurred
+ */
+tsleep(chan, pri, seconds)
+caddr_t chan;
+{
+ label_t lqsav;
+ register struct proc *pp;
+ register sec, n, rval;
+
+ pp = u.u_procp;
+ n = spl7();
+ sec = 0;
+ rval = 0;
+ if (pp->p_clktim && pp->p_clktim<seconds)
+ seconds = 0;
+ if (seconds) {
+ pp->p_flag |= STIMO;
+ sec = pp->p_clktim-seconds;
+ pp->p_clktim = seconds;
+ }
+ bcopy((caddr_t)u.u_qsav, (caddr_t)lqsav, sizeof (label_t));
+ if (setjmp(u.u_qsav))
+ rval = TS_SIG;
+ else {
+ sleep(chan, pri);
+ if ((pp->p_flag&STIMO)==0 && seconds)
+ rval = TS_TIME;
+ else
+ rval = TS_OK;
+ }
+ pp->p_flag &= ~STIMO;
+ bcopy((caddr_t)lqsav, (caddr_t)u.u_qsav, sizeof (label_t));
+ 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;
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_wchan = 0;
rpp->p_slptime = 0;
rpp->p_aveflt = rip->p_aveflt;
- rate.v_pgin += rip->p_aveflt;
rpp->p_faults = 0;
n = PIDHASH(rpp->p_pid);
p->p_idhash = pidhash[n];
rpp->p_stat = SRUN;
setrq(rpp);
spl0();
- /* THE SSWAP BIT IS REPLACED BY u.u_pcb.pcb_sswap SEE procdup */
+ /* SSWAP NOT NEEDED IN THIS CASE AS u.u_pcb.pcb_sswap SUFFICES */
/* rpp->p_flag |= SSWAP; */
rip->p_flag &= ~SKEEP;
if (isvfork) {