|
|
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.