1 b2cfc4e2 2003-09-30 devnull #include <lib9.h>
3 b2cfc4e2 2003-09-30 devnull static struct {
5 b2cfc4e2 2003-09-30 devnull QLp x[1024];
13 b2cfc4e2 2003-09-30 devnull QueuingR,
14 b2cfc4e2 2003-09-30 devnull QueuingW,
15 b2cfc4e2 2003-09-30 devnull Sleeping,
18 b2cfc4e2 2003-09-30 devnull static ulong (*_rendezvousp)(ulong, ulong) = rendezvous;
20 b2cfc4e2 2003-09-30 devnull /* this gets called by the thread library ONLY to get us to use its rendezvous */
22 b2cfc4e2 2003-09-30 devnull _qlockinit(ulong (*r)(ulong, ulong))
24 b2cfc4e2 2003-09-30 devnull _rendezvousp = r;
27 b2cfc4e2 2003-09-30 devnull /* find a free shared memory location to queue ourselves in */
28 b2cfc4e2 2003-09-30 devnull static QLp*
29 b2cfc4e2 2003-09-30 devnull getqlp(void)
31 b2cfc4e2 2003-09-30 devnull QLp *p, *op;
33 b2cfc4e2 2003-09-30 devnull op = ql.p;
34 b2cfc4e2 2003-09-30 devnull for(p = op+1; ; p++){
35 b2cfc4e2 2003-09-30 devnull if(p == &ql.x[nelem(ql.x)])
36 b2cfc4e2 2003-09-30 devnull p = ql.x;
37 b2cfc4e2 2003-09-30 devnull if(p == op)
39 b2cfc4e2 2003-09-30 devnull if(_tas(&(p->inuse)) == 0){
40 b2cfc4e2 2003-09-30 devnull ql.p = p;
41 b2cfc4e2 2003-09-30 devnull p->next = nil;
45 b2cfc4e2 2003-09-30 devnull return p;
49 b2cfc4e2 2003-09-30 devnull qlock(QLock *q)
51 b2cfc4e2 2003-09-30 devnull QLp *p, *mp;
53 b2cfc4e2 2003-09-30 devnull lock(&q->lock);
54 b2cfc4e2 2003-09-30 devnull if(!q->locked){
55 b2cfc4e2 2003-09-30 devnull q->locked = 1;
56 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
61 b2cfc4e2 2003-09-30 devnull /* chain into waiting list */
62 b2cfc4e2 2003-09-30 devnull mp = getqlp();
63 b2cfc4e2 2003-09-30 devnull p = q->tail;
64 b2cfc4e2 2003-09-30 devnull if(p == nil)
65 b2cfc4e2 2003-09-30 devnull q->head = mp;
67 b2cfc4e2 2003-09-30 devnull p->next = mp;
68 b2cfc4e2 2003-09-30 devnull q->tail = mp;
69 b2cfc4e2 2003-09-30 devnull mp->state = Queuing;
70 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
72 b2cfc4e2 2003-09-30 devnull /* wait */
73 b2cfc4e2 2003-09-30 devnull while((*_rendezvousp)((ulong)mp, 1) == ~0)
75 b2cfc4e2 2003-09-30 devnull mp->inuse = 0;
79 b2cfc4e2 2003-09-30 devnull qunlock(QLock *q)
83 b2cfc4e2 2003-09-30 devnull lock(&q->lock);
84 b2cfc4e2 2003-09-30 devnull p = q->head;
85 b2cfc4e2 2003-09-30 devnull if(p != nil){
86 b2cfc4e2 2003-09-30 devnull /* wakeup head waiting process */
87 b2cfc4e2 2003-09-30 devnull q->head = p->next;
88 b2cfc4e2 2003-09-30 devnull if(q->head == nil)
89 b2cfc4e2 2003-09-30 devnull q->tail = nil;
90 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
91 b2cfc4e2 2003-09-30 devnull while((*_rendezvousp)((ulong)p, 0x12345) == ~0)
95 b2cfc4e2 2003-09-30 devnull q->locked = 0;
96 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
100 b2cfc4e2 2003-09-30 devnull canqlock(QLock *q)
102 b2cfc4e2 2003-09-30 devnull if(!canlock(&q->lock))
103 b2cfc4e2 2003-09-30 devnull return 0;
104 b2cfc4e2 2003-09-30 devnull if(!q->locked){
105 b2cfc4e2 2003-09-30 devnull q->locked = 1;
106 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
107 b2cfc4e2 2003-09-30 devnull return 1;
109 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
110 b2cfc4e2 2003-09-30 devnull return 0;
114 b2cfc4e2 2003-09-30 devnull rlock(RWLock *q)
116 b2cfc4e2 2003-09-30 devnull QLp *p, *mp;
118 b2cfc4e2 2003-09-30 devnull lock(&q->lock);
119 b2cfc4e2 2003-09-30 devnull if(q->writer == 0 && q->head == nil){
120 b2cfc4e2 2003-09-30 devnull /* no writer, go for it */
121 b2cfc4e2 2003-09-30 devnull q->readers++;
122 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
126 b2cfc4e2 2003-09-30 devnull mp = getqlp();
127 b2cfc4e2 2003-09-30 devnull p = q->tail;
128 b2cfc4e2 2003-09-30 devnull if(p == 0)
129 b2cfc4e2 2003-09-30 devnull q->head = mp;
131 b2cfc4e2 2003-09-30 devnull p->next = mp;
132 b2cfc4e2 2003-09-30 devnull q->tail = mp;
133 b2cfc4e2 2003-09-30 devnull mp->next = nil;
134 b2cfc4e2 2003-09-30 devnull mp->state = QueuingR;
135 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
137 b2cfc4e2 2003-09-30 devnull /* wait in kernel */
138 b2cfc4e2 2003-09-30 devnull while((*_rendezvousp)((ulong)mp, 1) == ~0)
140 b2cfc4e2 2003-09-30 devnull mp->inuse = 0;
144 b2cfc4e2 2003-09-30 devnull canrlock(RWLock *q)
146 b2cfc4e2 2003-09-30 devnull lock(&q->lock);
147 b2cfc4e2 2003-09-30 devnull if (q->writer == 0 && q->head == nil) {
148 b2cfc4e2 2003-09-30 devnull /* no writer; go for it */
149 b2cfc4e2 2003-09-30 devnull q->readers++;
150 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
151 b2cfc4e2 2003-09-30 devnull return 1;
153 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
154 b2cfc4e2 2003-09-30 devnull return 0;
158 b2cfc4e2 2003-09-30 devnull runlock(RWLock *q)
162 b2cfc4e2 2003-09-30 devnull lock(&q->lock);
163 b2cfc4e2 2003-09-30 devnull if(q->readers <= 0)
164 b2cfc4e2 2003-09-30 devnull abort();
165 b2cfc4e2 2003-09-30 devnull p = q->head;
166 b2cfc4e2 2003-09-30 devnull if(--(q->readers) > 0 || p == nil){
167 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
171 b2cfc4e2 2003-09-30 devnull /* start waiting writer */
172 b2cfc4e2 2003-09-30 devnull if(p->state != QueuingW)
173 b2cfc4e2 2003-09-30 devnull abort();
174 b2cfc4e2 2003-09-30 devnull q->head = p->next;
175 b2cfc4e2 2003-09-30 devnull if(q->head == 0)
176 b2cfc4e2 2003-09-30 devnull q->tail = 0;
177 b2cfc4e2 2003-09-30 devnull q->writer = 1;
178 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
180 b2cfc4e2 2003-09-30 devnull /* wakeup waiter */
181 b2cfc4e2 2003-09-30 devnull while((*_rendezvousp)((ulong)p, 0) == ~0)
186 b2cfc4e2 2003-09-30 devnull wlock(RWLock *q)
188 b2cfc4e2 2003-09-30 devnull QLp *p, *mp;
190 b2cfc4e2 2003-09-30 devnull lock(&q->lock);
191 b2cfc4e2 2003-09-30 devnull if(q->readers == 0 && q->writer == 0){
192 b2cfc4e2 2003-09-30 devnull /* noone waiting, go for it */
193 b2cfc4e2 2003-09-30 devnull q->writer = 1;
194 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
198 b2cfc4e2 2003-09-30 devnull /* wait */
199 b2cfc4e2 2003-09-30 devnull p = q->tail;
200 b2cfc4e2 2003-09-30 devnull mp = getqlp();
201 b2cfc4e2 2003-09-30 devnull if(p == nil)
202 b2cfc4e2 2003-09-30 devnull q->head = mp;
204 b2cfc4e2 2003-09-30 devnull p->next = mp;
205 b2cfc4e2 2003-09-30 devnull q->tail = mp;
206 b2cfc4e2 2003-09-30 devnull mp->next = nil;
207 b2cfc4e2 2003-09-30 devnull mp->state = QueuingW;
208 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
210 b2cfc4e2 2003-09-30 devnull /* wait in kernel */
211 b2cfc4e2 2003-09-30 devnull while((*_rendezvousp)((ulong)mp, 1) == ~0)
213 b2cfc4e2 2003-09-30 devnull mp->inuse = 0;
217 b2cfc4e2 2003-09-30 devnull canwlock(RWLock *q)
219 b2cfc4e2 2003-09-30 devnull lock(&q->lock);
220 b2cfc4e2 2003-09-30 devnull if (q->readers == 0 && q->writer == 0) {
221 b2cfc4e2 2003-09-30 devnull /* no one waiting; go for it */
222 b2cfc4e2 2003-09-30 devnull q->writer = 1;
223 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
224 b2cfc4e2 2003-09-30 devnull return 1;
226 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
227 b2cfc4e2 2003-09-30 devnull return 0;
231 b2cfc4e2 2003-09-30 devnull wunlock(RWLock *q)
235 b2cfc4e2 2003-09-30 devnull lock(&q->lock);
236 b2cfc4e2 2003-09-30 devnull if(q->writer == 0)
237 b2cfc4e2 2003-09-30 devnull abort();
238 b2cfc4e2 2003-09-30 devnull p = q->head;
239 b2cfc4e2 2003-09-30 devnull if(p == nil){
240 b2cfc4e2 2003-09-30 devnull q->writer = 0;
241 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
244 b2cfc4e2 2003-09-30 devnull if(p->state == QueuingW){
245 b2cfc4e2 2003-09-30 devnull /* start waiting writer */
246 b2cfc4e2 2003-09-30 devnull q->head = p->next;
247 b2cfc4e2 2003-09-30 devnull if(q->head == nil)
248 b2cfc4e2 2003-09-30 devnull q->tail = nil;
249 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
250 b2cfc4e2 2003-09-30 devnull while((*_rendezvousp)((ulong)p, 0) == ~0)
255 b2cfc4e2 2003-09-30 devnull if(p->state != QueuingR)
256 b2cfc4e2 2003-09-30 devnull abort();
258 b2cfc4e2 2003-09-30 devnull /* wake waiting readers */
259 b2cfc4e2 2003-09-30 devnull while(q->head != nil && q->head->state == QueuingR){
260 b2cfc4e2 2003-09-30 devnull p = q->head;
261 b2cfc4e2 2003-09-30 devnull q->head = p->next;
262 b2cfc4e2 2003-09-30 devnull q->readers++;
263 b2cfc4e2 2003-09-30 devnull while((*_rendezvousp)((ulong)p, 0) == ~0)
266 b2cfc4e2 2003-09-30 devnull if(q->head == nil)
267 b2cfc4e2 2003-09-30 devnull q->tail = nil;
268 b2cfc4e2 2003-09-30 devnull q->writer = 0;
269 b2cfc4e2 2003-09-30 devnull unlock(&q->lock);
273 b2cfc4e2 2003-09-30 devnull rsleep(Rendez *r)
275 b2cfc4e2 2003-09-30 devnull QLp *t, *me;
277 b2cfc4e2 2003-09-30 devnull if(!r->l)
278 b2cfc4e2 2003-09-30 devnull abort();
279 b2cfc4e2 2003-09-30 devnull lock(&r->l->lock);
280 b2cfc4e2 2003-09-30 devnull /* we should hold the qlock */
281 b2cfc4e2 2003-09-30 devnull if(!r->l->locked)
282 b2cfc4e2 2003-09-30 devnull abort();
284 b2cfc4e2 2003-09-30 devnull /* add ourselves to the wait list */
285 b2cfc4e2 2003-09-30 devnull me = getqlp();
286 b2cfc4e2 2003-09-30 devnull me->state = Sleeping;
287 b2cfc4e2 2003-09-30 devnull if(r->head == nil)
288 b2cfc4e2 2003-09-30 devnull r->head = me;
290 b2cfc4e2 2003-09-30 devnull r->tail->next = me;
291 b2cfc4e2 2003-09-30 devnull me->next = nil;
292 b2cfc4e2 2003-09-30 devnull r->tail = me;
294 b2cfc4e2 2003-09-30 devnull /* pass the qlock to the next guy */
295 b2cfc4e2 2003-09-30 devnull t = r->l->head;
297 b2cfc4e2 2003-09-30 devnull r->l->head = t->next;
298 b2cfc4e2 2003-09-30 devnull if(r->l->head == nil)
299 b2cfc4e2 2003-09-30 devnull r->l->tail = nil;
300 b2cfc4e2 2003-09-30 devnull unlock(&r->l->lock);
301 b2cfc4e2 2003-09-30 devnull while((*_rendezvousp)((ulong)t, 0x12345) == ~0)
304 b2cfc4e2 2003-09-30 devnull r->l->locked = 0;
305 b2cfc4e2 2003-09-30 devnull unlock(&r->l->lock);
308 b2cfc4e2 2003-09-30 devnull /* wait for a wakeup */
309 b2cfc4e2 2003-09-30 devnull while((*_rendezvousp)((ulong)me, 0x23456) == ~0)
311 b2cfc4e2 2003-09-30 devnull me->inuse = 0;
312 b2cfc4e2 2003-09-30 devnull if(!r->l->locked)
313 b2cfc4e2 2003-09-30 devnull abort();
317 b2cfc4e2 2003-09-30 devnull rwakeup(Rendez *r)
322 b2cfc4e2 2003-09-30 devnull * take off wait and put on front of queue
323 b2cfc4e2 2003-09-30 devnull * put on front so guys that have been waiting will not get starved
326 b2cfc4e2 2003-09-30 devnull if(!r->l)
327 b2cfc4e2 2003-09-30 devnull abort();
328 b2cfc4e2 2003-09-30 devnull lock(&r->l->lock);
329 b2cfc4e2 2003-09-30 devnull if(!r->l->locked)
330 b2cfc4e2 2003-09-30 devnull abort();
332 b2cfc4e2 2003-09-30 devnull t = r->head;
333 b2cfc4e2 2003-09-30 devnull if(t == nil){
334 b2cfc4e2 2003-09-30 devnull unlock(&r->l->lock);
335 b2cfc4e2 2003-09-30 devnull return 0;
338 b2cfc4e2 2003-09-30 devnull r->head = t->next;
339 b2cfc4e2 2003-09-30 devnull if(r->head == nil)
340 b2cfc4e2 2003-09-30 devnull r->tail = nil;
342 b2cfc4e2 2003-09-30 devnull t->next = r->l->head;
343 b2cfc4e2 2003-09-30 devnull r->l->head = t;
344 b2cfc4e2 2003-09-30 devnull if(r->l->tail == nil)
345 b2cfc4e2 2003-09-30 devnull r->l->tail = t;
347 b2cfc4e2 2003-09-30 devnull t->state = Queuing;
348 b2cfc4e2 2003-09-30 devnull unlock(&r->l->lock);
349 b2cfc4e2 2003-09-30 devnull return 1;
353 b2cfc4e2 2003-09-30 devnull rwakeupall(Rendez *r)
357 b2cfc4e2 2003-09-30 devnull for(i=0; rwakeup(r); i++)
359 b2cfc4e2 2003-09-30 devnull return i;