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