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