Annotation of OSKit-Mach/oskit/pc/osenv_timer.c, revision 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.