9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | 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 }