mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-12 11:10:07 +00:00
166 lines
2.2 KiB
C
166 lines
2.2 KiB
C
#include <u.h>
|
|
#include <libc.h>
|
|
|
|
/*
|
|
* The function pointers are supplied by the thread
|
|
* library during its initialization. If there is no thread
|
|
* library, there is no multithreading.
|
|
*/
|
|
|
|
int (*_lock)(Lock*, int, ulong);
|
|
void (*_unlock)(Lock*, ulong);
|
|
int (*_qlock)(QLock*, int, ulong); /* do not use */
|
|
void (*_qunlock)(QLock*, ulong);
|
|
void (*_rsleep)(Rendez*, ulong); /* do not use */
|
|
int (*_rwakeup)(Rendez*, int, ulong);
|
|
int (*_rlock)(RWLock*, int, ulong); /* do not use */
|
|
int (*_wlock)(RWLock*, int, ulong);
|
|
void (*_runlock)(RWLock*, ulong);
|
|
void (*_wunlock)(RWLock*, ulong);
|
|
|
|
void
|
|
lock(Lock *l)
|
|
{
|
|
if(_lock)
|
|
(*_lock)(l, 1, getcallerpc(&l));
|
|
else
|
|
l->held = 1;
|
|
}
|
|
|
|
int
|
|
canlock(Lock *l)
|
|
{
|
|
if(_lock)
|
|
return (*_lock)(l, 0, getcallerpc(&l));
|
|
else{
|
|
if(l->held)
|
|
return 0;
|
|
l->held = 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
void
|
|
unlock(Lock *l)
|
|
{
|
|
if(_unlock)
|
|
(*_unlock)(l, getcallerpc(&l));
|
|
else
|
|
l->held = 0;
|
|
}
|
|
|
|
void
|
|
qlock(QLock *l)
|
|
{
|
|
if(_qlock)
|
|
(*_qlock)(l, 1, getcallerpc(&l));
|
|
else
|
|
l->l.held = 1;
|
|
}
|
|
|
|
int
|
|
canqlock(QLock *l)
|
|
{
|
|
if(_qlock)
|
|
return (*_qlock)(l, 0, getcallerpc(&l));
|
|
else{
|
|
if(l->l.held)
|
|
return 0;
|
|
l->l.held = 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
void
|
|
qunlock(QLock *l)
|
|
{
|
|
if(_qunlock)
|
|
(*_qunlock)(l, getcallerpc(&l));
|
|
else
|
|
l->l.held = 0;
|
|
}
|
|
|
|
void
|
|
rlock(RWLock *l)
|
|
{
|
|
if(_rlock)
|
|
(*_rlock)(l, 1, getcallerpc(&l));
|
|
else
|
|
l->readers++;
|
|
}
|
|
|
|
int
|
|
canrlock(RWLock *l)
|
|
{
|
|
if(_rlock)
|
|
return (*_rlock)(l, 0, getcallerpc(&l));
|
|
else{
|
|
if(l->writer)
|
|
return 0;
|
|
l->readers++;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
void
|
|
runlock(RWLock *l)
|
|
{
|
|
if(_runlock)
|
|
(*_runlock)(l, getcallerpc(&l));
|
|
else
|
|
l->readers--;
|
|
}
|
|
|
|
void
|
|
wlock(RWLock *l)
|
|
{
|
|
if(_wlock)
|
|
(*_wlock)(l, 1, getcallerpc(&l));
|
|
else
|
|
l->writer = (void*)1;
|
|
}
|
|
|
|
int
|
|
canwlock(RWLock *l)
|
|
{
|
|
if(_wlock)
|
|
return (*_wlock)(l, 0, getcallerpc(&l));
|
|
else{
|
|
if(l->writer || l->readers)
|
|
return 0;
|
|
l->writer = (void*)1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
void
|
|
wunlock(RWLock *l)
|
|
{
|
|
if(_wunlock)
|
|
(*_wunlock)(l, getcallerpc(&l));
|
|
else
|
|
l->writer = nil;
|
|
}
|
|
|
|
void
|
|
rsleep(Rendez *r)
|
|
{
|
|
if(_rsleep)
|
|
(*_rsleep)(r, getcallerpc(&r));
|
|
}
|
|
|
|
int
|
|
rwakeup(Rendez *r)
|
|
{
|
|
if(_rwakeup)
|
|
return (*_rwakeup)(r, 0, getcallerpc(&r));
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
rwakeupall(Rendez *r)
|
|
{
|
|
if(_rwakeup)
|
|
return (*_rwakeup)(r, 1, getcallerpc(&r));
|
|
return 0;
|
|
}
|