Annotation of Net2/kern/kern_synch.c, revision 1.1.1.4

1.1       root        1: /*-
                      2:  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
                      3:  * Copyright (c) 1991 The Regents of the University of California.
                      4:  * All rights reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  * 3. All advertising materials mentioning features or use of this software
                     15:  *    must display the following acknowledgement:
                     16:  *     This product includes software developed by the University of
                     17:  *     California, Berkeley and its contributors.
                     18:  * 4. Neither the name of the University nor the names of its contributors
                     19:  *    may be used to endorse or promote products derived from this software
                     20:  *    without specific prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     32:  * SUCH DAMAGE.
                     33:  *
1.1.1.4 ! root       34:  *     from: @(#)kern_synch.c  7.18 (Berkeley) 6/27/91
        !            35:  *     kern_synch.c,v 1.8 1993/06/27 06:22:32 andrew Exp
1.1       root       36:  */
                     37: 
                     38: #include "param.h"
                     39: #include "systm.h"
                     40: #include "proc.h"
                     41: #include "kernel.h"
                     42: #include "buf.h"
                     43: #include "signalvar.h"
                     44: #include "resourcevar.h"
                     45: 
                     46: #include "machine/cpu.h"
                     47: 
1.1.1.4 ! root       48: void endtsleep __P((struct proc *p));
        !            49: 
1.1       root       50: u_char curpri;                 /* usrpri of curproc */
                     51: 
                     52: /*
                     53:  * Force switch among equal priority processes every 100ms.
                     54:  */
1.1.1.4 ! root       55: /* ARGSUSED */
        !            56: void
        !            57: roundrobin(caddr_t arg)
1.1       root       58: {
                     59: 
                     60:        need_resched();
                     61:        timeout(roundrobin, (caddr_t)0, hz / 10);
                     62: }
                     63: 
                     64: /*
                     65:  * constants for digital decay and forget
                     66:  *     90% of (p_cpu) usage in 5*loadav time
                     67:  *     95% of (p_pctcpu) usage in 60 seconds (load insensitive)
                     68:  *          Note that, as ps(1) mentions, this can let percentages
                     69:  *          total over 100% (I've seen 137.9% for 3 processes).
                     70:  *
                     71:  * Note that hardclock updates p_cpu and p_cpticks independently.
                     72:  *
                     73:  * We wish to decay away 90% of p_cpu in (5 * loadavg) seconds.
                     74:  * That is, the system wants to compute a value of decay such
                     75:  * that the following for loop:
                     76:  *     for (i = 0; i < (5 * loadavg); i++)
                     77:  *             p_cpu *= decay;
                     78:  * will compute
                     79:  *     p_cpu *= 0.1;
                     80:  * for all values of loadavg:
                     81:  *
                     82:  * Mathematically this loop can be expressed by saying:
                     83:  *     decay ** (5 * loadavg) ~= .1
                     84:  *
                     85:  * The system computes decay as:
                     86:  *     decay = (2 * loadavg) / (2 * loadavg + 1)
                     87:  *
                     88:  * We wish to prove that the system's computation of decay
                     89:  * will always fulfill the equation:
                     90:  *     decay ** (5 * loadavg) ~= .1
                     91:  *
                     92:  * If we compute b as:
                     93:  *     b = 2 * loadavg
                     94:  * then
                     95:  *     decay = b / (b + 1)
                     96:  *
                     97:  * We now need to prove two things:
                     98:  *     1) Given factor ** (5 * loadavg) ~= .1, prove factor == b/(b+1)
                     99:  *     2) Given b/(b+1) ** power ~= .1, prove power == (5 * loadavg)
                    100:  *     
                    101:  * Facts:
                    102:  *         For x close to zero, exp(x) =~ 1 + x, since
                    103:  *              exp(x) = 0! + x**1/1! + x**2/2! + ... .
                    104:  *              therefore exp(-1/b) =~ 1 - (1/b) = (b-1)/b.
                    105:  *         For x close to zero, ln(1+x) =~ x, since
                    106:  *              ln(1+x) = x - x**2/2 + x**3/3 - ...     -1 < x < 1
                    107:  *              therefore ln(b/(b+1)) = ln(1 - 1/(b+1)) =~ -1/(b+1).
                    108:  *         ln(.1) =~ -2.30
                    109:  *
                    110:  * Proof of (1):
                    111:  *    Solve (factor)**(power) =~ .1 given power (5*loadav):
                    112:  *     solving for factor,
                    113:  *      ln(factor) =~ (-2.30/5*loadav), or
                    114:  *      factor =~ exp(-1/((5/2.30)*loadav)) =~ exp(-1/(2*loadav)) =
                    115:  *          exp(-1/b) =~ (b-1)/b =~ b/(b+1).                    QED
                    116:  *
                    117:  * Proof of (2):
                    118:  *    Solve (factor)**(power) =~ .1 given factor == (b/(b+1)):
                    119:  *     solving for power,
                    120:  *      power*ln(b/(b+1)) =~ -2.30, or
                    121:  *      power =~ 2.3 * (b + 1) = 4.6*loadav + 2.3 =~ 5*loadav.  QED
                    122:  *
                    123:  * Actual power values for the implemented algorithm are as follows:
                    124:  *      loadav: 1       2       3       4
                    125:  *      power:  5.68    10.32   14.94   19.55
                    126:  */
                    127: 
                    128: /* calculations for digital decay to forget 90% of usage in 5*loadav sec */
                    129: #define        loadfactor(loadav)      (2 * (loadav))
                    130: #define        decay_cpu(loadfac, cpu) (((loadfac) * (cpu)) / ((loadfac) + FSCALE))
                    131: 
                    132: /* decay 95% of `p_pctcpu' in 60 seconds; see CCPU_SHIFT before changing */
                    133: fixpt_t        ccpu = 0.95122942450071400909 * FSCALE;         /* exp(-1/20) */
                    134: 
                    135: /*
                    136:  * If `ccpu' is not equal to `exp(-1/20)' and you still want to use the
                    137:  * faster/more-accurate formula, you'll have to estimate CCPU_SHIFT below
                    138:  * and possibly adjust FSHIFT in "param.h" so that (FSHIFT >= CCPU_SHIFT).
                    139:  *
                    140:  * To estimate CCPU_SHIFT for exp(-1/20), the following formula was used:
                    141:  *     1 - exp(-1/20) ~= 0.0487 ~= 0.0488 == 1 (fixed pt, *11* bits).
                    142:  *
                    143:  * If you dont want to bother with the faster/more-accurate formula, you
                    144:  * can set CCPU_SHIFT to (FSHIFT + 1) which will use a slower/less-accurate
                    145:  * (more general) method of calculating the %age of CPU used by a process.
                    146:  */
                    147: #define        CCPU_SHIFT      11
                    148: 
                    149: /*
                    150:  * Recompute process priorities, once a second
                    151:  */
1.1.1.4 ! root      152: /* ARGSUSED */
        !           153: void
        !           154: schedcpu(caddr_t arg)
1.1       root      155: {
                    156:        register fixpt_t loadfac = loadfactor(averunnable[0]);
                    157:        register struct proc *p;
                    158:        register int s;
                    159:        register unsigned int newcpu;
                    160: 
                    161:        wakeup((caddr_t)&lbolt);
                    162:        for (p = allproc; p != NULL; p = p->p_nxt) {
                    163:                /*
                    164:                 * Increment time in/out of memory and sleep time
                    165:                 * (if sleeping).  We ignore overflow; with 16-bit int's
                    166:                 * (remember them?) overflow takes 45 days.
                    167:                 */
                    168:                p->p_time++;
                    169:                if (p->p_stat == SSLEEP || p->p_stat == SSTOP)
                    170:                        p->p_slptime++;
                    171:                p->p_pctcpu = (p->p_pctcpu * ccpu) >> FSHIFT;
                    172:                /*
                    173:                 * If the process has slept the entire second,
                    174:                 * stop recalculating its priority until it wakes up.
                    175:                 */
                    176:                if (p->p_slptime > 1)
                    177:                        continue;
                    178:                /*
                    179:                 * p_pctcpu is only for ps.
                    180:                 */
                    181: #if    (FSHIFT >= CCPU_SHIFT)
                    182:                p->p_pctcpu += (hz == 100)?
                    183:                        ((fixpt_t) p->p_cpticks) << (FSHIFT - CCPU_SHIFT):
                    184:                        100 * (((fixpt_t) p->p_cpticks)
                    185:                                << (FSHIFT - CCPU_SHIFT)) / hz;
                    186: #else
                    187:                p->p_pctcpu += ((FSCALE - ccpu) *
                    188:                        (p->p_cpticks * FSCALE / hz)) >> FSHIFT;
                    189: #endif
                    190:                p->p_cpticks = 0;
                    191:                newcpu = (u_int) decay_cpu(loadfac, p->p_cpu) + p->p_nice;
                    192:                p->p_cpu = min(newcpu, UCHAR_MAX);
                    193:                setpri(p);
                    194:                s = splhigh();  /* prevent state changes */
                    195:                if (p->p_pri >= PUSER) {
                    196: #define        PPQ     (128 / NQS)             /* priorities per queue */
                    197:                        if ((p != curproc) &&
                    198:                            p->p_stat == SRUN &&
1.1.1.3   root      199:                            (p->p_flag & (SLOAD|SWEXIT)) == SLOAD &&
1.1       root      200:                            (p->p_pri / PPQ) != (p->p_usrpri / PPQ)) {
                    201:                                remrq(p);
                    202:                                p->p_pri = p->p_usrpri;
                    203:                                setrq(p);
                    204:                        } else
                    205:                                p->p_pri = p->p_usrpri;
                    206:                }
                    207:                splx(s);
                    208:        }
                    209:        vmmeter();
                    210:        if (bclnlist != NULL)
                    211:                wakeup((caddr_t)pageproc);
                    212:        timeout(schedcpu, (caddr_t)0, hz);
                    213: }
                    214: 
                    215: /*
                    216:  * Recalculate the priority of a process after it has slept for a while.
                    217:  * For all load averages >= 1 and max p_cpu of 255, sleeping for at least
                    218:  * six times the loadfactor will decay p_cpu to zero.
                    219:  */
1.1.1.4 ! root      220: void
1.1       root      221: updatepri(p)
                    222:        register struct proc *p;
                    223: {
                    224:        register unsigned int newcpu = p->p_cpu;
                    225:        register fixpt_t loadfac = loadfactor(averunnable[0]);
                    226: 
                    227:        if (p->p_slptime > 5 * loadfac)
                    228:                p->p_cpu = 0;
                    229:        else {
                    230:                p->p_slptime--; /* the first time was done in schedcpu */
                    231:                while (newcpu && --p->p_slptime)
                    232:                        newcpu = (int) decay_cpu(loadfac, newcpu);
                    233:                p->p_cpu = min(newcpu, UCHAR_MAX);
                    234:        }
                    235:        setpri(p);
                    236: }
                    237: 
                    238: #define SQSIZE 0100    /* Must be power of 2 */
                    239: #define HASH(x)        (( (int) x >> 5) & (SQSIZE-1))
                    240: struct slpque {
                    241:        struct proc *sq_head;
                    242:        struct proc **sq_tailp;
                    243: } slpque[SQSIZE];
                    244: 
                    245: /*
                    246:  * During autoconfiguration or after a panic, a sleep will simply
                    247:  * lower the priority briefly to allow interrupts, then return.
                    248:  * The priority to be used (safepri) is machine-dependent, thus this
                    249:  * value is initialized and maintained in the machine-dependent layers.
                    250:  * This priority will typically be 0, or the lowest priority
                    251:  * that is safe for use on the interrupt stack; it can be made
                    252:  * higher to block network software interrupts after panics.
                    253:  */
                    254: int safepri;
                    255: 
                    256: /*
                    257:  * General sleep call.
                    258:  * Suspends current process until a wakeup is made on chan.
                    259:  * The process will then be made runnable with priority pri.
                    260:  * Sleeps at most timo/hz seconds (0 means no timeout).
                    261:  * If pri includes PCATCH flag, signals are checked
                    262:  * before and after sleeping, else signals are not checked.
                    263:  * Returns 0 if awakened, EWOULDBLOCK if the timeout expires.
                    264:  * If PCATCH is set and a signal needs to be delivered,
                    265:  * ERESTART is returned if the current system call should be restarted
                    266:  * if possible, and EINTR is returned if the system call should
                    267:  * be interrupted by the signal (return EINTR).
                    268:  */
1.1.1.4 ! root      269: int
        !           270: #ifdef __STDC__
        !           271: tsleep(caddr_t chan, int pri, const char *wmesg, int timo)
        !           272: #else
1.1       root      273: tsleep(chan, pri, wmesg, timo)
                    274:        caddr_t chan;
                    275:        int pri;
                    276:        char *wmesg;
                    277:        int timo;
1.1.1.4 ! root      278: #endif
1.1       root      279: {
                    280:        register struct proc *p = curproc;
                    281:        register struct slpque *qp;
                    282:        register s;
                    283:        int sig, catch = pri & PCATCH;
                    284:        extern int cold;
                    285: 
                    286:        s = splhigh();
                    287:        if (cold || panicstr) {
                    288:                /*
                    289:                 * After a panic, or during autoconfiguration,
                    290:                 * just give interrupts a chance, then just return;
                    291:                 * don't run any other procs or panic below,
                    292:                 * in case this is the idle process and already asleep.
                    293:                 */
                    294:                splx(safepri);
                    295:                splx(s);
                    296:                return (0);
                    297:        }
                    298: #ifdef DIAGNOSTIC
                    299:        if (chan == 0 || p->p_stat != SRUN || p->p_rlink)
                    300:                panic("tsleep");
                    301: #endif
                    302:        p->p_wchan = chan;
                    303:        p->p_wmesg = wmesg;
                    304:        p->p_slptime = 0;
                    305:        p->p_pri = pri & PRIMASK;
                    306:        qp = &slpque[HASH(chan)];
                    307:        if (qp->sq_head == 0)
                    308:                qp->sq_head = p;
                    309:        else
                    310:                *qp->sq_tailp = p;
                    311:        *(qp->sq_tailp = &p->p_link) = 0;
                    312:        if (timo)
1.1.1.4 ! root      313:                timeout((timeout_t)endtsleep, (caddr_t)p, timo);
1.1       root      314:        /*
                    315:         * We put ourselves on the sleep queue and start our timeout
                    316:         * before calling CURSIG, as we could stop there, and a wakeup
                    317:         * or a SIGCONT (or both) could occur while we were stopped.
                    318:         * A SIGCONT would cause us to be marked as SSLEEP
                    319:         * without resuming us, thus we must be ready for sleep
                    320:         * when CURSIG is called.  If the wakeup happens while we're
                    321:         * stopped, p->p_wchan will be 0 upon return from CURSIG.
                    322:         */
                    323:        if (catch) {
                    324:                p->p_flag |= SSINTR;
                    325:                if (sig = CURSIG(p)) {
                    326:                        if (p->p_wchan)
                    327:                                unsleep(p);
                    328:                        p->p_stat = SRUN;
                    329:                        goto resume;
                    330:                }
                    331:                if (p->p_wchan == 0) {
                    332:                        catch = 0;
                    333:                        goto resume;
                    334:                }
                    335:        }
                    336:        p->p_stat = SSLEEP;
                    337:        p->p_stats->p_ru.ru_nvcsw++;
                    338:        swtch();
1.1.1.4 ! root      339: #ifdef DDB
1.1.1.2   root      340:        /* handy breakpoint location after process "wakes" */
                    341:        asm(".globl bpendtsleep ; bpendtsleep:");
                    342: #endif
1.1       root      343: resume:
                    344:        curpri = p->p_usrpri;
                    345:        splx(s);
                    346:        p->p_flag &= ~SSINTR;
                    347:        if (p->p_flag & STIMO) {
                    348:                p->p_flag &= ~STIMO;
                    349:                if (catch == 0 || sig == 0)
                    350:                        return (EWOULDBLOCK);
                    351:        } else if (timo)
1.1.1.4 ! root      352:                untimeout((timeout_t)endtsleep, (caddr_t)p);
1.1       root      353:        if (catch && (sig != 0 || (sig = CURSIG(p)))) {
                    354:                if (p->p_sigacts->ps_sigintr & sigmask(sig))
                    355:                        return (EINTR);
                    356:                return (ERESTART);
                    357:        }
                    358:        return (0);
                    359: }
                    360: 
                    361: /*
                    362:  * Implement timeout for tsleep.
                    363:  * If process hasn't been awakened (wchan non-zero),
                    364:  * set timeout flag and undo the sleep.  If proc
                    365:  * is stopped, just unsleep so it will remain stopped.
                    366:  */
1.1.1.4 ! root      367: void
1.1       root      368: endtsleep(p)
                    369:        register struct proc *p;
                    370: {
                    371:        int s = splhigh();
                    372: 
                    373:        if (p->p_wchan) {
                    374:                if (p->p_stat == SSLEEP)
                    375:                        setrun(p);
                    376:                else
                    377:                        unsleep(p);
                    378:                p->p_flag |= STIMO;
                    379:        }
                    380:        splx(s);
                    381: }
                    382: 
                    383: /*
                    384:  * Short-term, non-interruptable sleep.
                    385:  */
1.1.1.4 ! root      386: void
1.1       root      387: sleep(chan, pri)
                    388:        caddr_t chan;
                    389:        int pri;
                    390: {
                    391:        register struct proc *p = curproc;
                    392:        register struct slpque *qp;
                    393:        register s;
                    394:        extern int cold;
                    395: 
                    396: #ifdef DIAGNOSTIC
                    397:        if (pri > PZERO) {
                    398:                printf("sleep called with pri %d > PZERO, wchan: %x\n",
                    399:                        pri, chan);
                    400:                panic("old sleep");
                    401:        }
                    402: #endif
                    403:        s = splhigh();
                    404:        if (cold || panicstr) {
                    405:                /*
                    406:                 * After a panic, or during autoconfiguration,
                    407:                 * just give interrupts a chance, then just return;
                    408:                 * don't run any other procs or panic below,
                    409:                 * in case this is the idle process and already asleep.
                    410:                 */
                    411:                splx(safepri);
                    412:                splx(s);
                    413:                return;
                    414:        }
                    415: #ifdef DIAGNOSTIC
                    416:        if (chan==0 || p->p_stat != SRUN || p->p_rlink)
                    417:                panic("sleep");
                    418: #endif
                    419:        p->p_wchan = chan;
                    420:        p->p_wmesg = NULL;
                    421:        p->p_slptime = 0;
                    422:        p->p_pri = pri;
                    423:        qp = &slpque[HASH(chan)];
                    424:        if (qp->sq_head == 0)
                    425:                qp->sq_head = p;
                    426:        else
                    427:                *qp->sq_tailp = p;
                    428:        *(qp->sq_tailp = &p->p_link) = 0;
                    429:        p->p_stat = SSLEEP;
                    430:        p->p_stats->p_ru.ru_nvcsw++;
                    431:        swtch();
1.1.1.4 ! root      432: #ifdef DDB
1.1.1.2   root      433:        /* handy breakpoint location after process "wakes" */
                    434:        asm(".globl bpendsleep ; bpendsleep:");
                    435: #endif
1.1       root      436:        curpri = p->p_usrpri;
                    437:        splx(s);
                    438: }
                    439: 
                    440: /*
                    441:  * Remove a process from its wait queue
                    442:  */
1.1.1.4 ! root      443: void
1.1       root      444: unsleep(p)
                    445:        register struct proc *p;
                    446: {
                    447:        register struct slpque *qp;
                    448:        register struct proc **hp;
                    449:        int s;
                    450: 
                    451:        s = splhigh();
                    452:        if (p->p_wchan) {
                    453:                hp = &(qp = &slpque[HASH(p->p_wchan)])->sq_head;
                    454:                while (*hp != p)
                    455:                        hp = &(*hp)->p_link;
                    456:                *hp = p->p_link;
                    457:                if (qp->sq_tailp == &p->p_link)
                    458:                        qp->sq_tailp = hp;
                    459:                p->p_wchan = 0;
                    460:        }
                    461:        splx(s);
                    462: }
                    463: 
                    464: /*
                    465:  * Wakeup on "chan"; set all processes
                    466:  * sleeping on chan to run state.
                    467:  */
1.1.1.4 ! root      468: void
1.1       root      469: wakeup(chan)
                    470:        register caddr_t chan;
                    471: {
                    472:        register struct slpque *qp;
                    473:        register struct proc *p, **q;
                    474:        int s;
                    475: 
                    476:        s = splhigh();
                    477:        qp = &slpque[HASH(chan)];
                    478: restart:
                    479:        for (q = &qp->sq_head; p = *q; ) {
                    480: #ifdef DIAGNOSTIC
                    481:                if (p->p_rlink || p->p_stat != SSLEEP && p->p_stat != SSTOP)
                    482:                        panic("wakeup");
                    483: #endif
                    484:                if (p->p_wchan == chan) {
                    485:                        p->p_wchan = 0;
                    486:                        *q = p->p_link;
                    487:                        if (qp->sq_tailp == &p->p_link)
                    488:                                qp->sq_tailp = q;
                    489:                        if (p->p_stat == SSLEEP) {
                    490:                                /* OPTIMIZED INLINE EXPANSION OF setrun(p) */
                    491:                                if (p->p_slptime > 1)
                    492:                                        updatepri(p);
                    493:                                p->p_slptime = 0;
                    494:                                p->p_stat = SRUN;
                    495:                                if (p->p_flag & SLOAD)
                    496:                                        setrq(p);
                    497:                                /*
                    498:                                 * Since curpri is a usrpri,
                    499:                                 * p->p_pri is always better than curpri.
                    500:                                 */
                    501:                                if ((p->p_flag&SLOAD) == 0)
                    502:                                        wakeup((caddr_t)&proc0);
                    503:                                else
                    504:                                        need_resched();
                    505:                                /* END INLINE EXPANSION */
                    506:                                goto restart;
                    507:                        }
                    508:                } else
                    509:                        q = &p->p_link;
                    510:        }
                    511:        splx(s);
                    512: }
                    513: 
                    514: /*
                    515:  * Initialize the (doubly-linked) run queues
                    516:  * to be empty.
                    517:  */
1.1.1.4 ! root      518: void
1.1       root      519: rqinit()
                    520: {
                    521:        register int i;
                    522: 
                    523:        for (i = 0; i < NQS; i++)
                    524:                qs[i].ph_link = qs[i].ph_rlink = (struct proc *)&qs[i];
                    525: }
                    526: 
                    527: /*
                    528:  * Change process state to be runnable,
                    529:  * placing it on the run queue if it is in memory,
                    530:  * and awakening the swapper if it isn't in memory.
                    531:  */
1.1.1.4 ! root      532: void
1.1       root      533: setrun(p)
                    534:        register struct proc *p;
                    535: {
                    536:        register int s;
                    537: 
                    538:        s = splhigh();
                    539:        switch (p->p_stat) {
                    540: 
                    541:        case 0:
                    542:        case SWAIT:
                    543:        case SRUN:
                    544:        case SZOMB:
                    545:        default:
                    546:                panic("setrun");
                    547: 
                    548:        case SSTOP:
                    549:        case SSLEEP:
                    550:                unsleep(p);             /* e.g. when sending signals */
                    551:                break;
                    552: 
                    553:        case SIDL:
                    554:                break;
                    555:        }
                    556:        p->p_stat = SRUN;
                    557:        if (p->p_flag & SLOAD)
                    558:                setrq(p);
                    559:        splx(s);
                    560:        if (p->p_slptime > 1)
                    561:                updatepri(p);
                    562:        p->p_slptime = 0;
                    563:        if ((p->p_flag&SLOAD) == 0)
                    564:                wakeup((caddr_t)&proc0);
                    565:        else if (p->p_pri < curpri)
                    566:                need_resched();
                    567: }
                    568: 
                    569: /*
                    570:  * Compute priority of process when running in user mode.
                    571:  * Arrange to reschedule if the resulting priority
                    572:  * is better than that of the current process.
                    573:  */
1.1.1.4 ! root      574: void
1.1       root      575: setpri(p)
                    576:        register struct proc *p;
                    577: {
                    578:        register unsigned int newpri;
                    579: 
                    580:        newpri = PUSER + p->p_cpu / 4 + 2 * p->p_nice;
                    581:        newpri = min(newpri, MAXPRI);
                    582:        p->p_usrpri = newpri;
                    583:        if (newpri < curpri)
                    584:                need_resched();
                    585: }
1.1.1.2   root      586: 
1.1.1.4 ! root      587: #ifdef DDB
        !           588: void db_show_all_procs(long addr, int haddr, int count, char *modif)
        !           589: {
        !           590:     int np;
        !           591:     struct proc *ap, *p, *pp;
        !           592:     
        !           593:     np = nprocs;
        !           594:     p = ap = allproc;
        !           595:     if (modif[0] == 'm')
        !           596:         db_printf("  pid  proc    addr     map      comm         wchan\n");
        !           597:     else
        !           598:         db_printf("  pid  proc    addr     uid     ppid  pgrp   flag stat comm         wchan\n");
1.1.1.2   root      599:     while (--np >= 0) {
1.1.1.4 ! root      600:         pp = p->p_pptr;
        !           601:         if (pp == 0)
        !           602:            pp = p;
        !           603:         if (p->p_stat) {
        !           604:             if (modif[0] == 'm') {
        !           605:                 db_printf("%5d %06x %06x %06x %s   ",
        !           606:                           p->p_pid, ap, p->p_addr, p->p_vmspace, p->p_comm);
        !           607:             }
        !           608:             else {
        !           609:                 db_printf("%5d %06x %06x %3d %5d %5d  %06x  %d  %s   ",
        !           610:                           p->p_pid, ap, p->p_addr, p->p_cred->p_ruid,
        !           611:                           pp->p_pid, p->p_pgrp->pg_id, p->p_flag,
        !           612:                           p->p_stat, p->p_comm);
        !           613:             }
        !           614:             if (p->p_wchan) {
        !           615:                 if (p->p_wmesg)
        !           616:                     db_printf("%s ", p->p_wmesg);
        !           617:                 db_printf("%x", p->p_wchan);
1.1.1.2   root      618:            }
1.1.1.4 ! root      619:             db_printf("\n");
1.1.1.2   root      620:        }
1.1.1.4 ! root      621:         ap = p->p_nxt;
        !           622:         if (ap == 0 && np > 0)
        !           623:            ap = zombproc;
        !           624:         p = ap;
1.1.1.2   root      625:     }
                    626: }
                    627: #endif

unix.superglobalmegacorp.com

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