qlock.c - 9base - revived minimalist port of Plan 9 userland to Unix
 (HTM) git clone git://git.suckless.org/9base
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       qlock.c (2268B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 
            4 /*
            5  * The function pointers are supplied by the thread
            6  * library during its initialization.  If there is no thread
            7  * library, there is no multithreading.
            8  */
            9 
           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);
           20 
           21 void
           22 lock(Lock *l)
           23 {
           24         if(_lock)
           25                 (*_lock)(l, 1, getcallerpc(&l));
           26         else
           27                 l->held = 1;
           28 }
           29 
           30 int
           31 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 }
           42 
           43 void
           44 unlock(Lock *l)
           45 {
           46         if(_unlock)
           47                 (*_unlock)(l, getcallerpc(&l));
           48         else
           49                 l->held = 0;
           50 }
           51 
           52 void
           53 qlock(QLock *l)
           54 {
           55         if(_qlock)
           56                 (*_qlock)(l, 1, getcallerpc(&l));
           57         else
           58                 l->l.held = 1;
           59 }
           60 
           61 int
           62 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 }
           73 
           74 void
           75 qunlock(QLock *l)
           76 {
           77         if(_qunlock)
           78                 (*_qunlock)(l, getcallerpc(&l));
           79         else
           80                 l->l.held = 0;
           81 }
           82 
           83 void
           84 rlock(RWLock *l)
           85 {
           86         if(_rlock)
           87                 (*_rlock)(l, 1, getcallerpc(&l));
           88         else
           89                 l->readers++;
           90 }
           91 
           92 int
           93 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 }
          104 
          105 void
          106 runlock(RWLock *l)
          107 {
          108         if(_runlock)
          109                 (*_runlock)(l, getcallerpc(&l));
          110         else
          111                 l->readers--;
          112 }
          113 
          114 void
          115 wlock(RWLock *l)
          116 {
          117         if(_wlock)
          118                 (*_wlock)(l, 1, getcallerpc(&l));
          119         else
          120                 l->writer = (void*)1;
          121 }
          122 
          123 int
          124 canwlock(RWLock *l)
          125 {
          126         if(_wlock)
          127                 return (*_wlock)(l, 0, getcallerpc(&l));
          128         else{
          129                 if(l->writer || l->readers)
          130                         return 0;
          131                 l->writer = (void*)1;
          132                 return 1;
          133         }
          134 }
          135 
          136 void
          137 wunlock(RWLock *l)
          138 {
          139         if(_wunlock)
          140                 (*_wunlock)(l, getcallerpc(&l));
          141         else
          142                 l->writer = nil;
          143 }
          144 
          145 void
          146 rsleep(Rendez *r)
          147 {
          148         if(_rsleep)
          149                 (*_rsleep)(r, getcallerpc(&r));
          150 }
          151 
          152 int
          153 rwakeup(Rendez *r)
          154 {
          155         if(_rwakeup)
          156                 return (*_rwakeup)(r, 0, getcallerpc(&r));
          157         return 0;
          158 }
          159 
          160 int
          161 rwakeupall(Rendez *r)
          162 {
          163         if(_rwakeup)
          164                 return (*_rwakeup)(r, 1, getcallerpc(&r));
          165         return 0;
          166 }