Annotation of coherent/d/286_KERNEL/USRSRC/coh/clock.c, revision 1.1

1.1     ! root        1: /* $Header: /x/usr/src/sys/coh/RCS/clock.c,v 1.2 91/06/20 14:12:44 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/uproc.h>
        !            55: #include <sys/mdata.h>
        !            56: 
        !            57: int (*altclk)();       /* pointer to higher-speed clock function */
        !            58: int altsel;    /* if nonzero, CS for LOADABLE driver owning altclk() */
        !            59: 
        !            60: static int clocks;
        !            61: 
        !            62: /*
        !            63:  * This routine is called once every tick (1/HZ seconds).
        !            64:  * It gets called with the programme counter that was interrupted
        !            65:  * a flag telling whether we were in user or kernel mode and the
        !            66:  * previous priority we were in.
        !            67:  */
        !            68: clock(pc, umode)
        !            69: vaddr_t pc;
        !            70: {
        !            71:        register PROC *pp;
        !            72:        /*
        !            73:         * Ignore clock interrupts till we are ready.
        !            74:         */
        !            75:        if (batflag == 0)
        !            76:                return;
        !            77: 
        !            78:        /*
        !            79:         * Hook for alternate clock interrupt;
        !            80:         * Call polling function ("altclk") if there is one.
        !            81:         *
        !            82:         * For near function, "altsel" is 0 and "altclk" is offset.
        !            83:         * For far function, "altsel" is the CS selector and "altclk"
        !            84:         * is the offset.
        !            85:         *
        !            86:         * Since the polling function ends with a near rather than
        !            87:         * far return, far invocation is via ld_call() (ldas.s) which uses
        !            88:         * the despatch routine at CS:4 (ld.s) in any loadable driver.
        !            89:         */
        !            90:        if (altclk) {
        !            91:                if (altsel) {   /* will do far call to altclk fn */
        !            92:                        if (ld_call(altsel, altclk))
        !            93:                                return;
        !            94:                } else
        !            95:                        if ((*altclk)())
        !            96:                                return;
        !            97:        }
        !            98: 
        !            99:        /*
        !           100:         * Update timers.  Decrement time slice.
        !           101:         */
        !           102:        utimer += 1;
        !           103:        clocks += 1;
        !           104:        timer.t_tick += 1;
        !           105:        quantum -= 1;
        !           106: 
        !           107:        /*
        !           108:         * Give processes their schedule values per tick.
        !           109:         */
        !           110:        if (procq.p_lforw->p_cval > CVCLOCK) {
        !           111:                procq.p_lforw->p_cval -= CVCLOCK;
        !           112:                procq.p_cval += CVCLOCK;
        !           113:        }
        !           114: 
        !           115:        /*
        !           116:         * Tax current process and update his times.
        !           117:         */
        !           118:        pp = SELF;
        !           119:        pp->p_cval >>= 1;
        !           120:        if (umode == 0)
        !           121:                pp->p_stime++;
        !           122:        else {
        !           123:                pp->p_utime++;
        !           124:                u.u_ppc = pc;
        !           125:        }
        !           126: }
        !           127: 
        !           128: /*
        !           129:  * Do everything the clock wanted to do but couldn't as it would have
        !           130:  * taken too long.
        !           131:  * Also perform any system bookkeeping required at regular intervals.
        !           132:  */
        !           133: stand()
        !           134: {
        !           135:        int s;
        !           136: 
        !           137:        u.u_error = 0;
        !           138: 
        !           139:        /*
        !           140:         * Update the clock.
        !           141:         */
        !           142:        while (timer.t_tick >= HZ) {
        !           143:                timer.t_time++;
        !           144:                timer.t_tick -= HZ;
        !           145:                outflag = 1;
        !           146:        }
        !           147: 
        !           148:        /*
        !           149:         * Check expiration of quantum.
        !           150:         */
        !           151:        if (quantum <= 0) {
        !           152:                quantum = 0;
        !           153:                disflag = 1;
        !           154:        }
        !           155: 
        !           156:        /*
        !           157:         * Check the timed function queue if necessary.
        !           158:         */
        !           159:        if ( clocks > 0 )
        !           160:        do {
        !           161:                register TIM * np;
        !           162:                register TIM * tp;
        !           163: 
        !           164:                /*
        !           165:                 * Update [serviced] clock ticks since startup.
        !           166:                 */
        !           167:                lbolt++;
        !           168: 
        !           169:                /*
        !           170:                 * Remove timing list from queue, creating new temporary queue.
        !           171:                 */
        !           172:                tp = (TIM *) &timq[ lbolt % nel(timq) ];
        !           173:                s  = sphi();
        !           174: 
        !           175:                /*
        !           176:                 * Scan timing list.
        !           177:                 */
        !           178:                for ( np = tp->t_next; tp = np; ) {
        !           179: 
        !           180:                        /*
        !           181:                         * Remember next function in timing list.
        !           182:                         * NOTE: Must be done before function is invoked,
        !           183:                         *       since it may start a new timer.
        !           184:                         */
        !           185:                        np = tp->t_next;
        !           186: 
        !           187:                        /*
        !           188:                         * Function has not timed out: leave it on timing list.
        !           189:                         */
        !           190:                        if ( tp->t_lbolt != lbolt )
        !           191:                                continue;
        !           192: 
        !           193:                        /*
        !           194:                         * Remove function from timing list.
        !           195:                         */
        !           196:                        if ( tp->t_last->t_next = tp->t_next )
        !           197:                                tp->t_next->t_last = tp->t_last;
        !           198:                        tp->t_last = NULL;
        !           199: 
        !           200:                        /*
        !           201:                         * Invoke function.
        !           202:                         */
        !           203:                        spl(s);
        !           204:                        (*tp->t_func)( tp->t_farg, tp );
        !           205:                        sphi();
        !           206:                }
        !           207: 
        !           208:                spl( s );
        !           209: 
        !           210:        } while ( --clocks > 0 );
        !           211: 
        !           212:        /*
        !           213:         * Timeout any devices.
        !           214:         */
        !           215:        if (outflag) {
        !           216:                register int n;
        !           217: 
        !           218:                outflag = 0;
        !           219:                for (n=0; n<drvn; n++) {
        !           220:                        if (drvl[n].d_time == 0)
        !           221:                                continue;
        !           222:                        s = sphi();
        !           223:                        dtime((dev_t)makedev(n, 0));
        !           224:                        spl(s);
        !           225:                }
        !           226:        }
        !           227: 
        !           228:        /*
        !           229:         * Do profiling.
        !           230:         */
        !           231:        if (u.u_pscale != 0) {
        !           232:                register unsigned p;
        !           233:                register vaddr_t a;
        !           234: 
        !           235:                p = u.u_pscale;
        !           236:                a = (int *)u.u_pbase +
        !           237:                    pscale(u.u_ppc-u.u_pofft, p/sizeof (int));
        !           238:                if (a < u.u_pbend)
        !           239:                        putuwd(a, getuwd(a)+1);
        !           240:        }
        !           241: 
        !           242:        /*
        !           243:         * Check for signals and execute them.
        !           244:         */
        !           245:        if (SELF->p_ssig)
        !           246:                actvsig();
        !           247: 
        !           248:        /*
        !           249:         * Execute deferred functions.
        !           250:         */
        !           251:        defend();
        !           252: 
        !           253:        /*
        !           254:         * Should we dispatch?
        !           255:         */
        !           256:        if ((SELF->p_flags&PFDISP) != 0) {
        !           257:                SELF->p_flags &= ~PFDISP;
        !           258:                disflag = 1;
        !           259:                if ( stimer.t_last != 0 )
        !           260:                        wakeup((char *)&stimer);
        !           261:        }
        !           262: 
        !           263: #ifdef QWAKEUP
        !           264:        /*
        !           265:         * Dispatch pending wakeups.
        !           266:         */
        !           267:        while (ntowake)
        !           268:                wakeup2();
        !           269: 
        !           270: #endif
        !           271:        /*
        !           272:         * Redispatch.
        !           273:         * This used to be a function call in tsave,
        !           274:         * expanded in line here.
        !           275:         */
        !           276:        if (disflag) {
        !           277:                register PROC *pp;
        !           278: 
        !           279: #ifndef QWAKEUP
        !           280:                s=sphi();
        !           281: #endif
        !           282:                if ((pp=SELF)!=iprocp)
        !           283:                        setrun(pp);
        !           284:                dispatch();
        !           285: #ifndef QWAKEUP
        !           286:                spl(s);
        !           287: #endif
        !           288:        }
        !           289: }

unix.superglobalmegacorp.com

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