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