aboutsummaryrefslogtreecommitdiff
path: root/src/lib9
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-12-26 21:51:15 +0000
committerrsc <devnull@localhost>2004-12-26 21:51:15 +0000
commit5f8fa94796903bf81db4f1dc76d433a80308b3d4 (patch)
treebc94c36965c4bf6cdb420c4c5fe628024647f88e /src/lib9
parentb2ff5382580e13d82ca48966c9d79d3318865cba (diff)
downloadplan9port-5f8fa94796903bf81db4f1dc76d433a80308b3d4.tar.gz
plan9port-5f8fa94796903bf81db4f1dc76d433a80308b3d4.tar.bz2
plan9port-5f8fa94796903bf81db4f1dc76d433a80308b3d4.zip
cleanups - lots of removed files now in thread library.
qlock.c - stubs to thread library notify.c - clean interface slightly.
Diffstat (limited to 'src/lib9')
-rw-r--r--src/lib9/ffork-Darwin.c1
-rw-r--r--src/lib9/ffork-FreeBSD.c45
-rw-r--r--src/lib9/ffork-Linux-clone.c193
-rw-r--r--src/lib9/ffork-Linux.c5
-rw-r--r--src/lib9/ffork-OpenBSD.c1
-rw-r--r--src/lib9/ffork-SunOS.c1
-rw-r--r--src/lib9/ffork-pthread.c31
-rw-r--r--src/lib9/lock-Darwin.c1
-rw-r--r--src/lib9/lock-FreeBSD.c1
-rw-r--r--src/lib9/lock-Linux.c5
-rw-r--r--src/lib9/lock-pthread.c55
-rw-r--r--src/lib9/lock-tas.c57
-rw-r--r--src/lib9/mkfile5
-rw-r--r--src/lib9/notify.c29
-rw-r--r--src/lib9/qlock.c408
-rw-r--r--src/lib9/rendez-Darwin.c2
-rw-r--r--src/lib9/rendez-FreeBSD.c1
-rw-r--r--src/lib9/rendez-Linux.c5
-rw-r--r--src/lib9/rendez-OpenBSD.c1
-rw-r--r--src/lib9/rendez-SunOS.c1
-rw-r--r--src/lib9/rendez-pthread.c23
-rw-r--r--src/lib9/rendez-signal.c64
-rw-r--r--src/lib9/rendez.c42
-rw-r--r--src/lib9/tas-386.s6
-rw-r--r--src/lib9/tas-PowerMacintosh.c42
-rw-r--r--src/lib9/tas-power.c42
-rw-r--r--src/lib9/tas-sun4u.s4
27 files changed, 113 insertions, 958 deletions
diff --git a/src/lib9/ffork-Darwin.c b/src/lib9/ffork-Darwin.c
deleted file mode 100644
index 5e677f72..00000000
--- a/src/lib9/ffork-Darwin.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "ffork-pthread.c"
diff --git a/src/lib9/ffork-FreeBSD.c b/src/lib9/ffork-FreeBSD.c
deleted file mode 100644
index 476ce7ab..00000000
--- a/src/lib9/ffork-FreeBSD.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#include <lib9.h>
-#include "9proc.h"
-
-extern int __isthreaded;
-int
-ffork(int flags, void(*fn)(void*), void *arg)
-{
- int pid;
- void *p;
-
- _p9uproc(0);
- __isthreaded = 1;
- p = malloc(16384);
- if(p == nil)
- return -1;
- memset(p, 0xFE, 16384);
- pid = rfork_thread(RFPROC|flags, (char*)p+16000, (int(*)(void*))fn, arg);
- if(pid == 0)
- _p9uproc(0);
- return pid;
-}
-
-/*
- * For FreeBSD libc.
- */
-
-typedef struct {
- volatile long access_lock;
- volatile long lock_owner;
- volatile char *fname;
- volatile int lineno;
-} spinlock_t;
-
-void
-_spinlock(spinlock_t *lk)
-{
- lock((Lock*)&lk->access_lock);
-}
-
-int
-getfforkid(void)
-{
- return getpid();
-}
-
diff --git a/src/lib9/ffork-Linux-clone.c b/src/lib9/ffork-Linux-clone.c
deleted file mode 100644
index f4704c60..00000000
--- a/src/lib9/ffork-Linux-clone.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Is nothing simple?
- *
- * We can't free the stack until we've finished executing,
- * but once we've finished executing, we can't do anything
- * at all, including call free. So instead we keep a linked list
- * of all stacks for all processes, and every few times we try
- * to allocate a new stack we scan the current stack list for
- * dead processes and reclaim those stacks.
- */
-
-#include <u.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sched.h>
-#include <signal.h>
-#include <errno.h>
-#include <libc.h>
-#include "9proc.h"
-
-int fforkstacksize = 16384;
-
-typedef struct Stack Stack;
-struct Stack
-{
- Stack *next;
- Stack *fnext;
- int pid;
-};
-
-static Lock stacklock;
-static Stack *freestacks;
-static Stack *allstacks;
-static int stackmallocs;
-static void gc(void);
-
-static void*
-mallocstack(void)
-{
- Stack *p;
-
- lock(&stacklock);
-top:
- p = freestacks;
- if(p)
- freestacks = p->fnext;
- else{
- if(stackmallocs++%1 == 0)
- gc();
- if(freestacks)
- goto top;
- p = malloc(fforkstacksize);
- p->next = allstacks;
- allstacks = p;
- }
- if(p)
- p->pid = 1;
- unlock(&stacklock);
- return p;
-}
-
-static void
-gc(void)
-{
- Stack *p;
-
- for(p=allstacks; p; p=p->next){
- if(p->pid > 1)
- if(kill(p->pid, 0) < 0 && errno == ESRCH){
- if(0) fprint(2, "reclaim stack from %d\n", p->pid);
- p->pid = 0;
- }
- if(p->pid == 0){
- p->fnext = freestacks;
- freestacks = p;
- }
- }
-}
-
-static void
-freestack(void *v)
-{
- Stack *p;
-
- p = v;
- if(p == nil)
- return;
- lock(&stacklock);
- p->fnext = freestacks;
- p->pid = 0;
- freestacks = p;
- unlock(&stacklock);
- return;
-}
-
-static int
-tramp(void *v)
-{
- void (*fn)(void*), *arg;
- void **v2;
- void *p;
-
- _p9uproc(0);
- v2 = v;
- fn = v2[0];
- arg = v2[1];
- p = v2[2];
- free(v2);
- fn(arg);
- _exit(0);
- return 0;
-}
-
-static int
-trampnowait(void *v)
-{
- int pid;
- int cloneflag;
- void **v2;
- int *pidp;
- void *p;
-
- v2 = v;
- cloneflag = (int)v2[4];
- pidp = v2[3];
- p = v2[2];
- pid = clone(tramp, p+fforkstacksize-512, cloneflag, v);
- *pidp = pid;
- _exit(0);
- return 0;
-}
-
-int
-ffork(int flags, void (*fn)(void*), void *arg)
-{
- void **v;
- char *p;
- int cloneflag, pid, thepid, status, nowait;
-
- _p9uproc(0);
- p = mallocstack();
- v = malloc(sizeof(void*)*5);
- if(p==nil || v==nil){
- freestack(p);
- free(v);
- return -1;
- }
- cloneflag = 0;
- flags &= ~RFPROC;
- if(flags&RFMEM){
- cloneflag |= CLONE_VM;
- flags &= ~RFMEM;
- }
- if(!(flags&RFFDG))
- cloneflag |= CLONE_FILES;
- else
- flags &= ~RFFDG;
- nowait = flags&RFNOWAIT;
- if(!(flags&RFNOWAIT))
- cloneflag |= SIGCHLD;
- else
- flags &= ~RFNOWAIT;
- if(flags){
- fprint(2, "unknown rfork flags %x\n", flags);
- freestack(p);
- free(v);
- return -1;
- }
- v[0] = fn;
- v[1] = arg;
- v[2] = p;
- v[3] = &thepid;
- v[4] = (void*)cloneflag;
- thepid = -1;
- pid = clone(nowait ? trampnowait : tramp, p+fforkstacksize-16, cloneflag, v);
- if(pid > 0 && nowait){
- if(wait4(pid, &status, __WALL, 0) < 0)
- fprint(2, "ffork wait4: %r\n");
- }else
- thepid = pid;
- if(thepid == -1)
- freestack(p);
- else
- ((Stack*)p)->pid = thepid;
- return thepid;
-}
-
-int
-getfforkid(void)
-{
- return getpid();
-}
-
diff --git a/src/lib9/ffork-Linux.c b/src/lib9/ffork-Linux.c
deleted file mode 100644
index b433ec4a..00000000
--- a/src/lib9/ffork-Linux.c
+++ /dev/null
@@ -1,5 +0,0 @@
-#ifdef __Linux26__
-#include "ffork-pthread.c"
-#else
-#include "ffork-Linux-clone.c"
-#endif
diff --git a/src/lib9/ffork-OpenBSD.c b/src/lib9/ffork-OpenBSD.c
deleted file mode 100644
index 5e677f72..00000000
--- a/src/lib9/ffork-OpenBSD.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "ffork-pthread.c"
diff --git a/src/lib9/ffork-SunOS.c b/src/lib9/ffork-SunOS.c
deleted file mode 100644
index 5e677f72..00000000
--- a/src/lib9/ffork-SunOS.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "ffork-pthread.c"
diff --git a/src/lib9/ffork-pthread.c b/src/lib9/ffork-pthread.c
deleted file mode 100644
index c89ad138..00000000
--- a/src/lib9/ffork-pthread.c
+++ /dev/null
@@ -1,31 +0,0 @@
-#define NOPLAN9DEFINES
-#include <u.h>
-#include <libc.h>
-#include <pthread.h>
-#include "9proc.h"
-
-extern int __isthreaded;
-int
-ffork(int flags, void(*fn)(void*), void *arg)
-{
- pthread_t tid;
-
- if(flags != (RFMEM|RFNOWAIT)){
- werrstr("ffork unsupported");
- return -1;
- }
-
- _p9uproc(0);
- if(pthread_create(&tid, NULL, (void*(*)(void*))fn, arg) < 0)
- return -1;
- if((int)tid == 0)
- _p9uproc(0);
- return (int)tid;
-}
-
-int
-getfforkid(void)
-{
- return (int)pthread_self();
-}
-
diff --git a/src/lib9/lock-Darwin.c b/src/lib9/lock-Darwin.c
deleted file mode 100644
index 231ca713..00000000
--- a/src/lib9/lock-Darwin.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "lock-pthread.c"
diff --git a/src/lib9/lock-FreeBSD.c b/src/lib9/lock-FreeBSD.c
deleted file mode 100644
index bdd48a28..00000000
--- a/src/lib9/lock-FreeBSD.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "lock-tas.c"
diff --git a/src/lib9/lock-Linux.c b/src/lib9/lock-Linux.c
deleted file mode 100644
index c25596b9..00000000
--- a/src/lib9/lock-Linux.c
+++ /dev/null
@@ -1,5 +0,0 @@
-#ifdef __Linux26__
-#include "lock-pthread.c"
-#else
-#include "lock-tas.c"
-#endif
diff --git a/src/lib9/lock-pthread.c b/src/lib9/lock-pthread.c
deleted file mode 100644
index eb3ea21d..00000000
--- a/src/lib9/lock-pthread.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include <u.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <sched.h>
-#include <errno.h>
-#include <libc.h>
-
-static pthread_mutex_t initmutex = PTHREAD_MUTEX_INITIALIZER;
-
-static void
-lockinit(Lock *lk)
-{
- pthread_mutexattr_t attr;
-
- pthread_mutex_lock(&initmutex);
- if(lk->init == 0){
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
- pthread_mutex_init(&lk->mutex, &attr);
- pthread_mutexattr_destroy(&attr);
- lk->init = 1;
- }
- pthread_mutex_unlock(&initmutex);
-}
-
-void
-lock(Lock *lk)
-{
- if(!lk->init)
- lockinit(lk);
- if(pthread_mutex_lock(&lk->mutex) != 0)
- abort();
-}
-
-int
-canlock(Lock *lk)
-{
- int r;
-
- if(!lk->init)
- lockinit(lk);
- r = pthread_mutex_trylock(&lk->mutex);
- if(r == 0)
- return 1;
- if(r == EBUSY)
- return 0;
- abort();
-}
-
-void
-unlock(Lock *lk)
-{
- if(pthread_mutex_unlock(&lk->mutex) != 0)
- abort();
-}
diff --git a/src/lib9/lock-tas.c b/src/lib9/lock-tas.c
deleted file mode 100644
index e6f54de6..00000000
--- a/src/lib9/lock-tas.c
+++ /dev/null
@@ -1,57 +0,0 @@
-#include <u.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <sched.h>
-#include <libc.h>
-
-int _ntas;
-static int
-_xtas(void *v)
-{
- int x;
-
- _ntas++;
- x = _tas(v);
- if(x != 0 && x != 0xcafebabe){
- print("bad tas value %d\n", x);
- abort();
- }
- return x;
-}
-
-int
-canlock(Lock *l)
-{
- return !_xtas(&l->val);
-}
-
-void
-unlock(Lock *l)
-{
- l->val = 0;
-}
-
-void
-lock(Lock *lk)
-{
- int i;
-
- /* once fast */
- if(!_xtas(&lk->val))
- return;
- /* a thousand times pretty fast */
- for(i=0; i<1000; i++){
- if(!_xtas(&lk->val))
- return;
- sched_yield();
- }
- /* now nice and slow */
- for(i=0; i<1000; i++){
- if(!_xtas(&lk->val))
- return;
- usleep(100*1000);
- }
- /* take your time */
- while(_xtas(&lk->val))
- usleep(1000*1000);
-}
diff --git a/src/lib9/mkfile b/src/lib9/mkfile
index 133fcf41..0c1c3027 100644
--- a/src/lib9/mkfile
+++ b/src/lib9/mkfile
@@ -108,7 +108,6 @@ LIB9OFILES=\
jmp.$O\
lrand.$O\
lnrand.$O\
- lock-$SYSNAME.$O\
main.$O\
malloc.$O\
malloctag.$O\
@@ -129,7 +128,6 @@ LIB9OFILES=\
quote.$O\
read9pmsg.$O\
readn.$O\
- rendez-$SYSNAME.$O\
rfork.$O\
seek.$O\
sendfd.$O\
@@ -138,7 +136,6 @@ LIB9OFILES=\
strecpy.$O\
sysfatal.$O\
sysname.$O\
- tas-$OBJTYPE.$O\
time.$O\
tokenize.$O\
truerand.$O\
@@ -164,5 +161,3 @@ HFILES=\
%.$O: utf/%.c
$CC $CFLAGS utf/$stem.c
-
-rendez-Linux.$O: rendez-signal.c
diff --git a/src/lib9/notify.c b/src/lib9/notify.c
index 2b95e099..faf13928 100644
--- a/src/lib9/notify.c
+++ b/src/lib9/notify.c
@@ -7,9 +7,9 @@
* There is no equivalent note to Unix's SIGKILL, since
* it's not a deliverable signal anyway.
*
- * We do not handle SIGABRT or SIGSEGV, mainly so that
- * stack traces show the original source of the signal instead
- * of notifysigf.
+ * We do not handle SIGABRT or SIGSEGV, mainly because
+ * the thread library queues its notes for later, and we want
+ * to dump core with the state at time of delivery.
*
* We have to add some extra entry points to provide the
* ability to tweak which signals are deliverable and which
@@ -112,7 +112,6 @@ static void (*notifyf)(void*, char*); /* Plan 9 handler */
static void
signotify(int sig)
{
- int v;
char tmp[64];
Jmp *j;
@@ -150,7 +149,6 @@ noted(int v)
int
notify(void (*f)(void*, char*))
{
- int i;
static int init;
notifyf = f;
@@ -164,7 +162,8 @@ notify(void (*f)(void*, char*))
/*
* Nonsense about enabling and disabling signals.
*/
-static void(*)(int)
+typedef void Sighandler(int);
+static Sighandler*
handler(int s)
{
struct sigaction sa;
@@ -174,7 +173,7 @@ handler(int s)
}
static void
-notifysetenable(int sig, int enabled)
+notesetenable(int sig, int enabled)
{
sigset_t mask;
@@ -187,15 +186,15 @@ notifysetenable(int sig, int enabled)
}
void
-notifyenable(char *msg)
+noteenable(char *msg)
{
- notifyenablex(_p9strsig(msg), 1);
+ notesetenable(_p9strsig(msg), 1);
}
void
-notifydisable(char *msg)
+notedisable(char *msg)
{
- notifyenablex(_p9strsig(msg), 0);
+ notesetenable(_p9strsig(msg), 0);
}
static void
@@ -207,7 +206,8 @@ notifyseton(int s, int on)
sig = findsig(s);
if(sig == nil)
return;
- notifyenable(msg);
+ if(on)
+ notesetenable(s, 1);
memset(&sa, 0, sizeof sa);
sa.sa_handler = on ? signotify : signonotify;
if(sig->restart)
@@ -234,7 +234,7 @@ notifyon(char *msg)
void
notifyoff(char *msg)
{
- notifysetoff(_p9strsig(msg), 0);
+ notifyseton(_p9strsig(msg), 0);
}
/*
@@ -252,6 +252,7 @@ noteinit(void)
* If someone has already installed a handler,
* It's probably some ld preload nonsense,
* like pct (a SIGVTALRM-based profiler).
+ * Or maybe someone has already called notifyon/notifyoff.
* Leave it alone.
*/
if(handler(sig->sig) != SIG_DFL)
@@ -261,7 +262,7 @@ noteinit(void)
* (I.e. if parent has disabled for us, should we still enable?)
* Right now we always initialize to the state we want.
*/
- notifysetenable(sig->sig, sig->enabled);
+ notesetenable(sig->sig, sig->enabled);
notifyseton(sig->sig, sig->notified);
}
}
diff --git a/src/lib9/qlock.c b/src/lib9/qlock.c
index 0eacccd7..a979c443 100644
--- a/src/lib9/qlock.c
+++ b/src/lib9/qlock.c
@@ -1,379 +1,167 @@
-#include <lib9.h>
+#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);
-static struct {
- QLp *p;
- QLp x[1024];
-} ql = {
- ql.x
-};
-
-enum
-{
- Queuing,
- QueuingR,
- QueuingW,
- Sleeping,
- Waking,
-};
-
-static void (*procsleep)(_Procrend*) = _procsleep;
-static void (*procwakeup)(_Procrend*) = _procwakeup;
-#define _procsleep donotcall_procsleep
-#define _procwakeup donotcall_procwakeup
-
-/* this gets called by the thread library ONLY to get us to use its rendezvous */
void
-_qlockinit(void (*sleep)(_Procrend*), void (*wakeup)(_Procrend*))
+lock(Lock *l)
{
- procsleep = sleep;
- procwakeup = wakeup;
+ if(_lock)
+ (*_lock)(l, 1, getcallerpc(&l));
+ else
+ l->held = 1;
}
-/* find a free shared memory location to queue ourselves in */
-static QLp*
-getqlp(void)
+int
+canlock(Lock *l)
{
- QLp *p, *op;
-
- op = ql.p;
- for(p = op+1; ; p++){
- if(p == &ql.x[nelem(ql.x)])
- p = ql.x;
- if(p == op){
- fprint(2, "qlock: out of qlp\n");
- abort();
- }
- if(canlock(&p->inuse)){
- ql.p = p;
- p->next = nil;
- break;
- }
+ if(_lock)
+ return (*_lock)(l, 0, getcallerpc(&l));
+ else{
+ if(l->held)
+ return 0;
+ l->held = 1;
+ return 1;
}
- return p;
}
void
-qlock(QLock *q)
+unlock(Lock *l)
{
- QLp *p, *mp;
-
- lock(&q->lock);
- if(!q->locked){
- q->locked = 1;
- unlock(&q->lock);
- return;
- }
-
-
- /* chain into waiting list */
- mp = getqlp();
- p = q->tail;
- if(p == nil)
- q->head = mp;
+ if(_unlock)
+ (*_unlock)(l, getcallerpc(&l));
else
- p->next = mp;
- q->tail = mp;
- mp->state = Queuing;
- mp->rend.l = &q->lock;
- procsleep(&mp->rend);
- unlock(&q->lock);
- assert(mp->state == Waking);
- unlock(&mp->inuse);
+ l->held = 0;
}
void
-qunlock(QLock *q)
+qlock(QLock *l)
{
- QLp *p;
-
- lock(&q->lock);
- p = q->head;
- if(p != nil){
- /* wakeup head waiting process */
- q->head = p->next;
- if(q->head == nil)
- q->tail = nil;
- p->state = Waking;
- procwakeup(&p->rend);
- unlock(&q->lock);
- return;
- }
- q->locked = 0;
- unlock(&q->lock);
+ if(_qlock)
+ (*_qlock)(l, 1, getcallerpc(&l));
+ else
+ l->l.held = 1;
}
int
-canqlock(QLock *q)
+canqlock(QLock *l)
{
- if(!canlock(&q->lock))
- return 0;
- if(!q->locked){
- q->locked = 1;
- unlock(&q->lock);
+ if(_qlock)
+ return (*_qlock)(l, 0, getcallerpc(&l));
+ else{
+ if(l->l.held)
+ return 0;
+ l->l.held = 1;
return 1;
}
- unlock(&q->lock);
- return 0;
}
void
-rlock(RWLock *q)
+qunlock(QLock *l)
{
- QLp *p, *mp;
-
- lock(&q->lock);
- if(q->writer == 0 && q->head == nil){
- /* no writer, go for it */
- q->readers++;
- unlock(&q->lock);
- return;
- }
+ if(_qunlock)
+ (*_qunlock)(l, getcallerpc(&l));
+ else
+ l->l.held = 0;
+}
- mp = getqlp();
- p = q->tail;
- if(p == 0)
- q->head = mp;
+void
+rlock(RWLock *l)
+{
+ if(_rlock)
+ (*_rlock)(l, 1, getcallerpc(&l));
else
- p->next = mp;
- q->tail = mp;
- mp->next = nil;
- mp->state = QueuingR;
- mp->rend.l = &q->lock;
- procsleep(&mp->rend);
- unlock(&q->lock);
- assert(mp->state == Waking);
- unlock(&mp->inuse);
+ l->readers++;
}
int
-canrlock(RWLock *q)
+canrlock(RWLock *l)
{
- lock(&q->lock);
- if (q->writer == 0 && q->head == nil) {
- /* no writer; go for it */
- q->readers++;
- unlock(&q->lock);
+ if(_rlock)
+ return (*_rlock)(l, 0, getcallerpc(&l));
+ else{
+ if(l->writer)
+ return 0;
+ l->readers++;
return 1;
}
- unlock(&q->lock);
- return 0;
+ return 1;
}
void
-runlock(RWLock *q)
+runlock(RWLock *l)
{
- QLp *p;
-
- lock(&q->lock);
- if(q->readers <= 0)
- abort();
- p = q->head;
- if(--(q->readers) > 0 || p == nil){
- unlock(&q->lock);
- return;
- }
-
- /* start waiting writer */
- if(p->state != QueuingW)
- abort();
- q->head = p->next;
- if(q->head == 0)
- q->tail = 0;
- q->writer = 1;
-
- /* wakeup waiter */
- p->state = Waking;
- procwakeup(&p->rend);
- unlock(&q->lock);
+ if(_runlock)
+ (*_runlock)(l, getcallerpc(&l));
+ else
+ l->readers--;
}
void
-wlock(RWLock *q)
+wlock(RWLock *l)
{
- QLp *p, *mp;
-
- lock(&q->lock);
- if(q->readers == 0 && q->writer == 0){
- /* noone waiting, go for it */
- q->writer = 1;
- unlock(&q->lock);
- return;
- }
-
- /* wait */
- p = q->tail;
- mp = getqlp();
- if(p == nil)
- q->head = mp;
+ if(_wlock)
+ (*_wlock)(l, 1, getcallerpc(&l));
else
- p->next = mp;
- q->tail = mp;
- mp->next = nil;
- mp->state = QueuingW;
-
- /* wait in kernel */
- mp->rend.l = &q->lock;
- procsleep(&mp->rend);
- unlock(&q->lock);
- assert(mp->state == Waking);
- unlock(&mp->inuse);
+ l->writer = (void*)1;
}
int
-canwlock(RWLock *q)
+canwlock(RWLock *l)
{
- lock(&q->lock);
- if (q->readers == 0 && q->writer == 0) {
- /* no one waiting; go for it */
- q->writer = 1;
- unlock(&q->lock);
+ if(_wlock)
+ return (*_wlock)(l, 0, getcallerpc(&l));
+ else{
+ if(l->writer || l->readers)
+ return 0;
+ l->writer = (void*)1;
return 1;
}
- unlock(&q->lock);
- return 0;
}
void
-wunlock(RWLock *q)
+wunlock(RWLock *l)
{
- QLp *p;
-
- lock(&q->lock);
- if(q->writer == 0){
- fprint(2, "wunlock: not holding lock\n");
- abort();
- }
- p = q->head;
- if(p == nil){
- q->writer = 0;
- unlock(&q->lock);
- return;
- }
- if(p->state == QueuingW){
- /* start waiting writer */
- q->head = p->next;
- if(q->head == nil)
- q->tail = nil;
- p->state = Waking;
- procwakeup(&p->rend);
- unlock(&q->lock);
- return;
- }
-
- if(p->state != QueuingR){
- fprint(2, "wunlock: bad state\n");
- abort();
- }
-
- /* wake waiting readers */
- while(q->head != nil && q->head->state == QueuingR){
- p = q->head;
- q->head = p->next;
- q->readers++;
- p->state = Waking;
- procwakeup(&p->rend);
- }
- if(q->head == nil)
- q->tail = nil;
- q->writer = 0;
- unlock(&q->lock);
+ if(_wunlock)
+ (*_wunlock)(l, getcallerpc(&l));
+ else
+ l->writer = nil;
}
void
rsleep(Rendez *r)
{
- QLp *t, *me;
-
- if(!r->l){
- fprint(2, "rsleep: no lock\n");
- abort();
- }
- lock(&r->l->lock);
- /* we should hold the qlock */
- if(!r->l->locked){
- fprint(2, "rsleep: not locked\n");
- abort();
- }
-
- /* add ourselves to the wait list */
- me = getqlp();
- me->state = Sleeping;
- if(r->head == nil)
- r->head = me;
- else
- r->tail->next = me;
- me->next = nil;
- r->tail = me;
-
- /* pass the qlock to the next guy */
- t = r->l->head;
- if(t){
- r->l->head = t->next;
- if(r->l->head == nil)
- r->l->tail = nil;
- t->state = Waking;
- procwakeup(&t->rend);
- }else
- r->l->locked = 0;
-
- /* wait for a wakeup */
- me->rend.l = &r->l->lock;
- procsleep(&me->rend);
- assert(me->state == Waking);
- unlock(&me->inuse);
- if(!r->l->locked){
- fprint(2, "rsleep: not locked after wakeup\n");
- abort();
- }
- unlock(&r->l->lock);
+ if(_rsleep)
+ (*_rsleep)(r, getcallerpc(&r));
}
int
rwakeup(Rendez *r)
{
- QLp *t;
-
- /*
- * take off wait and put on front of queue
- * put on front so guys that have been waiting will not get starved
- */
-
- if(!r->l){
- fprint(2, "rwakeup: no lock\n");
- abort();
- }
- lock(&r->l->lock);
- if(!r->l->locked){
- fprint(2, "rwakeup: not locked\n");
- abort();
- }
-
- t = r->head;
- if(t == nil){
- unlock(&r->l->lock);
- return 0;
- }
-
- r->head = t->next;
- if(r->head == nil)
- r->tail = nil;
-
- t->next = r->l->head;
- r->l->head = t;
- if(r->l->tail == nil)
- r->l->tail = t;
-
- t->state = Queuing;
- unlock(&r->l->lock);
- return 1;
+ if(_rwakeup)
+ return (*_rwakeup)(r, 0, getcallerpc(&r));
+ return 0;
}
int
rwakeupall(Rendez *r)
{
- int i;
-
- for(i=0; rwakeup(r); i++)
- ;
- return i;
+ if(_rwakeup)
+ return (*_rwakeup)(r, 1, getcallerpc(&r));
+ return 0;
}
diff --git a/src/lib9/rendez-Darwin.c b/src/lib9/rendez-Darwin.c
deleted file mode 100644
index 2f099fc4..00000000
--- a/src/lib9/rendez-Darwin.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "rendez-pthread.c"
-
diff --git a/src/lib9/rendez-FreeBSD.c b/src/lib9/rendez-FreeBSD.c
deleted file mode 100644
index 05c52ae7..00000000
--- a/src/lib9/rendez-FreeBSD.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "rendez-signal.c"
diff --git a/src/lib9/rendez-Linux.c b/src/lib9/rendez-Linux.c
deleted file mode 100644
index c86fb5b5..00000000
--- a/src/lib9/rendez-Linux.c
+++ /dev/null
@@ -1,5 +0,0 @@
-#ifdef __Linux26__
-#include "rendez-pthread.c"
-#else
-#include "rendez-signal.c"
-#endif
diff --git a/src/lib9/rendez-OpenBSD.c b/src/lib9/rendez-OpenBSD.c
deleted file mode 100644
index 05c52ae7..00000000
--- a/src/lib9/rendez-OpenBSD.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "rendez-signal.c"
diff --git a/src/lib9/rendez-SunOS.c b/src/lib9/rendez-SunOS.c
deleted file mode 100644
index eabb9a75..00000000
--- a/src/lib9/rendez-SunOS.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "rendez-pthread.c"
diff --git a/src/lib9/rendez-pthread.c b/src/lib9/rendez-pthread.c
deleted file mode 100644
index 2d08e0c3..00000000
--- a/src/lib9/rendez-pthread.c
+++ /dev/null
@@ -1,23 +0,0 @@
-#include <u.h>
-#include <pthread.h>
-#include <libc.h>
-
-void
-_procsleep(_Procrend *rend)
-{
-//print("sleep %p %d\n", rend, getpid());
- pthread_cond_init(&rend->cond, 0);
- rend->asleep = 1;
- while(rend->asleep)
- pthread_cond_wait(&rend->cond, &rend->l->mutex);
- pthread_cond_destroy(&rend->cond);
-}
-
-void
-_procwakeup(_Procrend *rend)
-{
-//print("wakeup %p\n", rend);
- rend->asleep = 0;
- pthread_cond_signal(&rend->cond);
-}
-
diff --git a/src/lib9/rendez-signal.c b/src/lib9/rendez-signal.c
deleted file mode 100644
index 744a8fc8..00000000
--- a/src/lib9/rendez-signal.c
+++ /dev/null
@@ -1,64 +0,0 @@
-#include <u.h>
-#include <signal.h>
-#include <libc.h>
-
-#define DBG 0
-
-static void
-ign(int x)
-{
- USED(x);
-}
-
-void /*__attribute__((constructor))*/
-ignusr1(int restart)
-{
- struct sigaction sa;
-
- memset(&sa, 0, sizeof sa);
- sa.sa_handler = ign;
- sigemptyset(&sa.sa_mask);
- sigaddset(&sa.sa_mask, SIGUSR1);
- if(restart)
- sa.sa_flags = SA_RESTART;
- sigaction(SIGUSR1, &sa, nil);
-}
-
-void
-_procsleep(_Procrend *r)
-{
- sigset_t mask;
-
- /*
- * Go to sleep.
- *
- * Block USR1, set the handler to interrupt system calls,
- * unlock the vouslock so our waker can wake us,
- * and then suspend.
- */
- r->asleep = 1;
- r->pid = getpid();
-
- sigprocmask(SIG_SETMASK, nil, &mask);
- sigaddset(&mask, SIGUSR1);
- sigprocmask(SIG_SETMASK, &mask, nil);
- ignusr1(0);
- unlock(r->l);
- sigdelset(&mask, SIGUSR1);
- sigsuspend(&mask);
-
- /*
- * We're awake. Make USR1 not interrupt system calls.
- */
- ignusr1(1);
- assert(r->asleep == 0);
- lock(r->l);
-}
-
-void
-_procwakeup(_Procrend *r)
-{
- r->asleep = 0;
- assert(r->pid >= 1);
- kill(r->pid, SIGUSR1);
-}
diff --git a/src/lib9/rendez.c b/src/lib9/rendez.c
deleted file mode 100644
index 2b2c1a19..00000000
--- a/src/lib9/rendez.c
+++ /dev/null
@@ -1,42 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include "9proc.h"
-
-static Lock rendlock;
-static Uproc *rendhash[RENDHASH];
-
-ulong
-rendezvous(ulong tag, ulong val)
-{
- char c;
- ulong ret;
- Uproc *t, *self, **l;
-
- self = _p9uproc(0);
- lock(&rendlock);
- l = &rendhash[tag%RENDHASH];
- for(t=*l; t; l=&t->rendhash, t=*l){
- if(t->rendtag==tag){
- *l = t->rendhash;
- ret = t->rendval;
- t->rendval = val;
- t->rendtag++;
- c = 0;
- unlock(&rendlock);
- write(t->pipe[1], &c, 1);
- return ret;
- }
- }
-
- /* Going to sleep here. */
- t = self;
- t->rendtag = tag;
- t->rendval = val;
- t->rendhash = *l;
- *l = t;
- unlock(&rendlock);
- do
- read(t->pipe[0], &c, 1);
- while(t->rendtag == tag);
- return t->rendval;
-}
diff --git a/src/lib9/tas-386.s b/src/lib9/tas-386.s
deleted file mode 100644
index 7a62d2d3..00000000
--- a/src/lib9/tas-386.s
+++ /dev/null
@@ -1,6 +0,0 @@
-.globl _tas
-_tas:
- movl $0xCAFEBABE, %eax
- movl 4(%esp), %ecx
- xchgl %eax, 0(%ecx)
- ret
diff --git a/src/lib9/tas-PowerMacintosh.c b/src/lib9/tas-PowerMacintosh.c
deleted file mode 100644
index d7a8610c..00000000
--- a/src/lib9/tas-PowerMacintosh.c
+++ /dev/null
@@ -1,42 +0,0 @@
-#include "u.h"
-#include "libc.h"
-
-/*
- * first argument (l) is in r3 at entry.
- * r3 contains return value upon return.
- */
-int
-_tas(int *x)
-{
- int v;
- /*
- * this __asm__ works with gcc 2.95.2 (mac os x 10.1).
- * this assembly language destroys r0 (0), some other register (v),
- * r4 (x) and r5 (temp).
- */
- __asm__("\n sync\n"
- " li r0,0\n"
- " mr r4,%1 /* &l->val */\n"
- " lis r5,0xdead /* assemble constant 0xdeaddead */\n"
- " ori r5,r5,0xdead /* \" */\n"
- "tas1:\n"
- " dcbf r4,r0 /* cache flush; \"fix for 603x bug\" */\n"
- " lwarx %0,r4,r0 /* v = l->val with reservation */\n"
- " cmp cr0,0,%0,r0 /* v == 0 */\n"
- " bne tas0\n"
- " stwcx. r5,r4,r0 /* if (l->val same) l->val = 0xdeaddead */\n"
- " bne tas1\n"
- "tas0:\n"
- " sync\n"
- " isync\n"
- : "=r" (v)
- : "r" (x)
- : "cc", "memory", "r0", "r4", "r5"
- );
- switch(v) {
- case 0: return 0;
- case 0xdeaddead: return 1;
- default: fprint(2, "tas: corrupted 0x%lux\n", v);
- }
- return 0;
-}
diff --git a/src/lib9/tas-power.c b/src/lib9/tas-power.c
deleted file mode 100644
index 2ed71d47..00000000
--- a/src/lib9/tas-power.c
+++ /dev/null
@@ -1,42 +0,0 @@
-#include "u.h"
-#include "libc.h"
-
-/*
- * first argument (l) is in r3 at entry.
- * r3 contains return value upon return.
- */
-int
-_tas(int *x)
-{
- int v;
- int tmp, tmp2, tmp3;
-
- /*
- * this __asm__ works with gcc on linux
- */
- __asm__("\n sync\n"
- " li %1,0\n"
- " mr %2,%4 /* &x->val */\n"
- " lis %3,0xdead /* assemble constant 0xdeaddead */\n"
- " ori %3,%3,0xdead /* \" */\n"
- "tas1:\n"
- " dcbf %2,%1 /* cache flush; \"fix for 603x bug\" */\n"
- " lwarx %0,%2,%1 /* v = x->val with reservation */\n"
- " cmp cr0,0,%0,%1 /* v == 0 */\n"
- " bne tas0\n"
- " stwcx. %3,%2,%1 /* if (x->val same) x->val = 0xdeaddead */\n"
- " bne tas1\n"
- "tas0:\n"
- " sync\n"
- " isync\n"
- : "=r" (v), "=&r" (tmp), "=&r"(tmp2), "=&r"(tmp3)
- : "r" (x)
- : "cr0", "memory"
- );
- switch(v) {
- case 0: return 0;
- case 0xdeaddead: return 1;
- default: fprint(2, "tas: corrupted 0x%lux\n", v);
- }
- return 0;
-}
diff --git a/src/lib9/tas-sun4u.s b/src/lib9/tas-sun4u.s
deleted file mode 100644
index b960a26a..00000000
--- a/src/lib9/tas-sun4u.s
+++ /dev/null
@@ -1,4 +0,0 @@
-.globl _tas
-_tas:
- retl
- ldstub [%o0], %o0