Annotation of OSKit-Mach/oskit/pc/osenv_timer.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 University of Utah and the Flux Group.
                      3:  * All rights reserved.
                      4:  *
                      5:  * This file is part of the Flux OSKit.  The OSKit is free software, also known
                      6:  * as "open source;" you can redistribute it and/or modify it under the terms
                      7:  * of the GNU General Public License (GPL), version 2, as published by the Free
                      8:  * Software Foundation (FSF).  To explore alternate licensing terms, contact
                      9:  * the University of Utah at [email protected] or +1-801-585-3271.
                     10:  *
                     11:  * The OSKit is distributed in the hope that it will be useful, but WITHOUT ANY
                     12:  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
                     13:  * FOR A PARTICULAR PURPOSE.  See the GPL for more details.  You should have
                     14:  * received a copy of the GPL along with the OSKit; see the file COPYING.  If
                     15:  * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
                     16:  */
                     17: /*
                     18:  * Timer interrupt support.
                     19:  */
                     20: 
                     21: #include <oskit/dev/dev.h>
                     22: 
                     23: #include <oskit/machine/pc/pit.h>
                     24: 
                     25: #include <machine/mach_param.h>        /* HZ */
                     26: #include <machine/spl.h>
                     27: 
                     28: #include "../ds_oskit.h"
                     29: 
                     30: 
                     31: #define NTIMERS                4
                     32: #define TIMER_FREQ     HZ
                     33: #define TIMER_VALUE    (PIT_HZ / TIMER_FREQ)
                     34: 
                     35: struct timer_handler {
                     36:        void    (*func)(void);
                     37:        struct  timer_handler *next;
                     38: };
                     39: 
                     40: static struct timer_handler *timer_head, *timer_free;
                     41: static struct timer_handler timer_data[NTIMERS];
                     42: 
                     43: 
                     44: /*
                     45:  * This is called on every Mach clock tick, at splsoftclock.
                     46:  * These handlers want to be called with interrupts disabled,
                     47:  * but then reenable and redisable them before returning.
                     48:  */
                     49: void
                     50: softclock_oskit (void)
                     51: {
                     52:        struct timer_handler *th;
                     53:        osenv_intr_disable();
                     54:        for (th = timer_head; th; th = th->next)
                     55:                (*th->func)();
                     56:        osenv_intr_enable();
                     57: 
                     58:        oskit_softint();
                     59: }
                     60: 
                     61: /*
                     62:  * Initialize timers.
                     63:  */
                     64: void
                     65: osenv_timer_init()
                     66: {
                     67:        static int initialized = 0;  /* guard against multiple invocations */
                     68:        int i;
                     69: 
                     70:        if (initialized)
                     71:                return;
                     72: 
                     73:        initialized = 1;
                     74: 
                     75:        for (i = 0; i < NTIMERS; i++)
                     76:                timer_data[i].next = &timer_data[i + 1];
                     77:        timer_data[NTIMERS - 1].next = 0;
                     78:        timer_free = &timer_data[0];
                     79: }
                     80: 
                     81: /*
                     82:  * Turn all timers off.
                     83:  */
                     84: void
                     85: osenv_timer_shutdown()
                     86: {
                     87:        osenv_log(OSENV_LOG_DEBUG, "Shutting down timer\n");
                     88:        osenv_timer_pit_shutdown();
                     89: }
                     90: 
                     91: /*
                     92:  * Register a timer handler to be called at the specified frequency.
                     93:  */
                     94: void
                     95: osenv_timer_register(void (*func)(void), int freq)
                     96: {
                     97:        struct timer_handler *th;
                     98:        spl_t s;
                     99: 
                    100:        /* XXX */
                    101:        osenv_timer_init();
                    102: 
                    103:        if (timer_free == 0)
                    104:                osenv_panic("%s:%d: ran out of entries", __FILE__, __LINE__);
                    105:        /*
                    106:         * XXX
                    107:         */
                    108:        if (freq != TIMER_FREQ)
                    109:                osenv_panic("%s:%d: bad freq", __FILE__, __LINE__);
                    110:        if (func == 0)
                    111:                osenv_panic("%s:%d: null function", __FILE__, __LINE__);
                    112: 
                    113:        s = splio ();
                    114: 
                    115:        th = timer_free;
                    116:        timer_free = th->next;
                    117:        th->next = timer_head;
                    118:        timer_head = th;
                    119:        th->func = func;
                    120: 
                    121:        splx (s);
                    122: }
                    123: 
                    124: 
                    125: /*
                    126:  * Frequency and function address uniquely identify which to remove since
                    127:  * equal values are equivelent.
                    128:  */
                    129: void
                    130: osenv_timer_unregister(void (*func)(void), int freq)
                    131: {
                    132:        spl_t s;
                    133:        struct timer_handler *th, **prev;
                    134: 
                    135:        if (freq != TIMER_FREQ)
                    136:                osenv_panic("%s:%d: bad freq", __FILE__, __LINE__);
                    137: 
                    138:        s = splio ();
                    139: 
                    140:        /* move the timer from the run-queue to the unused-queue */
                    141:        prev = &timer_head;
                    142:        th = timer_head;
                    143: 
                    144:        while (th && (th->func != func)) {
                    145:                prev = &th->next;
                    146:                th = th->next;
                    147:        }
                    148:        if (!th) {
                    149:                osenv_log(OSENV_LOG_WARNING, "Timer handler not found\n");
                    150:        } else {
                    151:                /* have the active list skip over it */
                    152:                *prev = th->next;
                    153: 
                    154:                /* place in inactive queue */
                    155:                th->next = timer_free;
                    156:                timer_free = th;
                    157:        }
                    158: 
                    159:        splx (s);
                    160: }
                    161: 
                    162: 
                    163: /*
                    164:  * Spin for a small amount of time, specified in nanoseconds,
                    165:  * without blocking or enabling interrupts.
                    166:  */
                    167: void
                    168: osenv_timer_spin(long nanosec)
                    169: {
                    170:        int prev_val = osenv_timer_pit_read();
                    171: 
                    172:        while (nanosec > 0) {
                    173:                int val = osenv_timer_pit_read();
                    174:                if (val > prev_val)
                    175:                        prev_val += TIMER_VALUE;
                    176:                nanosec -= (prev_val - val) * PIT_NS;
                    177:                prev_val = val;
                    178:        }
                    179: }

unix.superglobalmegacorp.com

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