1 #include "u.h" 2 #include "../port/lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 7 void qlock(QLock * q)8qlock(QLock *q) 9 { 10 Proc *p, *mp; 11 12 lock(&q->use); 13 if(!q->locked) { 14 q->locked = 1; 15 unlock(&q->use); 16 return; 17 } 18 p = q->tail; 19 mp = up; 20 if(p == 0) 21 q->head = mp; 22 else 23 p->qnext = mp; 24 q->tail = mp; 25 mp->qnext = 0; 26 mp->state = Queueing; 27 up->qpc = getcallerpc(&q); 28 unlock(&q->use); 29 sched(); 30 } 31 32 int canqlock(QLock * q)33canqlock(QLock *q) 34 { 35 if(!canlock(&q->use)) 36 return 0; 37 if(q->locked){ 38 unlock(&q->use); 39 return 0; 40 } 41 q->locked = 1; 42 unlock(&q->use); 43 return 1; 44 } 45 46 void qunlock(QLock * q)47qunlock(QLock *q) 48 { 49 Proc *p; 50 51 lock(&q->use); 52 p = q->head; 53 if(p) { 54 q->head = p->qnext; 55 if(q->head == 0) 56 q->tail = 0; 57 unlock(&q->use); 58 ready(p); 59 return; 60 } 61 q->locked = 0; 62 unlock(&q->use); 63 } 64 65 void rlock(RWlock * l)66rlock(RWlock *l) 67 { 68 qlock(&l->x); /* wait here for writers and exclusion */ 69 lock(l); 70 l->readers++; 71 canqlock(&l->k); /* block writers if we are the first reader */ 72 unlock(l); 73 qunlock(&l->x); 74 } 75 76 /* same as rlock but punts if there are any writers waiting */ 77 int canrlock(RWlock * l)78canrlock(RWlock *l) 79 { 80 if (!canqlock(&l->x)) 81 return 0; 82 lock(l); 83 l->readers++; 84 canqlock(&l->k); /* block writers if we are the first reader */ 85 unlock(l); 86 qunlock(&l->x); 87 return 1; 88 } 89 90 void runlock(RWlock * l)91runlock(RWlock *l) 92 { 93 lock(l); 94 if(--l->readers == 0) /* last reader out allows writers */ 95 qunlock(&l->k); 96 unlock(l); 97 } 98 99 void wlock(RWlock * l)100wlock(RWlock *l) 101 { 102 qlock(&l->x); /* wait here for writers and exclusion */ 103 qlock(&l->k); /* wait here for last reader */ 104 } 105 106 void wunlock(RWlock * l)107wunlock(RWlock *l) 108 { 109 qunlock(&l->k); 110 qunlock(&l->x); 111 } 112