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--;
	}
}