minor fixups to restart stuff; version 4.1 for distrib
[unix-history] / usr / src / sys / kern / kern_synch.c
index 973121a..746f983 100644 (file)
@@ -1,4 +1,4 @@
-/*     kern_synch.c    3.7     %H%     */
+/*     kern_synch.c    4.1     %G%     */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -9,6 +9,7 @@
 #include "../h/inode.h"
 #include "../h/vm.h"
 #include "../h/pte.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 */
 
 
 #define SQSIZE 0100    /* Must be power of 2 */
@@ -29,40 +30,44 @@ struct proc *slpque[SQSIZE];
 sleep(chan, pri)
 caddr_t chan;
 {
 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 = 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;
        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(pri > PZERO) {
-               if(rp->p_sig && issig()) {
-                       rp->p_wchan = 0;
+               if(ISSIG(rp)) {
+                       if (rp->p_wchan)
+                               unsleep(rp);
                        rp->p_stat = SRUN;
                        rp->p_stat = SRUN;
-                       slpque[h] = rp->p_link;
                        (void) spl0();
                        goto psig;
                }
                        (void) spl0();
                        goto psig;
                }
+               if (rp->p_wchan == 0)
+                       goto out;
+               rp->p_stat = SSLEEP;
                (void) spl0();
                if(runin != 0) {
                        runin = 0;
                        wakeup((caddr_t)&runin);
                }
                swtch();
                (void) spl0();
                if(runin != 0) {
                        runin = 0;
                        wakeup((caddr_t)&runin);
                }
                swtch();
-               if(rp->p_sig && issig())
+               if(ISSIG(rp))
                        goto psig;
        } else {
                        goto psig;
        } else {
+               rp->p_stat = SSLEEP;
                (void) spl0();
                swtch();
        }
                (void) spl0();
                swtch();
        }
+out:
        splx(s);
        return;
 
        splx(s);
        return;
 
@@ -124,52 +129,67 @@ caddr_t chan;
        return(rval);
 }
 
        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;
 {
 /*
  * 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();
        int s;
 
        s = spl6();
-       i = HASH(chan);
+       h = &slpque[HASH(chan)];
 restart:
 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");
                        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;
                        p->p_wchan = 0;
+                       *q = p->p_link;
                        p->p_slptime = 0;
                        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
 #ifndef FASTVAX
-                               p->p_link = runq;
-                               runq = p->p_link;
+                                       p->p_link = runq;
+                                       runq = p->p_link;
 #else
 #else
-                               setrq(p);
+                                       setrq(p);
 #endif
 #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);
 }
        }
        splx(s);
 }
@@ -195,7 +215,6 @@ rqinit()
 setrun(p)
 register struct proc *p;
 {
 setrun(p)
 register struct proc *p;
 {
-       register caddr_t w;
        register s;
 
        s = spl6();
        register s;
 
        s = spl6();
@@ -208,16 +227,12 @@ register struct proc *p;
        default:
                panic("setrun");
 
        default:
                panic("setrun");
 
+       case SSTOP:
        case SSLEEP:
        case SSLEEP:
-               if (w = p->p_wchan) {
-                       wakeup(w);
-                       splx(s);
-                       return;
-               }
+               unsleep(p);             /* e.g. when sending signals */
                break;
 
        case SIDL:
                break;
 
        case SIDL:
-       case SSTOP:
                break;
        }
        p->p_stat = SRUN;
                break;
        }
        p->p_stat = SRUN;
@@ -244,7 +259,7 @@ register struct proc *pp;
        register p;
 
        p = (pp->p_cpu & 0377)/16;
        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 > 127)
                p = 127;
        if(p < curpri)
@@ -293,7 +308,7 @@ retry:
        rip = u.u_procp;
        rpp->p_stat = SIDL;
        rpp->p_clktim = 0;
        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;
        if (isvfork) {
                rpp->p_flag |= SVFORK;
                rpp->p_ndx = rip->p_ndx;
@@ -305,8 +320,12 @@ retry:
        rpp->p_textp = isvfork ? 0 : rip->p_textp;
        rpp->p_pid = mpid;
        rpp->p_ppid = rip->p_pid;
        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_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));
        if (isvfork) {
                rpp->p_tsize = rpp->p_dsize = rpp->p_ssize = 0;
                rpp->p_szpt = clrnd(ctopt(UPAGES));
@@ -323,9 +342,8 @@ retry:
        rpp->p_rssize = 0;
        rpp->p_wchan = 0;
        rpp->p_slptime = 0;
        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;
        n = PIDHASH(rpp->p_pid);
        p->p_idhash = pidhash[n];
        pidhash[n] = rpp - proc;