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