Annotation of coherent/d/PS2_KERNEL/coh.386/clock.c, revision 1.1

1.1     ! root        1: /* $Header: /y/coh.386/RCS/clock.c,v 1.6 92/07/16 16:33:29 hal Exp $ */
        !             2: /* (lgl-
        !             3:  *     The information contained herein is a trade secret of Mark Williams
        !             4:  *     Company, and  is confidential information.  It is provided  under a
        !             5:  *     license agreement,  and may be  copied or disclosed  only under the
        !             6:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !             7:  *     material without the express written authorization of Mark Williams
        !             8:  *     Company or persuant to the license agreement is unlawful.
        !             9:  *
        !            10:  *     COHERENT Version 2.3.37
        !            11:  *     Copyright (c) 1982, 1983, 1984.
        !            12:  *     An unpublished work by Mark Williams Company, Chicago.
        !            13:  *     All rights reserved.
        !            14:  -lgl) */
        !            15: /*
        !            16:  * Coherent.
        !            17:  * Clock.
        !            18:  * The clock comes in two parts.  There is the routine `clock' which
        !            19:  * gets called every tick at high priority.  It does the minimum it
        !            20:  * can and returns as soon as possible.  The second routine, `stand',
        !            21:  * gets called whenever we are about to return from an interrupt to
        !            22:  * user mode a low priority.  It can look at flags that the clock set
        !            23:  * and do the things the clock really wanted to do but didn't have time.
        !            24:  * Stand is truly the kernel of the system.
        !            25:  *
        !            26:  * 90/08/13    Hal Snyder              /usr/src/sys/coh/clock.c
        !            27:  * Add external altclk to allow polled device drivers.
        !            28:  * (extern'ed in coherent.h)
        !            29:  * 
        !            30:  * 87/10/26    Allan cornish           /usr/src/sys/coh/clock.c
        !            31:  * Timed functions are now invoked with TIM * tp as second argument.
        !            32:  * This facilitates the use of timed functions within loadable drivers.
        !            33:  *
        !            34:  * 87/07/07    Allan Cornish           /usr/src/sys/coh/clock.c
        !            35:  * Clocks static variable added - incremented by clock, decremented by stand().
        !            36:  * Lbolt variable added - clock ticks since startup - incremented by stand().
        !            37:  * Support for multiple timing queues ported from RTX.
        !            38:  *
        !            39:  * 87/01/05    Allan Cornish           /usr/src/sys/coh/clock.c
        !            40:  * stand() now only wakes &stimer if swap timer is active.
        !            41:  *
        !            42:  * 86/11/24    Allan Cornish           /usr/src/sys/coh/clock.c
        !            43:  * Added support for new t_last field in tim struct.
        !            44:  *
        !            45:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/clock.c
        !            46:  * Stand() calls defend() to execute functions deferred from interrupt level.
        !            47:  */
        !            48: #include <sys/coherent.h>
        !            49: #include <sys/con.h>
        !            50: #include <sys/proc.h>
        !            51: #include <sys/sched.h>
        !            52: #include <sys/stat.h>
        !            53: #include <sys/timeout.h>
        !            54: #include <sys/mdata.h>
        !            55: 
        !            56: int (*altclk)();       /* pointer to higher-speed clock function */
        !            57: 
        !            58: #ifndef _I386
        !            59: int altsel;    /* if nonzero, CS for LOADABLE driver owning altclk() */
        !            60: #endif
        !            61: 
        !            62: static int clocks;
        !            63: 
        !            64: /*
        !            65:  * This routine is called once every tick (1/HZ seconds).
        !            66:  * It gets called with the program counter that was interrupted
        !            67:  * a flag telling whether we were in user or kernel mode and the
        !            68:  * previous priority we were in.
        !            69:  */
        !            70: clock(pc, umode)
        !            71: vaddr_t pc;
        !            72: {
        !            73:        register PROC *pp;
        !            74: 
        !            75:        /*
        !            76:         * Ignore clock interrupts till we are ready.
        !            77:         */
        !            78:        if (batflag == 0)
        !            79:                return;
        !            80: 
        !            81:        /*
        !            82:         * Hook for alternate clock interrupt;
        !            83:         * Call polling function ("altclk") if there is one.
        !            84:         *
        !            85:         * For near function, "altsel" is 0 and "altclk" is offset.
        !            86:         * For far function, "altsel" is the CS selector and "altclk"
        !            87:         * is the offset.
        !            88:         *
        !            89:         * Since the polling function ends with a near rather than
        !            90:         * far return, far invocation is via ld_call() (ldas.s) which uses
        !            91:         * the despatch routine at CS:4 (ld.s) in any loadable driver.
        !            92:         */
        !            93:        if (altclk) {
        !            94: #ifndef _I386
        !            95:                if (altsel) {   /* will do far call to altclk fn */
        !            96:                        if (ld_call(altsel, altclk))
        !            97:                                return;
        !            98:                } else
        !            99: #endif
        !           100:                        if ((*altclk)())
        !           101:                                return;
        !           102:        }
        !           103: 
        !           104:        /*
        !           105:         * Update timers.  Decrement time slice.
        !           106:         */
        !           107:        utimer += 1;
        !           108:        clocks += 1;
        !           109:        timer.t_tick += 1;
        !           110:        quantum -= 1;
        !           111: 
        !           112:        /*
        !           113:         * Give processes their schedule values per tick.
        !           114:         */
        !           115:        if (procq.p_lforw->p_cval > CVCLOCK) {
        !           116:                procq.p_lforw->p_cval -= CVCLOCK;
        !           117:                procq.p_cval += CVCLOCK;
        !           118:        }
        !           119: 
        !           120:        /*
        !           121:         * Tax current process and update his times.
        !           122:         */
        !           123:        pp = SELF;
        !           124:        pp->p_cval >>= 1;
        !           125:        if (umode) {
        !           126:                pp->p_utime++;
        !           127:                u.u_ppc = pc;
        !           128:        } else
        !           129:                pp->p_stime++;
        !           130: }
        !           131: 
        !           132: /*
        !           133:  * stand()
        !           134:  *
        !           135:  * Called when there is an interrupt or trap.
        !           136:  */
        !           137: 
        !           138: stand()
        !           139: {
        !           140:        int s;
        !           141: 
        !           142: #ifdef TIMING
        !           143:        /*
        !           144:         * Every 500th call to stand(), dump logged intervals.
        !           145:         *
        !           146:         * Log a group of events doing
        !           147:         *      LOGIN(label);
        !           148:         *      ...
        !           149:         *      LOGOUT();
        !           150:         *
        !           151:         * If you want to group several selected events in one total,
        !           152:         * do LOGPAUSE() to halt between events and LOGRESUME() to
        !           153:         * add in the time for another event.  Event count is displayed.
        !           154:         * For example:
        !           155:         *      LOGIN(label);
        !           156:         *      while (...) {
        !           157:         *              LOGPAUSE();
        !           158:         *              ... stuff you don't want timed...
        !           159:         *              LOGRESUME();
        !           160:         *              ... stuff you want timed...
        !           161:         *      }
        !           162:         *      LOGOUT();
        !           163:         *
        !           164:         * Display is for the 3 longest intervals seen in latest logging
        !           165:         * period.
        !           166:         *
        !           167:         * Timing between in & out is displayed with ~1 usec resolution.
        !           168:         * Overhead per event is ~20 usec.
        !           169:         */
        !           170:        static int call_ct; /* DEBUG */
        !           171: 
        !           172:        call_ct++;
        !           173:        if (call_ct >= 500) {
        !           174:                call_ct = 0;
        !           175:                LOGLIST();
        !           176:        }
        !           177: #endif
        !           178: 
        !           179: 
        !           180:        u.u_error = 0;
        !           181: 
        !           182:        /*
        !           183:         * Update the clock.
        !           184:         */
        !           185:        while (timer.t_tick >= HZ) {
        !           186:                timer.t_time++;
        !           187:                timer.t_tick -= HZ;
        !           188:                outflag = 1;
        !           189:        }
        !           190: 
        !           191:        /*
        !           192:         * Check expiration of quantum.
        !           193:         */
        !           194:        if (quantum <= 0) {
        !           195:                quantum = 0;
        !           196:                disflag = 1;
        !           197:        }
        !           198: 
        !           199:        /*
        !           200:         * Check the timed function queue if necessary.
        !           201:         */
        !           202:        if (clocks > 0)
        !           203:        do {
        !           204:                register TIM * np;
        !           205:                register TIM * tp;
        !           206: 
        !           207:                /*
        !           208:                 * Update [serviced] clock ticks since startup.
        !           209:                 */
        !           210:                lbolt++;
        !           211:                clocks--;
        !           212: 
        !           213:                /*
        !           214:                 * Remove timing list from queue, creating new temporary queue.
        !           215:                 */
        !           216:                tp = (TIM *) &timq[ lbolt % nel(timq) ];
        !           217:                s  = sphi();
        !           218: 
        !           219:                /*
        !           220:                 * Scan timing list.
        !           221:                 */
        !           222:                for (np = tp->t_next; tp = np;) {
        !           223: 
        !           224:                        /*
        !           225:                         * Remember next function in timing list.
        !           226:                         * NOTE: Must be done before function is invoked,
        !           227:                         *       since it may start a new timer.
        !           228:                         */
        !           229:                        np = tp->t_next;
        !           230: 
        !           231:                        /*
        !           232:                         * Function has not timed out: leave it on timing list.
        !           233:                         */
        !           234:                        if (tp->t_lbolt != lbolt)
        !           235:                                continue;
        !           236: 
        !           237:                        /*
        !           238:                         * Remove function from timing list.
        !           239:                         */
        !           240:                        if (tp->t_last->t_next = tp->t_next)
        !           241:                                tp->t_next->t_last = tp->t_last;
        !           242:                        tp->t_last = NULL;
        !           243: 
        !           244:                        /*
        !           245:                         * Invoke function.
        !           246:                         */
        !           247:                        spl(s);
        !           248:                        (*tp->t_func)(tp->t_farg, tp);
        !           249:                        sphi();
        !           250:                }
        !           251: 
        !           252:                spl(s);
        !           253: 
        !           254:        } while (clocks);
        !           255: 
        !           256:        /*
        !           257:         * Timeout any devices.
        !           258:         */
        !           259:        if (outflag) {
        !           260:                register int n;
        !           261: 
        !           262:                outflag = 0;
        !           263:                for (n=0; n<drvn; n++) {
        !           264:                        if (drvl[n].d_time == 0)
        !           265:                                continue;
        !           266:                        s = sphi();
        !           267:                        dtime((dev_t)makedev(n, 0));
        !           268:                        spl(s);
        !           269:                }
        !           270:        }
        !           271: 
        !           272:        /*
        !           273:         * Do profiling.
        !           274:         */
        !           275: #ifdef _I386   /* profiling */
        !           276:        if (u.u_pscale & ~1) {  /* if scale is not zero or one */
        !           277:                /*
        !           278:                 * Treat u.u_pscale as fixed-point fraction 0xXXXX.YYYY.
        !           279:                 * Increment the (short) profiling entry at
        !           280:                 *      base + (pc - offset) * scale
        !           281:                 */
        !           282:                register vaddr_t a;
        !           283: 
        !           284:                a = (u.u_pbase + pscale(u.u_ppc-u.u_pofft, u.u_pscale)) & ~1;
        !           285:                if (a < u.u_pbend)
        !           286:                        putusd(a, getusd(a)+1);
        !           287:        }
        !           288: #else          /* profiling */
        !           289:        if (u.u_pscale) {
        !           290:                register unsigned p;
        !           291:                register vaddr_t a;
        !           292: 
        !           293:                p = u.u_pscale;
        !           294:                a = (int *)u.u_pbase +
        !           295:                    pscale((int)(u.u_ppc-u.u_pofft), p/sizeof (int));
        !           296:                if (a < u.u_pbend)
        !           297:                        putuwd(a, getuwd(a)+1);
        !           298:        }
        !           299: #endif         /* profiling */
        !           300: 
        !           301:        /*
        !           302:         * Check for signals and execute them.
        !           303:         */
        !           304:        if (SELF->p_ssig) {
        !           305:                actvsig();
        !           306:        }
        !           307: 
        !           308:        /*
        !           309:         * Execute deferred functions.
        !           310:         */
        !           311:        defend();
        !           312: 
        !           313:        /*
        !           314:         * Should we dispatch?
        !           315:         */
        !           316:        if ((SELF->p_flags&PFDISP) != 0) {
        !           317:                SELF->p_flags &= ~PFDISP;
        !           318:                disflag = 1;
        !           319:                if (stimer.t_last != 0)
        !           320:                        wakeup((char *)&stimer);
        !           321:        }
        !           322: 
        !           323:        /*
        !           324:         * Redispatch.
        !           325:         */
        !           326:        if (disflag) {
        !           327:                register PROC *pp;
        !           328: 
        !           329:                s=sphi();
        !           330:                if ((pp=SELF)!=iprocp)
        !           331:                        setrun(pp);
        !           332:                dispatch();
        !           333:                spl(s);
        !           334:        }
        !           335: stand_done:
        !           336:        return;
        !           337: }
        !           338: 
        !           339: #ifdef TIMING
        !           340: 
        !           341: #define EIMAX 3
        !           342: 
        !           343: static int label, b_in, t_in;
        !           344: static int b_pause, t_pause, e_pause, paused, timing;
        !           345: 
        !           346: struct H_event {
        !           347:        int f; /* timing label */
        !           348:        int b; /* delta ticks */
        !           349:        int t; /* delta timer */
        !           350:        int e; /* event count */
        !           351: } Ltab[EIMAX];
        !           352: 
        !           353: LOGIN(lab)
        !           354: {
        !           355:        paused = 0;
        !           356:        b_pause = t_pause = 0;
        !           357:        e_pause = 1;
        !           358:        label = lab;
        !           359:        b_in = clocks + lbolt;
        !           360:        t_in = read_t0();
        !           361:        timing = 1;
        !           362: }
        !           363: 
        !           364: LOGOUT()
        !           365: {
        !           366:        int i;
        !           367: 
        !           368:        if (!timing)
        !           369:                return;
        !           370:        if (!paused) {
        !           371:                b_pause += clocks + lbolt - b_in;
        !           372:                t_pause += (t_in - read_t0());
        !           373:                if (t_pause < 0)
        !           374:                        t_pause += 11932;
        !           375:        }
        !           376:        for (i = 0; i < EIMAX; i++) {
        !           377:                if (b_pause > Ltab[i].b) {
        !           378:                        Ltab[i].b = b_pause;
        !           379:                        Ltab[i].t = t_pause;
        !           380:                        Ltab[i].f = label;
        !           381:                        Ltab[i].e = e_pause;
        !           382:                        break;
        !           383:                } else if (b_pause == Ltab[i].b) {
        !           384:                        if (t_pause > Ltab[i].t) {
        !           385:                                Ltab[i].t = t_pause;
        !           386:                                Ltab[i].f = label;
        !           387:                                Ltab[i].e = e_pause;
        !           388:                                break;
        !           389:                        } else if (t_pause == Ltab[i].t) {
        !           390:                                break;
        !           391:                        }
        !           392:                }
        !           393:        }
        !           394:        timing = 0;
        !           395: }
        !           396: 
        !           397: LOGLIST()
        !           398: {
        !           399:        int i, printed = 0;
        !           400: 
        !           401:        for (i = 0; i < EIMAX; i++)
        !           402:                if (Ltab[i].t || Ltab[i].b) {
        !           403:                        if (printed == 0) {
        !           404:                                printf("\npsw=%x ", read_psw());
        !           405:                                printed = 1;
        !           406:                        }
        !           407:                        printf("f=%x b=%d t=%d e=%d  ",
        !           408:                          Ltab[i].f, Ltab[i].b, Ltab[i].t, Ltab[i].e);
        !           409:                        Ltab[i].f = Ltab[i].b = Ltab[i].t = 0;
        !           410:                } else
        !           411:                        break;
        !           412: }
        !           413: 
        !           414: LOGPAUSE()
        !           415: {
        !           416:        if (!timing)
        !           417:                return;
        !           418:        if (!paused) {
        !           419:                b_pause += clocks + lbolt - b_in;
        !           420:                t_pause += (t_in - read_t0());
        !           421:                if (t_pause < 0)
        !           422:                        t_pause += 11932;
        !           423:                paused = 1;
        !           424:        }
        !           425: }
        !           426: 
        !           427: LOGRESUME()
        !           428: {
        !           429:        if (!timing)
        !           430:                return;
        !           431:        if (paused) {
        !           432:                b_in = clocks + lbolt;
        !           433:                t_in = read_t0();
        !           434:                paused = 0;
        !           435:                e_pause++;
        !           436:        }
        !           437: }
        !           438: #endif

unix.superglobalmegacorp.com

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