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