Annotation of researchv10dc/sys/os/slp.c, revision 1.1.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.