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