Coherent4.2.10/i386/defer.c
/* $Header: /ker/i386/RCS/defer.c,v 2.3 93/08/19 03:40:00 nigel Exp Locker: nigel $ */
/*
* Purpose: Handle deferring of functions and subsequent execution.
*
* $Log: defer.c,v $
* Revision 2.3 93/08/19 03:40:00 nigel
* Nigel's R83
*
* Revision 2.2 93/07/26 13:55:49 nigel
* Nigel's R80
*
* Revision 1.1 92/11/09 17:08:40 root
* Just before adding vio segs.
*/
#define DEFLIM 128 /* maximum number of deferred functions */
void defer();
void defend();
static void (*defunc[DEFLIM])();
static int defarg[DEFLIM];
static int defqix, defqox, defcnt;
/*
* defer()
*
* Defer a function [usually from interrupt level].
* The deferred function takes a single int-sized arg.
*/
#define DEFDBG 1
#if DEFDBG
static int deftag[DEFLIM];
void
defer0(f,a,t)
void (*f)();
int a;
int t;
{
int s=sphi();
if (defcnt < DEFLIM) { /* is there room in defer queue? */
defunc[defqix] = f;
defarg[defqix] = a;
deftag[defqix] = t;
if (++defqix >= DEFLIM)
defqix = 0;
defcnt++;
} else {
static foo;
int *r=(int *)(&f);
int tmpqox = defqox+DEFLIM-16;
if (foo++ == 0) {
printf("\nDefer overflow r=%x t =%x f=%x a=%x ",
*(r-1), t, f, a);
do {
tmpqox = (tmpqox+1) % DEFLIM;
printf("\nt=%x f=%x a=%x ox=%d ",
deftag[tmpqox], defunc[tmpqox],
defarg[tmpqox], tmpqox);
} while (tmpqox != defqox);
}
}
spl(s);
}
void
defer(f,a)
void (*f)();
int a;
{
defer0(f, a, 0);
}
#else
void
defer(f,a)
void (*f)();
int a;
{
int s=sphi();
if (defcnt < DEFLIM) { /* is there room in defer queue? */
defunc[defqix] = f;
defarg[defqix] = a;
if (++defqix >= DEFLIM)
defqix = 0;
defcnt++;
} else {
static foo;
int *r=(int *)(&f);
if (foo++ < 4)
printf("\nDefer overflow r=%x f=%x a=%x ", *(r-1), f, a);
}
spl(s);
}
#endif
/*
* defend()
*
* Evaluate all deferred functions.
* Should be called periodically by busy-wait device drivers.
*/
void
defend()
{
while (defcnt) {
(*defunc[defqox])(defarg[defqox]);
if (++defqox >= DEFLIM)
defqox = 0;
defcnt--;
}
}