1 #include "dat.h" 2 #include "fns.h" 3 #include "error.h" 4 5 void lock(Lock * l)6lock(Lock *l) 7 { 8 int i; 9 10 if(_tas(&l->val) == 0) 11 return; 12 for(i=0; i<100; i++){ 13 if(_tas(&l->val) == 0) 14 return; 15 osyield(); 16 } 17 for(i=1;; i++){ 18 if(_tas(&l->val) == 0) 19 return; 20 osmillisleep(i*10); 21 if(i > 100){ 22 osyield(); 23 i = 1; 24 } 25 } 26 } 27 28 int canlock(Lock * l)29canlock(Lock *l) 30 { 31 return _tas(&l->val) == 0; 32 } 33 34 void unlock(Lock * l)35unlock(Lock *l) 36 { 37 l->val = 0; 38 } 39 40 void qlock(QLock * q)41qlock(QLock *q) 42 { 43 Proc *p; 44 45 lock(&q->use); 46 if(!q->locked) { 47 q->locked = 1; 48 unlock(&q->use); 49 return; 50 } 51 p = q->tail; 52 if(p == 0) 53 q->head = up; 54 else 55 p->qnext = up; 56 q->tail = up; 57 up->qnext = 0; 58 unlock(&q->use); 59 osblock(); 60 } 61 62 int canqlock(QLock * q)63canqlock(QLock *q) 64 { 65 if(!canlock(&q->use)) 66 return 0; 67 if(q->locked){ 68 unlock(&q->use); 69 return 0; 70 } 71 q->locked = 1; 72 unlock(&q->use); 73 return 1; 74 } 75 76 void qunlock(QLock * q)77qunlock(QLock *q) 78 { 79 Proc *p; 80 81 lock(&q->use); 82 p = q->head; 83 if(p) { 84 q->head = p->qnext; 85 if(q->head == 0) 86 q->tail = 0; 87 unlock(&q->use); 88 osready(p); 89 return; 90 } 91 q->locked = 0; 92 unlock(&q->use); 93 } 94 95 void rlock(RWlock * l)96rlock(RWlock *l) 97 { 98 qlock(&l->x); /* wait here for writers and exclusion */ 99 lock(&l->l); 100 l->readers++; 101 canqlock(&l->k); /* block writers if we are the first reader */ 102 unlock(&l->l); 103 qunlock(&l->x); 104 } 105 106 /* same as rlock but punts if there are any writers waiting */ 107 int canrlock(RWlock * l)108canrlock(RWlock *l) 109 { 110 if (!canqlock(&l->x)) 111 return 0; 112 lock(&l->l); 113 l->readers++; 114 canqlock(&l->k); /* block writers if we are the first reader */ 115 unlock(&l->l); 116 qunlock(&l->x); 117 return 1; 118 } 119 120 void runlock(RWlock * l)121runlock(RWlock *l) 122 { 123 lock(&l->l); 124 if(--l->readers == 0) /* last reader out allows writers */ 125 qunlock(&l->k); 126 unlock(&l->l); 127 } 128 129 void wlock(RWlock * l)130wlock(RWlock *l) 131 { 132 qlock(&l->x); /* wait here for writers and exclusion */ 133 qlock(&l->k); /* wait here for last reader */ 134 } 135 136 void wunlock(RWlock * l)137wunlock(RWlock *l) 138 { 139 qunlock(&l->k); 140 qunlock(&l->x); 141 } 142