Annotation of coherent/b/kernel/coh.386/clock.c, revision 1.1

1.1     ! root        1: /* $Header: /y/coh.386/RCS/clock.c,v 1.9 93/04/14 10:06:19 root 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 5.0
        !            11:  *     Copyright (c) 1982, 1993.
        !            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: 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:  * and the CPL of the interrupted code (0..3).
        !            68:  */
        !            69: clock(pc, umode)
        !            70: caddr_t pc;
        !            71: {
        !            72:        register PROC *pp;
        !            73: 
        !            74:        /*
        !            75:         * Ignore clock interrupts till we are ready.
        !            76:         */
        !            77:        if (batflag == 0)
        !            78:                return;
        !            79: 
        !            80:        /*
        !            81:         * Hook for alternate clock interrupt;
        !            82:         * Call polling function ("altclk") if there is one.
        !            83:         *
        !            84:         * For near function, "altsel" is 0 and "altclk" is offset.
        !            85:         * For far function, "altsel" is the CS selector and "altclk"
        !            86:         * is the offset.
        !            87:         *
        !            88:         * Since the polling function ends with a near rather than
        !            89:         * far return, far invocation is via ld_call() (ldas.s) which uses
        !            90:         * the despatch routine at CS:4 (ld.s) in any loadable driver.
        !            91:         */
        !            92:        if (altclk) {
        !            93: #ifndef _I386
        !            94:                if (altsel) {   /* will do far call to altclk fn */
        !            95:                        if (ld_call(altsel, altclk))
        !            96:                                return;
        !            97:                } else
        !            98: #endif
        !            99:                        if ((*altclk)())
        !           100:                                return;
        !           101:        }
        !           102: 
        !           103:        /*
        !           104:         * Update timers.  Decrement time slice.
        !           105:         */
        !           106:        utimer += 1;
        !           107:        clocks += 1;
        !           108:        timer.t_tick += 1;
        !           109:        quantum -= 1;
        !           110: 
        !           111: #ifndef _I386
        !           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: #endif
        !           120: 
        !           121:        /*
        !           122:         * Tax current process and update his times.
        !           123:         */
        !           124:        pp = SELF;
        !           125: #ifndef _I386
        !           126:        pp->p_cval >>= 1;
        !           127: #endif
        !           128:        if (umode == R_USR) {
        !           129:                pp->p_utime++;
        !           130:                u.u_ppc = pc;
        !           131:        } else
        !           132:                pp->p_stime++;
        !           133: }
        !           134: 
        !           135: /*
        !           136:  * stand()
        !           137:  *
        !           138:  * Called when there is an interrupt or trap.
        !           139:  */
        !           140: stand()
        !           141: {
        !           142:        int s;
        !           143: 
        !           144: #ifdef TIMING
        !           145:        /*
        !           146:         * Every 500th call to stand(), dump logged intervals.
        !           147:         *
        !           148:         * Log a group of events doing
        !           149:         *      LOGIN(label);
        !           150:         *      ...
        !           151:         *      LOGOUT();
        !           152:         *
        !           153:         * If you want to group several selected events in one total,
        !           154:         * do LOGPAUSE() to halt between events and LOGRESUME() to
        !           155:         * add in the time for another event.  Event count is displayed.
        !           156:         * For example:
        !           157:         *      LOGIN(label);
        !           158:         *      while (...) {
        !           159:         *              LOGPAUSE();
        !           160:         *              ... stuff you don't want timed...
        !           161:         *              LOGRESUME();
        !           162:         *              ... stuff you want timed...
        !           163:         *      }
        !           164:         *      LOGOUT();
        !           165:         *
        !           166:         * Display is for the 3 longest intervals seen in latest logging
        !           167:         * period.
        !           168:         *
        !           169:         * Timing between in & out is displayed with ~1 usec resolution.
        !           170:         * Overhead per event is ~20 usec.
        !           171:         */
        !           172:        static int call_ct; /* DEBUG */
        !           173: 
        !           174:        call_ct++;
        !           175:        if (call_ct >= 500) {
        !           176:                call_ct = 0;
        !           177:                LOGLIST();
        !           178:        }
        !           179: #endif
        !           180: 
        !           181:        u.u_error = 0;
        !           182: 
        !           183:        /*
        !           184:         * Update the clock.
        !           185:         */
        !           186:        while (timer.t_tick >= HZ) {
        !           187:                timer.t_time++;
        !           188:                timer.t_tick -= HZ;
        !           189:                outflag = 1;
        !           190:        }
        !           191: 
        !           192:        /*
        !           193:         * Check expiration of quantum.
        !           194:         */
        !           195:        if (quantum <= 0) {
        !           196:                quantum = 0;
        !           197:                disflag = 1;
        !           198:        }
        !           199: 
        !           200:        /*
        !           201:         * Check the timed function queue if necessary.
        !           202:         */
        !           203:        if (clocks > 0)
        !           204:        do {
        !           205:                register TIM * np;
        !           206:                register TIM * tp;
        !           207: 
        !           208:                /*
        !           209:                 * Update [serviced] clock ticks since startup.
        !           210:                 */
        !           211:                lbolt++;
        !           212:                clocks--;
        !           213: 
        !           214:                /*
        !           215:                 * Remove timing list from queue, creating new temporary queue.
        !           216:                 */
        !           217:                tp = (TIM *) &timq[ lbolt % nel(timq) ];
        !           218:                s  = sphi();
        !           219: 
        !           220:                /*
        !           221:                 * Scan timing list.
        !           222:                 */
        !           223:                for (np = tp->t_next; tp = np;) {
        !           224: 
        !           225:                        /*
        !           226:                         * Remember next function in timing list.
        !           227:                         * NOTE: Must be done before function is invoked,
        !           228:                         *       since it may start a new timer.
        !           229:                         */
        !           230:                        np = tp->t_next;
        !           231: 
        !           232:                        /*
        !           233:                         * Function has not timed out: leave it on timing list.
        !           234:                         */
        !           235:                        if (tp->t_lbolt != lbolt)
        !           236:                                continue;
        !           237: 
        !           238:                        /*
        !           239:                         * Remove function from timing list.
        !           240:                         */
        !           241:                        if (tp->t_last->t_next = tp->t_next)
        !           242:                                tp->t_next->t_last = tp->t_last;
        !           243:                        tp->t_last = NULL;
        !           244: 
        !           245:                        /*
        !           246:                         * Invoke function.
        !           247:                         */
        !           248:                        spl(s);
        !           249:                        (*tp->t_func)(tp->t_farg, tp);
        !           250:                        sphi();
        !           251:                }
        !           252: 
        !           253:                spl(s);
        !           254: 
        !           255:                STREAMS_TIMEOUT ();
        !           256: 
        !           257:        } while (clocks);
        !           258: 
        !           259:        /*
        !           260:         * Timeout any devices.
        !           261:         */
        !           262:        if (outflag) {
        !           263:                register int n;
        !           264: 
        !           265:                outflag = 0;
        !           266:                for (n=0; n<drvn; n++) {
        !           267:                        if (drvl[n].d_time == 0)
        !           268:                                continue;
        !           269:                        s = sphi();
        !           270:                        dtime((dev_t)makedev(n, 0));
        !           271:                        spl(s);
        !           272:                }
        !           273:        }
        !           274: 
        !           275:        /*
        !           276:         * Do profiling.
        !           277:         */
        !           278: #ifdef _I386   /* profiling */
        !           279:        if (u.u_pscale & ~1) {  /* if scale is not zero or one */
        !           280:                /*
        !           281:                 * Treat u.u_pscale as fixed-point fraction 0xXXXX.YYYY.
        !           282:                 * Increment the (short) profiling entry at
        !           283:                 *      base + (pc - offset) * scale
        !           284:                 */
        !           285:                register caddr_t a;
        !           286: 
        !           287:                a = (caddr_t) ((long) (u.u_pbase + pscale(u.u_ppc-u.u_pofft,
        !           288:                                                          u.u_pscale)) & ~1);
        !           289:                if (a < u.u_pbend)
        !           290:                        putusd(a, getusd(a)+1);
        !           291:        }
        !           292: #else          /* profiling */
        !           293:        if (u.u_pscale) {
        !           294:                register unsigned p;
        !           295:                register caddr_t a;
        !           296: 
        !           297:                p = u.u_pscale;
        !           298:                a = (int *)u.u_pbase +
        !           299:                    pscale((int)(u.u_ppc-u.u_pofft), p/sizeof (int));
        !           300:                if (a < u.u_pbend)
        !           301:                        putuwd(a, getuwd(a)+1);
        !           302:        }
        !           303: #endif         /* profiling */
        !           304: 
        !           305:        /*
        !           306:         * Check for signals and execute them.
        !           307:         */
        !           308:        if (SELF->p_ssig) {
        !           309:                actvsig();
        !           310:        }
        !           311: 
        !           312:        /*
        !           313:         * Execute deferred functions.
        !           314:         */
        !           315:        defend();
        !           316: 
        !           317:        /*
        !           318:         * Should we dispatch?
        !           319:         */
        !           320:        if ((SELF->p_flags&PFDISP) != 0) {
        !           321:                SELF->p_flags &= ~PFDISP;
        !           322:                disflag = 1;
        !           323:                if (stimer.t_last != 0)
        !           324:                        wakeup((char *)&stimer);
        !           325:        }
        !           326: 
        !           327:        /*
        !           328:         * Redispatch.
        !           329:         */
        !           330:        if (disflag) {
        !           331:                register PROC *pp;
        !           332: 
        !           333:                s=sphi();
        !           334:                if ((pp=SELF)!=iprocp)
        !           335:                        setrun(pp);
        !           336:                dispatch();
        !           337:                spl(s);
        !           338:        }
        !           339: 
        !           340:        STREAMS_SCHEDULER ();
        !           341: 
        !           342:        return;
        !           343: }
        !           344: 
        !           345: #ifdef TIMING
        !           346: 
        !           347: #define EIMAX 3
        !           348: 
        !           349: static int label, b_in, t_in;
        !           350: static int b_pause, t_pause, e_pause, paused, timing;
        !           351: 
        !           352: struct H_event {
        !           353:        int f; /* timing label */
        !           354:        int b; /* delta ticks */
        !           355:        int t; /* delta timer */
        !           356:        int e; /* event count */
        !           357: } Ltab[EIMAX];
        !           358: 
        !           359: LOGIN(lab)
        !           360: {
        !           361:        paused = 0;
        !           362:        b_pause = t_pause = 0;
        !           363:        e_pause = 1;
        !           364:        label = lab;
        !           365:        b_in = clocks + lbolt;
        !           366:        t_in = read_t0();
        !           367:        timing = 1;
        !           368: }
        !           369: 
        !           370: LOGOUT()
        !           371: {
        !           372:        int i;
        !           373: 
        !           374:        if (!timing)
        !           375:                return;
        !           376:        if (!paused) {
        !           377:                b_pause += clocks + lbolt - b_in;
        !           378:                t_pause += (t_in - read_t0());
        !           379:                if (t_pause < 0)
        !           380:                        t_pause += 11932;
        !           381:        }
        !           382:        for (i = 0; i < EIMAX; i++) {
        !           383:                if (b_pause > Ltab[i].b) {
        !           384:                        Ltab[i].b = b_pause;
        !           385:                        Ltab[i].t = t_pause;
        !           386:                        Ltab[i].f = label;
        !           387:                        Ltab[i].e = e_pause;
        !           388:                        break;
        !           389:                } else if (b_pause == Ltab[i].b) {
        !           390:                        if (t_pause > Ltab[i].t) {
        !           391:                                Ltab[i].t = t_pause;
        !           392:                                Ltab[i].f = label;
        !           393:                                Ltab[i].e = e_pause;
        !           394:                                break;
        !           395:                        } else if (t_pause == Ltab[i].t) {
        !           396:                                break;
        !           397:                        }
        !           398:                }
        !           399:        }
        !           400:        timing = 0;
        !           401: }
        !           402: 
        !           403: LOGLIST()
        !           404: {
        !           405:        int i, printed = 0;
        !           406: 
        !           407:        for (i = 0; i < EIMAX; i++)
        !           408:                if (Ltab[i].t || Ltab[i].b) {
        !           409:                        if (printed == 0) {
        !           410:                                printf("\npsw=%x ", read_psw());
        !           411:                                printed = 1;
        !           412:                        }
        !           413:                        printf("f=%x b=%d t=%d e=%d  ",
        !           414:                          Ltab[i].f, Ltab[i].b, Ltab[i].t, Ltab[i].e);
        !           415:                        Ltab[i].f = Ltab[i].b = Ltab[i].t = 0;
        !           416:                } else
        !           417:                        break;
        !           418: }
        !           419: 
        !           420: LOGPAUSE()
        !           421: {
        !           422:        if (!timing)
        !           423:                return;
        !           424:        if (!paused) {
        !           425:                b_pause += clocks + lbolt - b_in;
        !           426:                t_pause += (t_in - read_t0());
        !           427:                if (t_pause < 0)
        !           428:                        t_pause += 11932;
        !           429:                paused = 1;
        !           430:        }
        !           431: }
        !           432: 
        !           433: LOGRESUME()
        !           434: {
        !           435:        if (!timing)
        !           436:                return;
        !           437:        if (paused) {
        !           438:                b_in = clocks + lbolt;
        !           439:                t_in = read_t0();
        !           440:                paused = 0;
        !           441:                e_pause++;
        !           442:        }
        !           443: }
        !           444: #endif

unix.superglobalmegacorp.com

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