tmore freebsd work - plan9port - [fork] Plan 9 from user space (HTM) git clone git://src.adamsgaard.dk/plan9port (DIR) Log (DIR) Files (DIR) Refs (DIR) README (DIR) LICENSE --- (DIR) commit d54ead7fb922cfa661c7b7f0d0b2ba1251cdea7f (DIR) parent 9cb22ba60776e22568798b40560543ddf6c8ed2c (HTM) Author: rsc <devnull@localhost> Date: Tue, 28 Dec 2004 04:20:39 +0000 more freebsd work Diffstat: M src/libthread/FreeBSD.c | 49 +++++++++++++++++++++++++------ A src/libthread/FreeBSDasm.s | 54 +++++++++++++++++++++++++++++++ M src/libthread/Linux.c | 8 -------- M src/libthread/channel.c | 3 --- M src/libthread/daemonize.c | 13 +++++-------- M src/libthread/exec.c | 4 ---- M src/libthread/mkfile | 2 ++ M src/libthread/pthread.c | 4 ---- M src/libthread/thread.c | 5 +---- M src/libthread/threadimpl.h | 16 ++++++++++++++++ 10 files changed, 118 insertions(+), 40 deletions(-) --- (DIR) diff --git a/src/libthread/FreeBSD.c b/src/libthread/FreeBSD.c t@@ -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; t@@ -70,7 +62,6 @@ _spinlock(spinlock_t *lk) { lock((Lock*)&lk->access_lock); } - __isthreaded = 1; /* * sleep and wakeup t@@ -351,6 +342,46 @@ _threadsetproc(Proc *p) 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; +} + (DIR) diff --git a/src/libthread/FreeBSDasm.s b/src/libthread/FreeBSDasm.s t@@ -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 + (DIR) diff --git a/src/libthread/Linux.c b/src/libthread/Linux.c t@@ -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" /* (DIR) diff --git a/src/libthread/channel.c b/src/libthread/channel.c t@@ -1,6 +1,3 @@ -#include "u.h" -#include "libc.h" -#include "thread.h" #include "threadimpl.h" /* (DIR) diff --git a/src/libthread/daemonize.c b/src/libthread/daemonize.c t@@ -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 t@@ -15,8 +10,10 @@ static void 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 t@@ -83,7 +80,7 @@ _threadsetupdaemonize(void) child(); if(n > 0) break; - sysfatal("passer pipe read: %r"); + print("passer read: %r\n"); } buf[n] = 0; _exit(atoi(buf)); (DIR) diff --git a/src/libthread/exec.c b/src/libthread/exec.c t@@ -1,7 +1,3 @@ -#include "u.h" -#include <errno.h> -#include "libc.h" -#include "thread.h" #include "threadimpl.h" static Lock thewaitlock; (DIR) diff --git a/src/libthread/mkfile b/src/libthread/mkfile t@@ -39,3 +39,5 @@ test:V: tprimes tspawn CLEANFILES=p1.txt p2.txt tp1.txt tp2.txt + + (DIR) diff --git a/src/libthread/pthread.c b/src/libthread/pthread.c t@@ -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; (DIR) diff --git a/src/libthread/thread.c b/src/libthread/thread.c t@@ -1,6 +1,3 @@ -#include "u.h" -#include "libc.h" -#include "thread.h" #include "threadimpl.h" int _threaddebuglevel; t@@ -95,7 +92,7 @@ threadalloc(void (*fn)(void*), void *arg, uint stack) 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. */ (DIR) diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h t@@ -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;