Annotation of researchv9/sys.vax/sys/slp.c, revision 1.1

1.1     ! root        1: /*     slp.c   4.14    81/06/11        */
        !             2: 
        !             3: #include "../h/param.h"
        !             4: #include "../h/systm.h"
        !             5: #include "../h/dir.h"
        !             6: #include "../h/user.h"
        !             7: #include "../h/lnode.h"
        !             8: #include "../h/proc.h"
        !             9: #include "../h/file.h"
        !            10: #include "../h/inode.h"
        !            11: #include "../h/vm.h"
        !            12: #include "../h/pte.h"
        !            13: #include "../h/mtpr.h"
        !            14: #include "../h/share.h"
        !            15: 
        !            16: #define SQSIZE 0100    /* Must be power of 2 */
        !            17: #define HASH(x)        (( (int) x >> 5) & (SQSIZE-1))
        !            18: struct proc *slpque[SQSIZE];
        !            19: 
        !            20: /*
        !            21:  * Give up the processor till a wakeup occurs
        !            22:  * on chan, at which time the process
        !            23:  * enters the scheduling queue at priority pri.
        !            24:  * The most important effect of pri is that when
        !            25:  * pri<=PZERO a signal cannot disturb the sleep;
        !            26:  * if pri>PZERO signals will be processed.
        !            27:  * Callers of this routine must be prepared for
        !            28:  * premature return, and check that the reason for
        !            29:  * sleeping has gone away.
        !            30:  */
        !            31: sleep(chan, pri)
        !            32: caddr_t chan;
        !            33: {
        !            34:        register struct proc *rp, **hp;
        !            35:        register s;
        !            36: 
        !            37:        rp = u.u_procp;
        !            38:        s = spl6();
        !            39:        if (chan==0 || rp->p_stat != SRUN || rp->p_rlink)
        !            40:                panic("sleep");
        !            41:        rp->p_wchan = chan;
        !            42:        rp->p_slptime = 0;
        !            43:        rp->p_pri = pri;
        !            44:        hp = &slpque[HASH(chan)];
        !            45:        rp->p_link = *hp;
        !            46:        *hp = rp;
        !            47:        if(pri > PZERO) {
        !            48:                if(rp->p_sig && issig(rp)) {
        !            49:                        if (rp->p_wchan)
        !            50:                                unsleep(rp);
        !            51:                        rp->p_stat = SRUN;
        !            52:                        (void) spl0();
        !            53:                        goto psig;
        !            54:                }
        !            55:                if (rp->p_wchan == 0)
        !            56:                        goto out;
        !            57:                rp->p_stat = SSLEEP;
        !            58:                (void) spl0();
        !            59:                swtch();
        !            60:                if(rp->p_sig && issig(rp))
        !            61:                        goto psig;
        !            62:        } else {
        !            63:                rp->p_stat = SSLEEP;
        !            64:                (void) spl0();
        !            65:                swtch();
        !            66:        }
        !            67: out:
        !            68:        splx(s);
        !            69:        return;
        !            70: 
        !            71:        /*
        !            72:         * If priority was low (>PZERO) and
        !            73:         * there has been a signal,
        !            74:         * execute non-local goto to
        !            75:         * the qsav location.
        !            76:         * (see trap1/trap.c)
        !            77:         */
        !            78: psig:
        !            79:        longjmp(u.u_qsav);
        !            80:        /*NOTREACHED*/
        !            81: }
        !            82: 
        !            83: /*
        !            84:  * Sleep on chan at pri.
        !            85:  * Return in no more than the indicated number of seconds.
        !            86:  * (If seconds==0, no timeout implied)
        !            87:  * Return      TS_OK if chan was awakened normally
        !            88:  *             TS_TIME if timeout occurred
        !            89:  *             TS_SIG if asynchronous signal occurred
        !            90:  */
        !            91: tsleep(chan, pri, seconds)
        !            92: caddr_t chan;
        !            93: {
        !            94:        label_t lqsav;
        !            95:        register n, rval;
        !            96:        register struct proc *pp = u.u_procp;
        !            97: 
        !            98:        n = spl7();
        !            99:        bcopy((caddr_t)u.u_qsav, (caddr_t)lqsav, sizeof (label_t));
        !           100:        pp->p_tsleep = seconds;
        !           101:        if (setjmp(u.u_qsav))
        !           102:                rval = TS_SIG;
        !           103:        else {
        !           104:                sleep(chan, pri);
        !           105:                if (pp->p_flag&STIMO)
        !           106:                        rval = TS_TIME;
        !           107:                else
        !           108:                        rval = TS_OK;
        !           109:        }
        !           110:        pp->p_tsleep = 0;
        !           111:        pp->p_flag &= ~STIMO;
        !           112:        bcopy((caddr_t)lqsav, (caddr_t)u.u_qsav, sizeof (label_t));
        !           113:        splx(n);
        !           114:        return(rval);
        !           115: }
        !           116: 
        !           117: /*
        !           118:  * Remove a process from its wait queue
        !           119:  */
        !           120: unsleep(p)
        !           121: register struct proc *p;
        !           122: {
        !           123:        register struct proc **hp;
        !           124:        register s;
        !           125: 
        !           126:        s = spl6();
        !           127:        if (p->p_wchan) {
        !           128:                hp = &slpque[HASH(p->p_wchan)];
        !           129:                while (*hp != p)
        !           130:                        hp = &(*hp)->p_link;
        !           131:                *hp = p->p_link;
        !           132:                p->p_wchan = 0;
        !           133:        }
        !           134:        splx(s);
        !           135: }
        !           136: 
        !           137: /*
        !           138:  * Wake up all processes sleeping on chan.
        !           139:  */
        !           140: wakeup(chan)
        !           141: register caddr_t chan;
        !           142: {
        !           143:        register struct proc *p, **q, **h;
        !           144:        int s;
        !           145: 
        !           146:        s = spl6();
        !           147:        h = &slpque[HASH(chan)];
        !           148: restart:
        !           149:        for (q = h; p = *q; ) {
        !           150:                if (p->p_rlink || p->p_stat != SSLEEP && p->p_stat != SSTOP)
        !           151:                        panic("wakeup");
        !           152:                if (p->p_wchan==chan) {
        !           153:                        p->p_wchan = 0;
        !           154:                        *q = p->p_link;
        !           155:                        p->p_slptime = 0;
        !           156:                        if (p->p_stat == SSLEEP) {
        !           157:                                /* OPTIMIZED INLINE EXPANSION OF setrun(p) */
        !           158:                                p->p_stat = SRUN;
        !           159:                                if (p->p_flag & SLOAD)
        !           160:                                        setrq(p);
        !           161:                                if(p->p_pri < curpri) {
        !           162:                                        runrun++;
        !           163:                                        aston();
        !           164:                                }
        !           165:                                if ((p->p_flag&SLOAD) == 0) {
        !           166:                                        if (runout != 0) {
        !           167:                                                runout = 0;
        !           168:                                                wakeup((caddr_t)&runout);
        !           169:                                        }
        !           170:                                        wantin++;
        !           171:                                }
        !           172:                                /* END INLINE EXPANSION */
        !           173:                                goto restart;
        !           174:                        }
        !           175:                } else
        !           176:                        q = &p->p_link;
        !           177:        }
        !           178:        splx(s);
        !           179: }
        !           180: 
        !           181: /*
        !           182:  * Initialize the (doubly-linked) run queues
        !           183:  * to be empty.
        !           184:  */
        !           185: rqinit()
        !           186: {
        !           187:        register int i;
        !           188: 
        !           189:        for (i = 0; i < NQS; i++)
        !           190:                qs[i].ph_link = qs[i].ph_rlink = (struct proc *)&qs[i];
        !           191: }
        !           192: 
        !           193: /*
        !           194:  * Set the process running;
        !           195:  * arrange for it to be swapped in if necessary.
        !           196:  */
        !           197: setrun(p)
        !           198: register struct proc *p;
        !           199: {
        !           200:        register s;
        !           201: 
        !           202:        s = spl6();
        !           203:        switch (p->p_stat) {
        !           204: 
        !           205:        case 0:
        !           206:        case SWAIT:
        !           207:        case SRUN:
        !           208:        case SZOMB:
        !           209:        default:
        !           210:                panic("setrun");
        !           211: 
        !           212:        case SSTOP:
        !           213:        case SSLEEP:
        !           214:                unsleep(p);             /* e.g. when sending signals */
        !           215:                break;
        !           216: 
        !           217:        case SIDL:
        !           218:                break;
        !           219:        }
        !           220:        p->p_stat = SRUN;
        !           221:        if (p->p_flag & SLOAD)
        !           222:                setrq(p);
        !           223:        splx(s);
        !           224:        if(p->p_pri < curpri) {
        !           225:                runrun++;
        !           226:                aston();
        !           227:        }
        !           228:        if ((p->p_flag&SLOAD) == 0) {
        !           229:                if(runout != 0) {
        !           230:                        runout = 0;
        !           231:                        wakeup((caddr_t)&runout);
        !           232:                }
        !           233:                wantin++;
        !           234:        }
        !           235: }
        !           236: 
        !           237: /*
        !           238:  * Set user priority.
        !           239:  * The rescheduling flag (runrun)
        !           240:  * is set if the priority is better
        !           241:  * than the currently running process.
        !           242:  *
        !           243:  * (Remember divide by 4 in setrq().)
        !           244:  */
        !           245: setpri(pp)
        !           246: register struct proc *pp;
        !           247: {
        !           248:        register int p;
        !           249:        register float f = pp->p_sharepri;
        !           250:        register int n = pp->p_nice;
        !           251: 
        !           252:        if (f > MaxSharePri || n == (2*NZERO-1)) {
        !           253:                if (pp->p_lnode->kl_norms) {
        !           254:                        if (n == (2*NZERO-1))
        !           255:                                p = 123;        /* Background process */
        !           256:                        else
        !           257:                                p = 119;        /* Background user */
        !           258:                } else
        !           259:                        p = 127;                /* Idle process */
        !           260:        } else {
        !           261:                f *= (float)((115-16)-PUSER);
        !           262:                p = f / MaxSharePri;
        !           263:                if (n > NZERO)
        !           264:                        p += 16;                /* Nice process */
        !           265:                if((p += PUSER) > 115)
        !           266:                        p = 115;
        !           267:        }
        !           268:        if(p < curpri) {
        !           269:                runrun++;
        !           270:                aston();
        !           271:        }
        !           272:        pp->p_usrpri = p;
        !           273:        return(p);
        !           274: }
        !           275: 
        !           276: /*
        !           277:  * Create a new process-- the internal version of
        !           278:  * sys fork.
        !           279:  * It returns 1 in the new process, 0 in the old.
        !           280:  */
        !           281: newproc(isvfork)
        !           282: {
        !           283:        register struct proc *p;
        !           284:        register struct proc *rpp, *rip;
        !           285:        register int n;
        !           286: 
        !           287:        p = NULL;
        !           288:        /*
        !           289:         * First, just locate a slot for a process
        !           290:         * and copy the useful info from this process into it.
        !           291:         * The panic "cannot happen" because fork has already
        !           292:         * checked for the existence of a slot.
        !           293:         */
        !           294: retry:
        !           295:        mpid++;
        !           296:        if(mpid >= 30000) {
        !           297:                mpid = 0;
        !           298:                goto retry;
        !           299:        }
        !           300:        for(rpp = proc; rpp < procNPROC; rpp++) {
        !           301:                if(rpp->p_stat == NULL && p==NULL)
        !           302:                        p = rpp;
        !           303:                if (rpp->p_pid==mpid || rpp->p_pgrp==mpid)
        !           304:                        goto retry;
        !           305:        }
        !           306:        if ((rpp = p)==NULL)
        !           307:                panic("no procs");
        !           308: 
        !           309:        /*
        !           310:         * make proc entry for new proc
        !           311:         */
        !           312: 
        !           313:        rip = u.u_procp;
        !           314:        rpp->p_stat = SIDL;
        !           315:        rpp->p_clktim = 0;
        !           316:        rpp->p_flag = SLOAD | (rip->p_flag & (SSEXEC|SPAGI|SDETACH|SNUSIG|STRC|SPROCTR));
        !           317:        if (isvfork) {
        !           318:                rpp->p_flag |= SVFORK;
        !           319:                rpp->p_ndx = rip->p_ndx;
        !           320:        } else
        !           321:                rpp->p_ndx = rpp - proc;
        !           322:        rpp->p_uid = rip->p_uid;
        !           323:        rpp->p_pgrp = rip->p_pgrp;
        !           324:        rpp->p_nice = rip->p_nice;
        !           325:        rpp->p_textp = isvfork ? 0 : rip->p_textp;
        !           326:        rpp->p_pid = mpid;
        !           327:        rpp->p_ppid = rip->p_pid;
        !           328:        rpp->p_pptr = rip;
        !           329:        rpp->p_time = 0;
        !           330:        rpp->p_cpu = 0;
        !           331:        rpp->p_siga0 = rip->p_siga0;
        !           332:        rpp->p_siga1 = rip->p_siga1;
        !           333:        /* take along any pending signals, like stops? */
        !           334:        if (isvfork) {
        !           335:                rpp->p_tsize = rpp->p_dsize = rpp->p_ssize = 0;
        !           336:                rpp->p_szpt = clrnd(ctopt(UPAGES));
        !           337:                forkstat.cntvfork++;
        !           338:                forkstat.sizvfork += rip->p_dsize + rip->p_ssize;
        !           339:        } else {
        !           340:                rpp->p_tsize = rip->p_tsize;
        !           341:                rpp->p_dsize = rip->p_dsize;
        !           342:                rpp->p_ssize = rip->p_ssize;
        !           343:                rip->p_lnode->kl_muse += rip->p_dsize + rip->p_ssize;
        !           344:                rpp->p_szpt = rip->p_szpt;
        !           345:                forkstat.cntfork++;
        !           346:                forkstat.sizfork += rip->p_dsize + rip->p_ssize;
        !           347:        }
        !           348:        rpp->p_rssize = 0;
        !           349:        rpp->p_maxrss = rip->p_maxrss;
        !           350:        rpp->p_wchan = 0;
        !           351:        rpp->p_slptime = 0;
        !           352:        rpp->p_pctcpu = 0;
        !           353:        rpp->p_cpticks = 0;
        !           354:        rpp->p_lnode = rip->p_lnode;
        !           355:        rpp->p_sharepri = rip->p_sharepri;
        !           356:        rpp->p_lnode->kl_refcount++;
        !           357:        n = PIDHASH(rpp->p_pid);
        !           358:        p->p_idhash = pidhash[n];
        !           359:        pidhash[n] = rpp - proc;
        !           360: 
        !           361:        /*
        !           362:         * make duplicate entries
        !           363:         * where needed
        !           364:         */
        !           365: 
        !           366:        multprog++;
        !           367: 
        !           368:        for(n=0; n<NOFILE; n++)
        !           369:                if(u.u_ofile[n] != NULL)
        !           370:                        u.u_ofile[n]->f_count++;
        !           371: 
        !           372:        u.u_cdir->i_count++;
        !           373:        if (u.u_rdir)
        !           374:                u.u_rdir->i_count++;
        !           375:        /*
        !           376:         * Partially simulate the environment
        !           377:         * of the new process so that when it is actually
        !           378:         * created (by copying) it will look right.
        !           379:         */
        !           380: 
        !           381:        rip->p_flag |= SKEEP;   /* prevent parent from being swapped */
        !           382: 
        !           383:        if (procdup(rpp, isvfork))
        !           384:                return (1);
        !           385: 
        !           386:        (void) spl6();
        !           387:        rpp->p_stat = SRUN;
        !           388:        setrq(rpp);
        !           389:        (void) spl0();
        !           390:        /* SSWAP NOT NEEDED IN THIS CASE AS u.u_pcb.pcb_sswap SUFFICES */
        !           391:        /* rpp->p_flag |= SSWAP; */
        !           392:        rip->p_flag &= ~SKEEP;
        !           393:        if (isvfork) {
        !           394:                u.u_procp->p_xlink = rpp;
        !           395:                u.u_procp->p_flag |= SNOVM;
        !           396:                while (rpp->p_flag & SVFORK)
        !           397:                        sleep((caddr_t)rpp, PZERO - 1);
        !           398:                if ((rpp->p_flag & SLOAD) == 0)
        !           399:                        panic("newproc vfork");
        !           400:                uaccess(rpp, Vfmap, &vfutl);
        !           401:                u.u_procp->p_xlink = 0;
        !           402:                vpassvm(rpp, u.u_procp, &vfutl, &u, Vfmap);
        !           403:                u.u_procp->p_flag &= ~SNOVM;
        !           404:                rpp->p_ndx = rpp - proc;
        !           405:                rpp->p_flag |= SVFDONE;
        !           406:                wakeup((caddr_t)rpp);
        !           407:        }
        !           408:        return (0);
        !           409: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.