1 #include "u.h"
2 #include "lib.h"
3 #include "dat.h"
4 #include "fns.h"
5 
6 static void
queue(Proc ** first,Proc ** last)7 queue(Proc **first, Proc **last)
8 {
9 	Proc *t;
10 
11 	t = *last;
12 	if(t == 0)
13 		*first = up;
14 	else
15 		t->qnext = up;
16 	*last = up;
17 	up->qnext = 0;
18 }
19 
20 static Proc*
dequeue(Proc ** first,Proc ** last)21 dequeue(Proc **first, Proc **last)
22 {
23 	Proc *t;
24 
25 	t = *first;
26 	if(t == 0)
27 		return 0;
28 	*first = t->qnext;
29 	if(*first == 0)
30 		*last = 0;
31 	return t;
32 }
33 
34 void
qlock(QLock * q)35 qlock(QLock *q)
36 {
37 	lock(&q->lk);
38 
39 	if(q->hold == 0) {
40 		q->hold = up;
41 		unlock(&q->lk);
42 		return;
43 	}
44 
45 	/*
46 	 * Can't assert this because of RWLock
47 	assert(q->hold != up);
48 	 */
49 
50 	queue((Proc**)&q->first, (Proc**)&q->last);
51 	unlock(&q->lk);
52 	procsleep();
53 }
54 
55 int
canqlock(QLock * q)56 canqlock(QLock *q)
57 {
58 	lock(&q->lk);
59 	if(q->hold == 0) {
60 		q->hold = up;
61 		unlock(&q->lk);
62 		return 1;
63 	}
64 	unlock(&q->lk);
65 	return 0;
66 }
67 
68 void
qunlock(QLock * q)69 qunlock(QLock *q)
70 {
71 	Proc *p;
72 
73 	lock(&q->lk);
74 	/*
75 	 * Can't assert this because of RWlock
76 	assert(q->hold == CT);
77 	 */
78 	p = dequeue((Proc**)&q->first, (Proc**)&q->last);
79 	if(p) {
80 		q->hold = p;
81 		unlock(&q->lk);
82 		procwakeup(p);
83 	} else {
84 		q->hold = 0;
85 		unlock(&q->lk);
86 	}
87 }
88 
89 int
holdqlock(QLock * q)90 holdqlock(QLock *q)
91 {
92 	return q->hold == up;
93 }
94 
95