aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/u.h6
-rw-r--r--src/libthread/BSD.c403
-rw-r--r--src/libthread/FreeBSD-386-asm.s52
-rw-r--r--src/libthread/FreeBSD.c34
-rw-r--r--src/libthread/OpenBSD-386-asm.s53
-rw-r--r--src/libthread/mkfile1
-rw-r--r--src/libthread/threadimpl.h9
7 files changed, 54 insertions, 504 deletions
diff --git a/include/u.h b/include/u.h
index d0cd6396..8a715b1e 100644
--- a/include/u.h
+++ b/include/u.h
@@ -86,10 +86,8 @@ typedef long p9jmp_buf[sizeof(sigjmp_buf)/sizeof(long)];
#elif defined(__FreeBSD__)
# include <sys/types.h>
# include <osreldate.h>
-# if __FreeBSD_version >= 500000
-# define PLAN9PORT_USING_PTHREADS 1
-# include <pthread.h>
-# endif
+# define PLAN9PORT_USING_PTHREADS 1
+# include <pthread.h>
# if !defined(_POSIX_SOURCE)
# undef _NEEDUSHORT
# undef _NEEDUINT
diff --git a/src/libthread/BSD.c b/src/libthread/BSD.c
deleted file mode 100644
index 737c0a63..00000000
--- a/src/libthread/BSD.c
+++ /dev/null
@@ -1,403 +0,0 @@
-#undef exits
-#undef _exits
-
-extern int __isthreaded;
-
-/*
- * spin locks
- */
-extern int _tas(int*);
-
-void
-_threadunlock(Lock *l, ulong pc)
-{
- USED(pc);
-
- l->held = 0;
-}
-
-int
-_threadlock(Lock *l, int block, ulong pc)
-{
- int i;
-
- USED(pc);
-
- /* once fast */
- if(!_tas(&l->held))
- return 1;
- if(!block)
- return 0;
-
- /* a thousand times pretty fast */
- for(i=0; i<1000; i++){
- if(!_tas(&l->held))
- return 1;
- sleep(0);
- }
- /* increasingly slow */
- for(i=0; i<10; i++){
- if(!_tas(&l->held))
- return 1;
- usleep(1);
- }
- for(i=0; i<10; i++){
- if(!_tas(&l->held))
- return 1;
- usleep(10);
- }
- for(i=0; i<10; i++){
- if(!_tas(&l->held))
- return 1;
- usleep(100);
- }
- for(i=0; i<10; i++){
- if(!_tas(&l->held))
- return 1;
- usleep(1000);
- }
- for(i=0; i<10; i++){
- if(!_tas(&l->held))
- return 1;
- usleep(10*1000);
- }
- /* now nice and slow */
- for(i=0; i<1000; i++){
- if(!_tas(&l->held))
- return 1;
- usleep(100*1000);
- }
- /* take your time */
- while(_tas(&l->held))
- usleep(1000*1000);
- return 1;
-}
-
-/*
- * For 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);
-}
-
-void
-_spinunlock(spinlock_t *lk)
-{
- unlock((Lock*)&lk->access_lock);
-}
-
-
-
-/*
- * sleep and wakeup
- */
-static void
-ign(int x)
-{
- USED(x);
-}
-
-static 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(_Procrendez *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.
- */
-again:
- 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.
- */
- lock(r->l);
- ignusr1(1);
- if(r->asleep && r->pid == getpid()){
- /* Didn't really wake up - signal from something else */
- goto again;
- }
-}
-
-void
-_procwakeup(_Procrendez *r)
-{
- if(r->asleep){
- r->asleep = 0;
- assert(r->pid >= 1);
- kill(r->pid, SIGUSR1);
- }
-}
-
-void
-_procwakeupandunlock(_Procrendez *r)
-{
- _procwakeup(r);
- unlock(r->l);
-}
-
-
-/*
- * process creation and exit
- */
-typedef struct Stackfree Stackfree;
-struct Stackfree
-{
- Stackfree *next;
- int pid;
-};
-static Lock stacklock;
-static Stackfree *stackfree;
-
-static void
-delayfreestack(uchar *stk)
-{
- Stackfree *sf;
-
- sf = (Stackfree*)stk;
- sf->pid = getpid();
- lock(&stacklock);
- sf->next = stackfree;
- stackfree = sf;
- unlock(&stacklock);
-}
-
-static void
-dofreestacks(void)
-{
- Stackfree *sf, *last, *next;
-
- if(stackfree==nil || !canlock(&stacklock))
- return;
-
- for(last=nil,sf=stackfree; sf; last=sf,sf=next){
- next = sf->next;
- if(sf->pid >= 1 && kill(sf->pid, 0) < 0 && errno == ESRCH){
- free(sf);
- if(last)
- last->next = next;
- else
- stackfree = next;
- sf = last;
- }
- }
- unlock(&stacklock);
-}
-
-static int
-startprocfn(void *v)
-{
- void **a;
- uchar *stk;
- void (*fn)(void*);
- Proc *p;
-
- a = (void**)v;
- fn = a[0];
- p = a[1];
- stk = a[2];
- free(a);
- p->osprocid = getpid();
-
- (*fn)(p);
-
- delayfreestack(stk);
- _exit(0);
- return 0;
-}
-
-void
-_procstart(Proc *p, void (*fn)(Proc*))
-{
- void **a;
- uchar *stk;
- int pid;
-
- dofreestacks();
- a = malloc(3*sizeof a[0]);
- if(a == nil)
- sysfatal("_procstart malloc: %r");
- stk = malloc(65536);
- if(stk == nil)
- sysfatal("_procstart malloc stack: %r");
-
- a[0] = fn;
- a[1] = p;
- a[2] = stk;
-
- pid = rfork_thread(RFPROC|RFMEM|RFNOWAIT, stk+65536-64, startprocfn, a);
- if(pid < 0){
- fprint(2, "_procstart rfork_thread: %r\n");
- abort();
- }
-}
-
-static char *threadexitsmsg;
-void
-sigusr2handler(int s)
-{
-/* fprint(2, "%d usr2 %d\n", time(0), getpid()); */
- if(threadexitsmsg)
- _exits(threadexitsmsg);
-}
-
-void
-threadexitsall(char *msg)
-{
- static int pid[1024];
- int i, npid, mypid;
- Proc *p;
-
- if(msg == nil)
- msg = "";
-
- /*
- * Only one guy, ever, gets to run this.
- * If two guys do it, inevitably they end up
- * tripping over each other in the underlying
- * C library exit() implementation, which is
- * trying to run the atexit handlers and apparently
- * not thread safe. This has been observed on
- * both Linux and OpenBSD. Sigh.
- */
- {
- static Lock onelock;
- if(!canlock(&onelock))
- _exits(threadexitsmsg);
- threadexitsmsg = msg;
- }
-
- if(msg == nil)
- msg = "";
- mypid = getpid();
- lock(&_threadprocslock);
- threadexitsmsg = msg;
- npid = 0;
- for(p=_threadprocs; p; p=p->next)
- if(p->osprocid != mypid && p->osprocid >= 1)
- pid[npid++] = p->osprocid;
- for(i=0; i<npid; i++)
- kill(pid[i], SIGUSR2);
- unlock(&_threadprocslock);
- exits(msg);
-}
-
-/*
- * per-process data, indexed by pid
- */
-typedef struct Perproc Perproc;
-struct Perproc
-{
- int pid;
- Proc *proc;
-};
-
-static Lock perlock;
-static Perproc perproc[1024];
-#define P ((Proc*)-1)
-
-static Perproc*
-myperproc(void)
-{
- int i, pid, h;
- Perproc *p;
-
- pid = getpid();
- h = pid%nelem(perproc);
- for(i=0; i<nelem(perproc); i++){
- p = &perproc[(i+h)%nelem(perproc)];
- if(p->pid == pid)
- return p;
- if(p->pid == 0){
- print("found 0 at %d (h=%d)\n", (i+h)%nelem(perproc), h);
- break;
- }
- }
- fprint(2, "myperproc %d: cannot find self\n", pid);
- abort();
- return nil;
-}
-
-static Perproc*
-newperproc(void)
-{
- int i, pid, h;
- Perproc *p;
-
- lock(&perlock);
- pid = getpid();
- h = pid%nelem(perproc);
- for(i=0; i<nelem(perproc); i++){
- p = &perproc[(i+h)%nelem(perproc)];
- if(p->pid == pid || p->pid == -1 || p->pid == 0){
- p->pid = pid;
- unlock(&perlock);
- return p;
- }
- }
- fprint(2, "newperproc %d: out of procs\n", pid);
- abort();
- return nil;
-}
-
-Proc*
-_threadproc(void)
-{
- return myperproc()->proc;
-}
-
-void
-_threadsetproc(Proc *p)
-{
- Perproc *pp;
-
- if(p)
- p->osprocid = getpid();
- pp = newperproc();
- pp->proc = p;
- if(p == nil)
- pp->pid = -1;
-}
-
-void
-_threadpexit(void)
-{
- _exit(0);
-}
diff --git a/src/libthread/FreeBSD-386-asm.s b/src/libthread/FreeBSD-386-asm.s
deleted file mode 100644
index 42169853..00000000
--- a/src/libthread/FreeBSD-386-asm.s
+++ /dev/null
@@ -1,52 +0,0 @@
-.globl _tas
-_tas:
- movl $0xCAFEBABE, %eax
- movl 4(%esp), %ecx
- xchgl %eax, 0(%ecx)
- ret
-
-.globl getmcontext
-getmcontext:
- movl 4(%esp), %eax
-
- movl %fs, 8(%eax)
- movl %es, 12(%eax)
- movl %ds, 16(%eax)
- movl %ss, 76(%eax)
- movl %edi, 20(%eax)
- movl %esi, 24(%eax)
- movl %ebp, 28(%eax)
- movl %ebx, 36(%eax)
- movl %edx, 40(%eax)
- movl %ecx, 44(%eax)
-
- movl $1, 48(%eax) /* %eax */
- movl (%esp), %ecx /* %eip */
- movl %ecx, 60(%eax)
- leal 4(%esp), %ecx /* %esp */
- movl %ecx, 72(%eax)
-
- movl 44(%eax), %ecx /* restore %ecx */
- movl $0, %eax
- ret
-
-.globl setmcontext
-setmcontext:
- movl 4(%esp), %eax
-
- movl 8(%eax), %fs
- movl 12(%eax), %es
- movl 16(%eax), %ds
- movl 76(%eax), %ss
- movl 20(%eax), %edi
- movl 24(%eax), %esi
- movl 28(%eax), %ebp
- movl 36(%eax), %ebx
- movl 40(%eax), %edx
- movl 44(%eax), %ecx
-
- movl 72(%eax), %esp
- pushl 60(%eax) /* new %eip */
- movl 48(%eax), %eax
- ret
-
diff --git a/src/libthread/FreeBSD.c b/src/libthread/FreeBSD.c
deleted file mode 100644
index 5c282465..00000000
--- a/src/libthread/FreeBSD.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "threadimpl.h"
-
-#include "BSD.c"
-
-/*
- * FreeBSD 4 and earlier needs the context functions.
- */
-void
-makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
-{
- int *sp;
-
- sp = (int*)ucp->uc_stack.ss_sp+ucp->uc_stack.ss_size/4;
- sp -= argc;
- memmove(sp, &argc+1, argc*sizeof(int));
- *--sp = 0; /* return address */
- ucp->uc_mcontext.mc_eip = (long)func;
- ucp->uc_mcontext.mc_esp = (int)sp;
-}
-
-int
-swapcontext(ucontext_t *oucp, ucontext_t *ucp)
-{
- if(getcontext(oucp) == 0)
- setcontext(ucp);
- return 0;
-}
-
-void
-_pthreadinit(void)
-{
- __isthreaded = 1;
- signal(SIGUSR2, sigusr2handler);
-}
diff --git a/src/libthread/OpenBSD-386-asm.s b/src/libthread/OpenBSD-386-asm.s
index dad1b536..42169853 100644
--- a/src/libthread/OpenBSD-386-asm.s
+++ b/src/libthread/OpenBSD-386-asm.s
@@ -1 +1,52 @@
-#include "FreeBSD-386-asm.s"
+.globl _tas
+_tas:
+ movl $0xCAFEBABE, %eax
+ movl 4(%esp), %ecx
+ xchgl %eax, 0(%ecx)
+ ret
+
+.globl getmcontext
+getmcontext:
+ movl 4(%esp), %eax
+
+ movl %fs, 8(%eax)
+ movl %es, 12(%eax)
+ movl %ds, 16(%eax)
+ movl %ss, 76(%eax)
+ movl %edi, 20(%eax)
+ movl %esi, 24(%eax)
+ movl %ebp, 28(%eax)
+ movl %ebx, 36(%eax)
+ movl %edx, 40(%eax)
+ movl %ecx, 44(%eax)
+
+ movl $1, 48(%eax) /* %eax */
+ movl (%esp), %ecx /* %eip */
+ movl %ecx, 60(%eax)
+ leal 4(%esp), %ecx /* %esp */
+ movl %ecx, 72(%eax)
+
+ movl 44(%eax), %ecx /* restore %ecx */
+ movl $0, %eax
+ ret
+
+.globl setmcontext
+setmcontext:
+ movl 4(%esp), %eax
+
+ movl 8(%eax), %fs
+ movl 12(%eax), %es
+ movl 16(%eax), %ds
+ movl 76(%eax), %ss
+ movl 20(%eax), %edi
+ movl 24(%eax), %esi
+ movl 28(%eax), %ebp
+ movl 36(%eax), %ebx
+ movl 40(%eax), %edx
+ movl 44(%eax), %ecx
+
+ movl 72(%eax), %esp
+ pushl 60(%eax) /* new %eip */
+ movl 48(%eax), %eax
+ ret
+
diff --git a/src/libthread/mkfile b/src/libthread/mkfile
index f621ac60..31c4c7e5 100644
--- a/src/libthread/mkfile
+++ b/src/libthread/mkfile
@@ -16,7 +16,6 @@ OFILES=\
<$PLAN9/src/mksyslib
HFILES=thread.h threadimpl.h
-FreeBSD.$O: BSD.c
NetBSD.$O: Linux.c
tprimes: test/tprimes.$O
diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h
index 6671f23c..e26ffe6b 100644
--- a/src/libthread/threadimpl.h
+++ b/src/libthread/threadimpl.h
@@ -15,15 +15,6 @@
#include "libc.h"
#include "thread.h"
-#if defined(__FreeBSD__) && __FreeBSD__ < 5
-extern int getmcontext(mcontext_t*);
-extern void setmcontext(mcontext_t*);
-#define setcontext(u) setmcontext(&(u)->uc_mcontext)
-#define getcontext(u) getmcontext(&(u)->uc_mcontext)
-extern int swapcontext(ucontext_t*, ucontext_t*);
-extern void makecontext(ucontext_t*, void(*)(), int, ...);
-#endif
-
#if defined(__APPLE__)
/*
* OS X before 10.5 (Leopard) does not provide