more freebsd work
diff --git a/src/libthread/FreeBSD.c b/src/libthread/FreeBSD.c index 77c4869..0fdb54b 100644 --- a/src/libthread/FreeBSD.c +++ b/src/libthread/FreeBSD.c
@@ -1,11 +1,3 @@ -#include "u.h" -#include <errno.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sched.h> -#include <signal.h> -#include "libc.h" -#include "thread.h" #include "threadimpl.h" extern int __isthreaded; @@ -70,7 +62,6 @@ { lock((Lock*)&lk->access_lock); } - __isthreaded = 1; /* * sleep and wakeup @@ -351,6 +342,46 @@ void _pthreadinit(void) { + __isthreaded = 1; signal(SIGUSR2, sigusr2handler); } +/* + * 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; +} + +extern int getmcontext(mcontext_t*); +extern int setmcontext(mcontext_t*); + +int +getcontext(ucontext_t *uc) +{ + return getmcontext(&uc->uc_mcontext); +} + +void +setcontext(ucontext_t *uc) +{ + setmcontext(&uc->uc_mcontext); +} + +int +swapcontext(ucontext_t *oucp, ucontext_t *ucp) +{ + if(getcontext(oucp) == 0) + setcontext(ucp); + return 0; +} +
diff --git a/src/libthread/FreeBSDasm.s b/src/libthread/FreeBSDasm.s new file mode 100644 index 0000000..f9a8025 --- /dev/null +++ b/src/libthread/FreeBSDasm.s
@@ -0,0 +1,54 @@ +.globl _tas +_tas: + movl $0xCAFEBABE, %eax + movl 4(%esp), %ecx + xchgl %eax, 0(%ecx) + ret + +.globl setmcontext +setmcontext: + movl 4(%esp), %edx + movl 8(%edx), %fs + movl 12(%edx), %es + movl 16(%edx), %ds + movl 76(%edx), %ss + movl 20(%edx), %edi + movl 24(%edx), %esi + movl 28(%edx), %ebp + movl %esp, %ecx + movl 72(%edx), %esp + pushl 60(%edx) /* eip */ + pushl 44(%edx) /* ecx */ + pushl 48(%edx) /* eax */ + movl 36(%edx), %ebx + movl 40(%edx), %edx + movl 12(%ecx), %eax + popl %eax + popl %ecx + ret + +.globl getmcontext +getmcontext: + pushl %edx + movl 8(%esp), %edx + movl %fs, 8(%edx) + movl %es, 12(%edx) + movl %ds, 16(%edx) + movl %ss, 76(%edx) + movl %edi, 20(%edx) + movl %esi, 24(%edx) + movl %ebp, 28(%edx) + movl %ebx, 36(%edx) + movl $1, 48(%edx) + popl %eax + movl %eax, 40(%edx) + movl %ecx, 44(%edx) + movl (%esp), %eax /* eip */ + movl %eax, 60(%edx) + movl %esp, %eax + addl $4, %eax /* setmcontext will re-push the eip */ + movl %eax, 72(%edx) + movl 40(%edx), %edx + xorl %eax, %eax + ret +
diff --git a/src/libthread/Linux.c b/src/libthread/Linux.c index be97f5a..103cb42 100644 --- a/src/libthread/Linux.c +++ b/src/libthread/Linux.c
@@ -1,11 +1,3 @@ -#include "u.h" -#include <errno.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sched.h> -#include <signal.h> -#include "libc.h" -#include "thread.h" #include "threadimpl.h" /*
diff --git a/src/libthread/channel.c b/src/libthread/channel.c index c8c9679..4dc51fc 100644 --- a/src/libthread/channel.c +++ b/src/libthread/channel.c
@@ -1,6 +1,3 @@ -#include "u.h" -#include "libc.h" -#include "thread.h" #include "threadimpl.h" /*
diff --git a/src/libthread/daemonize.c b/src/libthread/daemonize.c index 65af29a..dab6e42 100644 --- a/src/libthread/daemonize.c +++ b/src/libthread/daemonize.c
@@ -1,8 +1,3 @@ -#include <u.h> -#include <sys/signal.h> -#include <sys/wait.h> -#include <libc.h> -#include <thread.h> #include "threadimpl.h" #undef pipe @@ -15,8 +10,10 @@ child(void) { int status; - if(wait(&status) == sigpid && WIFEXITED(status)) - _exit(WEXITSTATUS(status)); + if(wait(&status) == sigpid) + if(WIFEXITED(status)) + _exit(WEXITSTATUS(status)); + _exit(97); } static void @@ -83,7 +80,7 @@ child(); if(n > 0) break; - sysfatal("passer pipe read: %r"); + print("passer read: %r\n"); } buf[n] = 0; _exit(atoi(buf));
diff --git a/src/libthread/exec.c b/src/libthread/exec.c index 6a7ca1d..a81490b 100644 --- a/src/libthread/exec.c +++ b/src/libthread/exec.c
@@ -1,7 +1,3 @@ -#include "u.h" -#include <errno.h> -#include "libc.h" -#include "thread.h" #include "threadimpl.h" static Lock thewaitlock;
diff --git a/src/libthread/mkfile b/src/libthread/mkfile index 259bcff..1e257b3 100644 --- a/src/libthread/mkfile +++ b/src/libthread/mkfile
@@ -39,3 +39,5 @@ CLEANFILES=p1.txt p2.txt tp1.txt tp2.txt + +
diff --git a/src/libthread/pthread.c b/src/libthread/pthread.c index c1804a4..8d3c7f9 100644 --- a/src/libthread/pthread.c +++ b/src/libthread/pthread.c
@@ -1,7 +1,3 @@ -#include "u.h" -#include <errno.h> -#include "libc.h" -#include "thread.h" #include "threadimpl.h" static pthread_mutex_t initmutex = PTHREAD_MUTEX_INITIALIZER;
diff --git a/src/libthread/thread.c b/src/libthread/thread.c index b41f9f3..92e9394 100644 --- a/src/libthread/thread.c +++ b/src/libthread/thread.c
@@ -1,6 +1,3 @@ -#include "u.h" -#include "libc.h" -#include "thread.h" #include "threadimpl.h" int _threaddebuglevel; @@ -95,7 +92,7 @@ sigemptyset(&zero); sigprocmask(SIG_BLOCK, &zero, &t->context.uc.uc_sigmask); - /* on Linux makecontext neglects floating point */ + /* must initialize with current context */ getcontext(&t->context.uc); /* call makecontext to do the real work. */
diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h index d4acebe..32afa5f 100644 --- a/src/libthread/threadimpl.h +++ b/src/libthread/threadimpl.h
@@ -1,4 +1,20 @@ +#include "u.h" +#include <errno.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sched.h> +#include <signal.h> #include <ucontext.h> +#include "libc.h" +#include "thread.h" + +#if defined(__FreeBSD__) && !defined(__FreeBSD5__) +extern int getcontext(ucontext_t*); +extern void setcontext(ucontext_t*); +extern int swapcontext(ucontext_t*, ucontext_t*); +extern void makecontext(ucontext_t*, void(*)(), int, ...); +#endif typedef struct Context Context; typedef struct Execjob Execjob;