|
|
1.1 ! root 1: /* ! 2: * File: defer.c ! 3: * ! 4: * Purpose: Handle deferring of functions and subsequent execution. ! 5: * ! 6: * $Log: defer.c,v $ ! 7: * Revision 1.9 93/06/14 13:42:38 bin ! 8: * Hal: kernel 78 update ! 9: * ! 10: * Revision 1.1 92/11/09 17:08:40 root ! 11: * Just before adding vio segs. ! 12: * ! 13: */ ! 14: ! 15: /* ! 16: * ---------------------------------------------------------------------- ! 17: * Includes. ! 18: */ ! 19: ! 20: /* ! 21: * ---------------------------------------------------------------------- ! 22: * Definitions. ! 23: * Constants. ! 24: * Macros with argument lists. ! 25: * Typedefs. ! 26: * Enums. ! 27: */ ! 28: #define DEFLIM 128 /* maximum number of deferred functions */ ! 29: ! 30: /* ! 31: * ---------------------------------------------------------------------- ! 32: * Functions. ! 33: * Import Functions. ! 34: * Export Functions. ! 35: * Local Functions. ! 36: */ ! 37: void defer(); ! 38: void defend(); ! 39: ! 40: /* ! 41: * ---------------------------------------------------------------------- ! 42: * Global Data. ! 43: * Import Variables. ! 44: * Export Variables. ! 45: * Local Variables. ! 46: */ ! 47: static void (*defunc[DEFLIM])(); ! 48: static int defarg[DEFLIM]; ! 49: static int defqix, defqox, defcnt; ! 50: ! 51: /* ! 52: * ---------------------------------------------------------------------- ! 53: * Code. ! 54: */ ! 55: ! 56: /* ! 57: * defer() ! 58: * ! 59: * Defer a function [usually from interrupt level]. ! 60: * The deferred function takes a single int-sized arg. ! 61: */ ! 62: #define DEFDBG 1 ! 63: #if DEFDBG ! 64: static int deftag[DEFLIM]; ! 65: ! 66: void ! 67: defer0(f,a,t) ! 68: void (*f)(); ! 69: int a; ! 70: int t; ! 71: { ! 72: int s=sphi(); ! 73: ! 74: if (defcnt < DEFLIM) { /* is there room in defer queue? */ ! 75: defunc[defqix] = f; ! 76: defarg[defqix] = a; ! 77: deftag[defqix] = t; ! 78: if (++defqix >= DEFLIM) ! 79: defqix = 0; ! 80: defcnt++; ! 81: } else { ! 82: static foo; ! 83: int *r=(int *)(&f); ! 84: int tmpqox = defqox+DEFLIM-16; ! 85: ! 86: if (foo++ == 0) { ! 87: printf("\nDefer overflow r=%x t =%x f=%x a=%x ", ! 88: *(r-1), t, f, a); ! 89: do { ! 90: tmpqox = (tmpqox+1) % DEFLIM; ! 91: printf("\nt=%x f=%x a=%x ox=%d ", ! 92: deftag[tmpqox], defunc[tmpqox], ! 93: defarg[tmpqox], tmpqox); ! 94: } while (tmpqox != defqox); ! 95: } ! 96: } ! 97: spl(s); ! 98: } ! 99: ! 100: void ! 101: defer(f,a) ! 102: void (*f)(); ! 103: int a; ! 104: { ! 105: defer0(f, a, 0); ! 106: } ! 107: #else ! 108: void ! 109: defer(f,a) ! 110: void (*f)(); ! 111: int a; ! 112: { ! 113: int s=sphi(); ! 114: ! 115: if (defcnt < DEFLIM) { /* is there room in defer queue? */ ! 116: defunc[defqix] = f; ! 117: defarg[defqix] = a; ! 118: if (++defqix >= DEFLIM) ! 119: defqix = 0; ! 120: defcnt++; ! 121: } else { ! 122: static foo; ! 123: int *r=(int *)(&f); ! 124: if (foo++ < 4) ! 125: printf("\nDefer overflow r=%x f=%x a=%x ", *(r-1), f, a); ! 126: } ! 127: spl(s); ! 128: } ! 129: #endif ! 130: ! 131: /* ! 132: * defend() ! 133: * ! 134: * Evaluate all deferred functions. ! 135: * Should be called periodically by busy-wait device drivers. ! 136: */ ! 137: void ! 138: defend() ! 139: { ! 140: while (defcnt) { ! 141: (*defunc[defqox])(defarg[defqox]); ! 142: if (++defqox >= DEFLIM) ! 143: defqox = 0; ! 144: defcnt--; ! 145: } ! 146: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.