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

1.1     ! root        1: #include "sys/param.h"
        !             2: #include "sys/systm.h"
        !             3: #include "sys/meter.h"
        !             4: #include "sys/callout.h"
        !             5: #include "sys/user.h"
        !             6: #include "sys/proc.h"
        !             7: #include "sys/psl.h"
        !             8: #include "sys/vm.h"
        !             9: #include "sys/buf.h"
        !            10: #include "sys/text.h"
        !            11: #include "sys/vlimit.h"
        !            12: #include "sys/mtpr.h"
        !            13: #include "sys/clock.h"
        !            14: 
        !            15: int    queueflag;
        !            16: 
        !            17: /*
        !            18:  * trivial kernel profiling; quite expensive in space
        !            19:  */
        !            20: #define        KMAX    (200*1024)      /* max kernel text */
        !            21: #define        KPSIZE  (50*256)        /* number of buckets */
        !            22: #define        KPROF   1
        !            23: #if KPROF
        !            24: long kprof[KPSIZE];
        !            25: #endif
        !            26: 
        !            27: 
        !            28: /*
        !            29:  * Hardclock is called straight from
        !            30:  * the real time clock interrupt.
        !            31:  * We limit the work we do at real clock interrupt time to:
        !            32:  *     reloading clock
        !            33:  *     decrementing time to callouts
        !            34:  *     recording cpu time usage
        !            35:  *     modifying priority of current process
        !            36:  *     arrange for soft clock interrupt
        !            37:  *     kernel pc profiling
        !            38:  *
        !            39:  * At software (softclock) interrupt time we:
        !            40:  *     implement callouts
        !            41:  *     maintain date
        !            42:  *     lightning bolt wakeup (every second)
        !            43:  *     alarm clock signals
        !            44:  *     jab the scheduler
        !            45:  *
        !            46:  * On the vax softclock interrupts are implemented by
        !            47:  * software interrupts.  Note that we may have multiple softclock
        !            48:  * interrupts compressed into one (due to excessive interrupt load),
        !            49:  * but that hardclock interrupts should never be lost.
        !            50:  */
        !            51: /*ARGSUSED*/
        !            52: hardclock(pc, ps)
        !            53:        caddr_t pc;
        !            54: {
        !            55:        register struct callout *p1;
        !            56:        register struct proc *pp;
        !            57:        register int s, cpstate;
        !            58: 
        !            59:        /*
        !            60:         * reprime clock
        !            61:         */
        !            62:        clkreld();
        !            63: 
        !            64:        /*
        !            65:         * update callout times
        !            66:         */
        !            67:        for (p1 = calltodo.c_next; p1 && p1->c_time <= 0; p1 = p1->c_next)
        !            68:                ;
        !            69:        if (p1)
        !            70:                p1->c_time--;
        !            71:        pp = u.u_procp;
        !            72:        if (USERMODE(ps)) {
        !            73:                u.u_vm.vm_utime++;
        !            74:                if (pp->p_nice > NZERO)
        !            75:                        cpstate = CP_NICE;
        !            76:                else
        !            77:                        cpstate = CP_USER;
        !            78:                s = 1;
        !            79:        } else {
        !            80: #if KPROF
        !            81:                s = (long)pc - KSTART;
        !            82:                if (s < 0)
        !            83:                        s = 0;  /* shouldn't */
        !            84:                else if (s >= KMAX)
        !            85:                        s = KMAX - 1;
        !            86:                s /= KMAX/KPSIZE;
        !            87:                kprof[s]++;
        !            88: #endif
        !            89:                cpstate = CP_SYS;
        !            90:                if (queueflag) {
        !            91:                        cpstate = CP_QUEUE;
        !            92:                        s = 0;
        !            93:                } else if (noproc) {
        !            94:                        if (BASEPRI(ps) == 0)
        !            95:                                cpstate = CP_IDLE;
        !            96:                        s = 0;
        !            97:                } else {
        !            98:                        u.u_vm.vm_stime++;
        !            99:                        s = 1;
        !           100:                }
        !           101:        }
        !           102:        cp_time[cpstate]++;
        !           103:        /*
        !           104:         * Adjust priority of current process.
        !           105:         */
        !           106:        if (s) {
        !           107:                pp->p_cpticks++;
        !           108:                if(++pp->p_cpu == 0)
        !           109:                        --pp->p_cpu;
        !           110:        }
        !           111:        ++lbolt;
        !           112:        setsoftclock();
        !           113: }
        !           114: 
        !           115: #define cpuave(a,b) ((int)(((int)((a)*(b)))/((b)+1)))
        !           116: extern double avenrun[];
        !           117: /*
        !           118:  * Constant for decay filter for cpu usage field
        !           119:  * in process table (used by ps au).
        !           120:  */
        !           121: static float ccpu = 0.9512294245;              /* exp(-1/20) */
        !           122: 
        !           123: /*
        !           124:  * Software clock interrupt.
        !           125:  * This routine runs at lower priority than device interrupts.
        !           126:  *
        !           127:  * Processes have their (32-bit) priority depend on their owner's ``normalised
        !           128:  * usage'' of resources. However, V9's low-level scheduler only has 127 priorities,
        !           129:  * (in fact, only 32, so that someone could use an 'ffs' instruction),
        !           130:  * so we normalise this ``sharepri'' into the 7-bit ``usrpri''. Note that
        !           131:  * the 'ffs' hack means that (after PUSER) there are only 20 real priorities
        !           132:  * for processes to run in, and that defined kernel priorities should differ
        !           133:  * by more than 4 to be meaningful.
        !           134:  */
        !           135: /*ARGSUSED*/
        !           136: softclock(pc, ps)
        !           137:        caddr_t pc;
        !           138: {
        !           139:        register struct callout *p1;
        !           140:        register struct proc *pp;
        !           141:        register int a, s;
        !           142:        extern char *panicstr;
        !           143: 
        !           144:        /*
        !           145:         * Perform callouts (but not after panics)
        !           146:         */
        !           147:        if (panicstr == 0) {
        !           148:                for (;;) {
        !           149:                        register caddr_t arg;
        !           150:                        register int (*func)();
        !           151: 
        !           152:                        s = spl7();
        !           153:                        if ((p1 = calltodo.c_next) == 0 || p1->c_time > 0) {
        !           154:                                splx(s);
        !           155:                                break;
        !           156:                        }
        !           157:                        calltodo.c_next = p1->c_next;
        !           158:                        arg = p1->c_arg;
        !           159:                        func = p1->c_func;
        !           160:                        p1->c_next = callfree;
        !           161:                        callfree = p1;
        !           162:                        (void) splx(s);
        !           163:                        (*func)(arg);
        !           164:                }
        !           165:        }
        !           166: 
        !           167:        /*
        !           168:         * If idling and processes are waiting to swap in,
        !           169:         * check on them.
        !           170:         */
        !           171:        if (noproc && runin) {
        !           172:                runin = 0;
        !           173:                wakeup((caddr_t)&runin);
        !           174:        }
        !           175:        if (lbolt % (HZ/10) == 0) {
        !           176:                runrun++;
        !           177:                aston();
        !           178:        }
        !           179: 
        !           180:        /*
        !           181:         * Lightning bolt every second:
        !           182:         *      sleep timeouts
        !           183:         *      process priority recomputation
        !           184:         *      process %cpu averaging
        !           185:         *      p_time and p_slptime for the swapper
        !           186:         *      kick swapper if processes want in
        !           187:         */
        !           188:        if (lbolt >= HZ) {
        !           189:                /* meaningless on VAX; meant for hardclock */
        !           190:                if (BASEPRI(ps))
        !           191:                        return;
        !           192:                time += lbolt / HZ;
        !           193:                lbolt %= HZ;
        !           194:                wakeup((caddr_t)&lbolt);
        !           195:                for (pp = proc; pp < procNPROC; pp++)
        !           196:                if ((a=pp->p_stat)!=0 && a!=SZOMB) {
        !           197:                        if (pp->p_time != 127)
        !           198:                                pp->p_time++;
        !           199:                        if (pp->p_clktim && --pp->p_clktim == 0)
        !           200:                                psignal(pp, SIGALRM);
        !           201:                        if (pp->p_tsleep && --pp->p_tsleep == 0) {
        !           202:                                s = spl6();
        !           203:                                switch (pp->p_stat) {   /* != a if interrupted */
        !           204: 
        !           205:                                case SSLEEP:
        !           206:                                        setrun(pp);
        !           207:                                        break;
        !           208: 
        !           209:                                case SSTOP:
        !           210:                                        unsleep(pp);
        !           211:                                        break;
        !           212:                                }
        !           213:                                pp->p_flag |= STIMO;
        !           214:                                splx(s);
        !           215:                        }
        !           216:                        if (a==SSLEEP || a==SSTOP)
        !           217:                                if (pp->p_slptime != 127)
        !           218:                                        pp->p_slptime++;
        !           219:                        /*
        !           220:                         * update silly numbers for ps to print
        !           221:                         */
        !           222:                        if (pp->p_flag&SLOAD)
        !           223:                                pp->p_pctcpu = ccpu*pp->p_pctcpu +
        !           224:                                    (1.0 - ccpu) * (pp->p_cpticks/(float)HZ);
        !           225:                        pp->p_cpticks = 0;
        !           226: 
        !           227:                        /*
        !           228:                         * Update p_cpu for scheduling
        !           229:                         */
        !           230:                        a = cpuave(pp->p_cpu, 2*avenrun[0]);
        !           231:                        if (a < 0)
        !           232:                                a = 0;
        !           233:                        if (a > 255)
        !           234:                                a = 255;
        !           235:                        pp->p_cpu = a;
        !           236:                        (void) setpri(pp);
        !           237:                        /*
        !           238:                         * p_usrpri == new process priority
        !           239:                         * now fix p_pri to match, carefully
        !           240:                         */
        !           241:                        s = spl6();
        !           242:                        if (pp->p_pri >= PUSER && pp->p_pri != pp->p_usrpri) {
        !           243:                                if ((pp != u.u_procp || noproc) && pp->p_stat == SRUN &&
        !           244:                                    (pp->p_flag & SLOAD)) {
        !           245:                                        remrq(pp);
        !           246:                                        pp->p_pri = pp->p_usrpri;
        !           247:                                        setrq(pp);
        !           248:                                } else
        !           249:                                        pp->p_pri = pp->p_usrpri;
        !           250:                        }
        !           251:                        splx(s);
        !           252:                }
        !           253:                if (runin!=0) {
        !           254:                        runin = 0;
        !           255:                        wakeup((caddr_t)&runin);
        !           256:                }
        !           257:        }
        !           258:        if (noproc)
        !           259:                return;
        !           260:        pp = u.u_procp;
        !           261:        /*
        !           262:         * If trapped user-mode, give it a profiling tick.
        !           263:         */
        !           264:        if (USERMODE(ps) && u.u_prof.pr_scale) {
        !           265:                pp->p_flag |= SOWEUPC;
        !           266:                aston();
        !           267:        }
        !           268:        /*
        !           269:         * random statistics, apparently computed just so
        !           270:         * that programs like ps can print them?  not a good reason
        !           271:         */
        !           272:        s = pp->p_rssize;
        !           273:        u.u_vm.vm_idsrss += s;
        !           274:        if (pp->p_textp) {
        !           275:                a = pp->p_textp->x_rssize;
        !           276:                s += a;
        !           277:                u.u_vm.vm_ixrss += a;
        !           278:        }
        !           279:        if (s > u.u_vm.vm_maxrss)
        !           280:                u.u_vm.vm_maxrss = s;
        !           281:        /*
        !           282:         * cpu time limit
        !           283:         */
        !           284:        if ((u.u_vm.vm_utime+u.u_vm.vm_stime+1)/HZ > u.u_limit[LIM_CPU]) {
        !           285:                psignal(pp, SIGXCPU);
        !           286:                if (u.u_limit[LIM_CPU] < INFINITY - 5)
        !           287:                        u.u_limit[LIM_CPU] += 5;
        !           288:        }
        !           289: }
        !           290: 
        !           291: /*
        !           292:  * Timeout is called to arrange that
        !           293:  * fun(arg) is called in tim/HZ seconds.
        !           294:  * An entry is linked into the callout
        !           295:  * structure.  The time in each structure
        !           296:  * entry is the number of HZ's more
        !           297:  * than the previous entry.
        !           298:  * In this way, decrementing the
        !           299:  * first entry has the effect of
        !           300:  * updating all entries.
        !           301:  *
        !           302:  * The panic is there because there is nothing
        !           303:  * intelligent to be done if an entry won't fit.
        !           304:  */
        !           305: timeout(fun, arg, tim)
        !           306:        int (*fun)();
        !           307:        caddr_t arg;
        !           308: {
        !           309:        register struct callout *p1, *p2, *pnew;
        !           310:        register int t;
        !           311:        int s;
        !           312: 
        !           313:        t = tim;
        !           314:        s = spl7();
        !           315:        pnew = callfree;
        !           316:        if (pnew == NULL)
        !           317:                panic("timeout table overflow");
        !           318:        callfree = pnew->c_next;
        !           319:        pnew->c_arg = arg;
        !           320:        pnew->c_func = fun;
        !           321:        for (p1 = &calltodo; (p2 = p1->c_next) && p2->c_time < t; p1 = p2)
        !           322:                t -= p2->c_time;
        !           323:        p1->c_next = pnew;
        !           324:        pnew->c_next = p2;
        !           325:        pnew->c_time = t;
        !           326:        if (p2)
        !           327:                p2->c_time -= t;
        !           328:        splx(s);
        !           329: }
        !           330: 
        !           331: /*
        !           332:  *      Delay goes to sleep on a unique address for a
        !           333:  *      guaranteed minimum period ticks/HZ secs.
        !           334:  *      Because a timeout() can't be cancelled, the process
        !           335:  *      will be unkillable while asleep.  Beware of giving
        !           336:  *      delay() an argument of more than a few hundred.
        !           337:  *
        !           338:  * used by one device driver and by sys nap.
        !           339:  * do we really need it?
        !           340:  */
        !           341: delay(ticks)
        !           342: {
        !           343:         register int    x;
        !           344:         extern wakeup();
        !           345: 
        !           346:         if (ticks<=0)
        !           347:                 return;
        !           348:         x = spl7();
        !           349:         timeout(wakeup, (caddr_t)u.u_procp+1, ticks);
        !           350:         sleep((caddr_t)u.u_procp+1, PZERO-1);
        !           351:         splx(x);
        !           352: }
        !           353: 
        !           354: /*
        !           355:  * init callouts
        !           356:  * called from main
        !           357:  */
        !           358: 
        !           359: callinit()
        !           360: {
        !           361:        register int i;
        !           362: 
        !           363:        callfree = callout;
        !           364:        for (i = 1; i < calloutcnt; i++)
        !           365:                callout[i-1].c_next = &callout[i];
        !           366: }

unix.superglobalmegacorp.com

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