|
|
1.1 root 1: /* $Header: /newbits/286_KERNEL/USRSRC/coh/RCS/poll.c,v 1.1 92/01/09 13:28:59 bin Exp Locker: bin $ */
2: /*
3: * The information contained herein is a trade secret of INETCO
4: * Systems, and is confidential information. It is provided under
5: * a license agreement, and may be copied or disclosed only under
6: * the terms of that agreement. Any reproduction or disclosure of
7: * this material without the express written authorization of
8: * INETCO Systems or persuant to the license agreement is unlawful.
9: *
10: * Copyright (c) 1986
11: * An unpublished work by INETCO Systems, Ltd.
12: * All rights reserved.
13: */
14:
15: /*
16: * [Stream] Polling.
17: *
18: * void pollinit( ) -- allocate polling buffers
19: * int pollopen(qp) -- enable polling by current process on given queue
20: * int pollwake(qp) -- wake all processes waiting for poll on given queue
21: * int pollexit( ) -- terminate all polls enabled by current process
22: * event_t * ep;
23: *
24: * $Log: poll.c,v $
25: * Revision 1.1 92/01/09 13:28:59 bin
26: * Initial revision
27: *
28: * Revision 1.1 88/03/24 16:14:10 src
29: * Initial revision
30: *
31: * 86/11/19 Allan Cornish /usr/src/sys/coh/poll.c
32: * Ported to Coherent from RTX.
33: */
34:
35: #include <sys/coherent.h>
36: #include <sys/proc.h>
37: #include <sys/uproc.h>
38:
39: /*
40: * Patchable data.
41: */
42: int NPOLL = 0;
43:
44: /*
45: * Private data.
46: */
47: static event_t * efreep;
48:
49: /**
50: *
51: * event_t *
52: * pollinit() -- allocate event buffers.
53: */
54: event_t *
55: pollinit()
56: {
57: register event_t * ep;
58: register event_t * ap;
59: static int first = 1;
60:
61: /*
62: * If dynamically growing event pool is specified [NPOLL == 0],
63: * try to allocate an additional cluster of 32 on each call.
64: */
65: if ( NPOLL == 0 ) {
66: if ( ep = kalloc( 32 * sizeof(event_t) ) )
67: ap = ep + 32;
68: }
69:
70: /*
71: * If statically sized event pool is specified [NPOLL != 0],
72: * try to allocate the pool on the first call.
73: */
74: else if ( first ) {
75: first = 0;
76: if ( ep = kalloc( NPOLL * sizeof(event_t) ) )
77: ap = ep + NPOLL;
78: }
79:
80: /*
81: * If event cluster was allocated, insert into free event queue.
82: */
83: if ( ep ) {
84: do {
85: ep->e_pnext = efreep;
86: efreep = ep;
87: } while ( ++ep < ap );
88: }
89:
90: return efreep;
91: }
92:
93: /**
94: *
95: * int
96: * pollopen(qp) -- enable polling by current process on given event queue
97: * event_t * qp;
98: */
99: pollopen( qp )
100: register event_t * qp;
101: {
102: register event_t * ep;
103:
104: /*
105: * Initialize device queue if required.
106: */
107: if ( qp->e_dnext == 0 )
108: qp->e_dnext = qp->e_dlast = qp;
109:
110: /*
111: * Obtain a free event buffer, or return.
112: */
113: if ( ((ep = efreep) == 0) && ((ep = pollinit()) == 0) ) {
114: printf("out of poll buffers\n");
115: return;
116: }
117:
118: /*
119: * Remove event buffer from free queue.
120: */
121: efreep = ep->e_pnext;
122:
123: /*
124: * Record process pointer in event buffer.
125: */
126: ep->e_procp = cprocp;
127:
128: /*
129: * Insert event at head of process event singularly-linked queue.
130: */
131: ep->e_pnext = cprocp->p_polls;
132: cprocp->p_polls = ep;
133:
134: /*
135: * Insert event at tail of circularly-linked device queue.
136: * This ensures that processes are first-in first-out.
137: */
138: ep->e_dnext = qp;
139: (ep->e_dlast = qp->e_dlast)->e_dnext = ep;
140: qp->e_dlast = ep;
141:
142: /*
143: * Record last process to enable polling on device.
144: */
145: qp->e_procp = cprocp;
146: }
147:
148: /**
149: *
150: * int
151: * pollwake( qp ) -- wake all processes waiting for poll on given queue
152: * event_t * qp;
153: */
154: pollwake( qp )
155: event_t * qp;
156: {
157: register event_t * ep = qp;
158: register PROC * pp;
159:
160: /*
161: * Clear device process pointer, indicating poll completed.
162: * NOTE: interrupt handlers may have already cleared it.
163: */
164: qp->e_procp = 0;
165:
166: if ( ep = qp->e_dnext ) {
167:
168: /*
169: * Service circularly-linked polls on device queue.
170: */
171: while ( ep != qp ) {
172: /*
173: * Wake process if it is sleeping.
174: */
175: if ( (pp = ep->e_procp) && (pp->p_state == PSSLEEP) )
176: wakeup( &pp->p_polls );
177:
178: ep = ep->e_dnext;
179: }
180: }
181: }
182:
183: /**
184: *
185: * int
186: * pollexit() -- terminate all polls opened by current process
187: */
188: int
189: pollexit()
190: {
191: register PROC * pp = cprocp;
192: register event_t * ep;
193:
194: /*
195: * Service all polling event buffers enabled by current process.
196: */
197: while ( ep = pp->p_polls ) {
198:
199: /*
200: * Remove event buffer from circularly-linked device queue.
201: */
202: (ep->e_dnext->e_dlast = ep->e_dlast)->e_dnext = ep->e_dnext;
203:
204: /*
205: * Remove event buffer from singularly-linked process queue.
206: */
207: pp->p_polls = ep->e_pnext;
208:
209: /*
210: * Insert event buffer at head of free event buffer queue.
211: */
212: ep->e_pnext = efreep;
213: efreep = ep;
214: }
215: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.