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)7queue(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)21dequeue(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)35qlock(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)56canqlock(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)69qunlock(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)90holdqlock(QLock *q) 91 { 92 return q->hold == up; 93 } 94 95