Blob
1 #include <u.h>2 #include <libc.h>4 /*5 * The function pointers are supplied by the thread6 * library during its initialization. If there is no thread7 * library, there is no multithreading.8 */10 int (*_lock)(Lock*, int, ulong);11 void (*_unlock)(Lock*, ulong);12 int (*_qlock)(QLock*, int, ulong); /* do not use */13 void (*_qunlock)(QLock*, ulong);14 void (*_rsleep)(Rendez*, ulong); /* do not use */15 int (*_rwakeup)(Rendez*, int, ulong);16 int (*_rlock)(RWLock*, int, ulong); /* do not use */17 int (*_wlock)(RWLock*, int, ulong);18 void (*_runlock)(RWLock*, ulong);19 void (*_wunlock)(RWLock*, ulong);21 void22 lock(Lock *l)23 {24 if(_lock)25 (*_lock)(l, 1, getcallerpc(&l));26 else27 l->held = 1;28 }30 int31 canlock(Lock *l)32 {33 if(_lock)34 return (*_lock)(l, 0, getcallerpc(&l));35 else{36 if(l->held)37 return 0;38 l->held = 1;39 return 1;40 }41 }43 void44 unlock(Lock *l)45 {46 if(_unlock)47 (*_unlock)(l, getcallerpc(&l));48 else49 l->held = 0;50 }52 void53 qlock(QLock *l)54 {55 if(_qlock)56 (*_qlock)(l, 1, getcallerpc(&l));57 else58 l->l.held = 1;59 }61 int62 canqlock(QLock *l)63 {64 if(_qlock)65 return (*_qlock)(l, 0, getcallerpc(&l));66 else{67 if(l->l.held)68 return 0;69 l->l.held = 1;70 return 1;71 }72 }74 void75 qunlock(QLock *l)76 {77 if(_qunlock)78 (*_qunlock)(l, getcallerpc(&l));79 else80 l->l.held = 0;81 }83 void84 rlock(RWLock *l)85 {86 if(_rlock)87 (*_rlock)(l, 1, getcallerpc(&l));88 else89 l->readers++;90 }92 int93 canrlock(RWLock *l)94 {95 if(_rlock)96 return (*_rlock)(l, 0, getcallerpc(&l));97 else{98 if(l->writer)99 return 0;100 l->readers++;101 return 1;102 }103 return 1;104 }106 void107 runlock(RWLock *l)108 {109 if(_runlock)110 (*_runlock)(l, getcallerpc(&l));111 else112 l->readers--;113 }115 void116 wlock(RWLock *l)117 {118 if(_wlock)119 (*_wlock)(l, 1, getcallerpc(&l));120 else121 l->writer = (void*)1;122 }124 int125 canwlock(RWLock *l)126 {127 if(_wlock)128 return (*_wlock)(l, 0, getcallerpc(&l));129 else{130 if(l->writer || l->readers)131 return 0;132 l->writer = (void*)1;133 return 1;134 }135 }137 void138 wunlock(RWLock *l)139 {140 if(_wunlock)141 (*_wunlock)(l, getcallerpc(&l));142 else143 l->writer = nil;144 }146 void147 rsleep(Rendez *r)148 {149 if(_rsleep)150 (*_rsleep)(r, getcallerpc(&r));151 }153 int154 rwakeup(Rendez *r)155 {156 if(_rwakeup)157 return (*_rwakeup)(r, 0, getcallerpc(&r));158 return 0;159 }161 int162 rwakeupall(Rendez *r)163 {164 if(_rwakeup)165 return (*_rwakeup)(r, 1, getcallerpc(&r));166 return 0;167 }