Annotation of researchv10no/sys/os/slp.c, revision 1.1

1.1     ! root        1: #include "sys/param.h"
        !             2: #include "sys/systm.h"
        !             3: #include "sys/user.h"
        !             4: #include "sys/proc.h"
        !             5: #include "sys/file.h"
        !             6: #include "sys/inode.h"
        !             7: #include "sys/vm.h"
        !             8: #include "sys/pte.h"
        !             9: #include "sys/mtpr.h"
        !            10: 
        !            11: #define SQSIZE 0100    /* Must be power of 2 */
        !            12: #define HASH(x)        (( (int) x >> 5) & (SQSIZE-1))
        !            13: struct proc *slpque[SQSIZE];
        !            14: 
        !            15: /*
        !            16:  * Give up the processor till a wakeup occurs
        !            17:  * on chan, at which time the process
        !            18:  * enters the scheduling queue at priority pri.
        !            19:  * The most important effect of pri is that when
        !            20:  * pri<=PZERO a signal cannot disturb the sleep;
        !            21:  * if pri>PZERO signals will be processed.
        !            22:  * Callers of this routine must be prepared for
        !            23:  * premature return, and check that the reason for
        !            24:  * sleeping has gone away.
        !            25:  */
        !            26: sleep(chan, pri)
        !            27: caddr_t chan;
        !            28: {
        !            29:        register struct proc *rp, **hp;
        !            30:        register s;
        !            31: 
        !            32:        rp = u.u_procp;
        !            33:        s = spl6();
        !            34:        if (chan==0 || rp->p_stat != SRUN || rp->p_rlink)
        !            35:                panic("sleep");
        !            36:        rp->p_wchan = chan;
        !            37:        rp->p_slptime = 0;
        !            38:        rp->p_pri = pri;
        !            39:        hp = &slpque[HASH(chan)];
        !            40:        rp->p_link = *hp;
        !            41:        *hp = rp;
        !            42:        if(pri > PZERO) {
        !            43:                if(rp->p_sig && issig()) {
        !            44:                        if (rp->p_wchan)
        !            45:                                unsleep(rp);
        !            46:                        rp->p_stat = SRUN;
        !            47:                        (void) spl0();
        !            48:                        goto psig;
        !            49:                }
        !            50:                if (rp->p_wchan == 0)
        !            51:                        goto out;
        !            52:                rp->p_stat = SSLEEP;
        !            53:                (void) spl0();
        !            54:                swtch();
        !            55:                if(rp->p_sig && issig())
        !            56:                        goto psig;
        !            57:        } else {
        !            58:                rp->p_stat = SSLEEP;
        !            59:                (void) spl0();
        !            60:                swtch();
        !            61:        }
        !            62: out:
        !            63:        splx(s);
        !            64:        return;
        !            65: 
        !            66:        /*
        !            67:         * If priority was low (>PZERO) and
        !            68:         * there has been a signal,
        !            69:         * execute non-local goto to
        !            70:         * the qsav location.
        !            71:         * (see trap1/trap.c)
        !            72:         */
        !            73: psig:
        !            74:        longjmp(u.u_qsav);
        !            75:        /*NOTREACHED*/
        !            76: }
        !            77: 
        !            78: /*
        !            79:  * Sleep on chan at pri.
        !            80:  * Return in no more than the indicated number of seconds.
        !            81:  * (If seconds==0, no timeout implied)
        !            82:  * Return      TS_OK if chan was awakened normally
        !            83:  *             TS_TIME if timeout occurred
        !            84:  *             TS_SIG if asynchronous signal occurred
        !            85:  */
        !            86: tsleep(chan, pri, seconds)
        !            87: caddr_t chan;
        !            88: {
        !            89:        label_t lqsav;
        !            90:        register n, rval;
        !            91:        register struct proc *pp = u.u_procp;
        !            92: 
        !            93:        n = spl7();
        !            94:        bcopy((caddr_t)u.u_qsav, (caddr_t)lqsav, sizeof (label_t));
        !            95:        pp->p_tsleep = seconds;
        !            96:        if (setjmp(u.u_qsav))
        !            97:                rval = TS_SIG;
        !            98:        else {
        !            99:                sleep(chan, pri);
        !           100:                if (pp->p_flag&STIMO)
        !           101:                        rval = TS_TIME;
        !           102:                else
        !           103:                        rval = TS_OK;
        !           104:        }
        !           105:        pp->p_flag &= ~STIMO;
        !           106:        bcopy((caddr_t)lqsav, (caddr_t)u.u_qsav, sizeof (label_t));
        !           107:        splx(n);
        !           108:        return(rval);
        !           109: }
        !           110: 
        !           111: /*
        !           112:  * Remove a process from its wait queue
        !           113:  */
        !           114: unsleep(p)
        !           115: register struct proc *p;
        !           116: {
        !           117:        register struct proc **hp;
        !           118:        register s;
        !           119: 
        !           120:        s = spl6();
        !           121:        if (p->p_wchan) {
        !           122:                hp = &slpque[HASH(p->p_wchan)];
        !           123:                while (*hp != p)
        !           124:                        hp = &(*hp)->p_link;
        !           125:                *hp = p->p_link;
        !           126:                p->p_wchan = 0;
        !           127:        }
        !           128:        splx(s);
        !           129: }
        !           130: 
        !           131: /*
        !           132:  * Wake up all processes sleeping on chan.
        !           133:  */
        !           134: wakeup(chan)
        !           135: register caddr_t chan;
        !           136: {
        !           137:        register struct proc *p, **q, **h;
        !           138:        int s;
        !           139: 
        !           140:        s = spl6();
        !           141:        h = &slpque[HASH(chan)];
        !           142: restart:
        !           143:        for (q = h; p = *q; ) {
        !           144:                if (p->p_rlink || p->p_stat != SSLEEP && p->p_stat != SSTOP)
        !           145:                        panic("wakeup");
        !           146:                if (p->p_wchan==chan) {
        !           147:                        p->p_wchan = 0;
        !           148:                        *q = p->p_link;
        !           149:                        p->p_slptime = 0;
        !           150:                        p->p_tsleep = 0;
        !           151:                        if (p->p_stat == SSLEEP) {
        !           152:                                /* OPTIMIZED INLINE EXPANSION OF setrun(p) */
        !           153:                                p->p_stat = SRUN;
        !           154:                                if (p->p_flag & SLOAD)
        !           155:                                        setrq(p);
        !           156:                                if(p->p_pri < curpri) {
        !           157:                                        runrun++;
        !           158:                                        aston();
        !           159:                                }
        !           160:                                if ((p->p_flag&SLOAD) == 0) {
        !           161:                                        if (runout != 0) {
        !           162:                                                runout = 0;
        !           163:                                                wakeup((caddr_t)&runout);
        !           164:                                        }
        !           165:                                        wantin++;
        !           166:                                }
        !           167:                                /* END INLINE EXPANSION */
        !           168:                                goto restart;
        !           169:                        }
        !           170:                } else
        !           171:                        q = &p->p_link;
        !           172:        }
        !           173:        splx(s);
        !           174: }
        !           175: 
        !           176: /*
        !           177:  * Initialize the (doubly-linked) run queues
        !           178:  * to be empty.
        !           179:  */
        !           180: rqinit()
        !           181: {
        !           182:        register int i;
        !           183: 
        !           184:        for (i = 0; i < NQS; i++)
        !           185:                qs[i].ph_link = qs[i].ph_rlink = (struct proc *)&qs[i];
        !           186: }
        !           187: 
        !           188: /*
        !           189:  * Set the process running;
        !           190:  * arrange for it to be swapped in if necessary.
        !           191:  */
        !           192: setrun(p)
        !           193: register struct proc *p;
        !           194: {
        !           195:        register s;
        !           196: 
        !           197:        s = spl6();
        !           198:        switch (p->p_stat) {
        !           199:        default:
        !           200:                panic("setrun");
        !           201: 
        !           202:        case SSTOP:
        !           203:        case SSLEEP:
        !           204:                unsleep(p);             /* e.g. when sending signals */
        !           205:                break;
        !           206: 
        !           207:        case SIDL:
        !           208:                break;
        !           209:        }
        !           210:        p->p_stat = SRUN;
        !           211:        if (p->p_flag & SLOAD)
        !           212:                setrq(p);
        !           213:        splx(s);
        !           214:        if(p->p_pri < curpri) {
        !           215:                runrun++;
        !           216:                aston();
        !           217:        }
        !           218:        if ((p->p_flag&SLOAD) == 0) {
        !           219:                if(runout != 0) {
        !           220:                        runout = 0;
        !           221:                        wakeup((caddr_t)&runout);
        !           222:                }
        !           223:                wantin++;
        !           224:        }
        !           225: }
        !           226: 
        !           227: /*
        !           228:  * Set user priority.
        !           229:  * The rescheduling flag (runrun)
        !           230:  * is set if the priority is better
        !           231:  * than the currently running process.
        !           232:  */
        !           233: setpri(pp)
        !           234: register struct proc *pp;
        !           235: {
        !           236:        register int p;
        !           237: 
        !           238:        p = pp->p_cpu/4;
        !           239:        p += PUSER + 2*(pp->p_nice - NZERO);
        !           240:        if (pp->p_rssize > pp->p_maxrss && freemem < desfree)
        !           241:                p += 2*4;       /* i.e. nice(4) */
        !           242:        if (p > PRIMAX)
        !           243:                p = PRIMAX;
        !           244:        if(p < curpri) {
        !           245:                runrun++;
        !           246:                aston();
        !           247:        }
        !           248:        pp->p_usrpri = p;
        !           249:        return(p);
        !           250: }
        !           251: 
        !           252: /*
        !           253:  * Create a new process--
        !           254:  * the internal version of sys fork.
        !           255:  * supply a process slot and a pid.
        !           256:  * returns 1 in the new process, 0 in the old.
        !           257:  */
        !           258: newproc(rpp, pid)
        !           259: register struct proc *rpp;
        !           260: int pid;
        !           261: {
        !           262:        register struct proc *rip;
        !           263:        register int n;
        !           264: 
        !           265:        /*
        !           266:         * init the proc entry
        !           267:         */
        !           268:        if (rpp->p_stat != 0)
        !           269:                panic("newproc");
        !           270:        rip = u.u_procp;
        !           271:        bzero((caddr_t)rpp, sizeof(*rpp));
        !           272:        rpp->p_stat = SIDL;
        !           273:        rpp->p_flag = SLOAD | (rip->p_flag & (SSEXEC|SPAGI|STRC|SPROCTR));
        !           274:        rpp->p_uid = rip->p_uid;
        !           275:        rpp->p_pgrp = rip->p_pgrp;
        !           276:        rpp->p_nice = rip->p_nice;
        !           277:        rpp->p_textp = rip->p_textp;
        !           278:        rpp->p_pid = pid;
        !           279:        rpp->p_ppid = rip->p_pid;
        !           280:        rpp->p_pptr = rip;
        !           281:        rpp->p_siga0 = rip->p_siga0;
        !           282:        rpp->p_siga1 = rip->p_siga1;
        !           283:        /* take along any pending signals, like stops? */
        !           284:        rpp->p_tsize = rip->p_tsize;
        !           285:        rpp->p_dsize = rip->p_dsize;
        !           286:        rpp->p_ssize = rip->p_ssize;
        !           287:        rpp->p_szpt = rip->p_szpt;
        !           288:        rpp->p_maxrss = rip->p_maxrss;
        !           289:        /*
        !           290:         * duplicate file references and so on
        !           291:         */
        !           292:        for(n=0; n<NOFILE; n++)
        !           293:                if(u.u_ofile[n] != NULL)
        !           294:                        u.u_ofile[n]->f_count++;
        !           295:        u.u_cdir->i_count++;
        !           296:        if (u.u_rdir)
        !           297:                u.u_rdir->i_count++;
        !           298:        /*
        !           299:         * make the copy
        !           300:         * child returns 1 when made runnable
        !           301:         * parent makes child runnable and returns 0
        !           302:         */
        !           303:        rip->p_flag |= SKEEP;   /* prevent parent from being swapped */
        !           304:        if (procdup(rpp))
        !           305:                return (1);
        !           306:        (void) spl6();
        !           307:        rpp->p_stat = SRUN;
        !           308:        setrq(rpp);
        !           309:        (void) spl0();
        !           310:        /* SSWAP NOT NEEDED IN THIS CASE AS u.u_pcb.pcb_sswap SUFFICES */
        !           311:        /* rpp->p_flag |= SSWAP; */
        !           312:        rip->p_flag &= ~SKEEP;
        !           313:        return (0);
        !           314: }

unix.superglobalmegacorp.com

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