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