Annotation of coherent/d/286_KERNEL/USRSRC/coh/clock.c, revision 1.1.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.