From d54ead7fb922cfa661c7b7f0d0b2ba1251cdea7f Mon Sep 17 00:00:00 2001 From: rsc Date: Tue, 28 Dec 2004 04:20:39 +0000 Subject: more freebsd work --- src/libthread/FreeBSD.c | 49 +++++++++++++++++++++++++++++++++-------- src/libthread/FreeBSDasm.s | 54 ++++++++++++++++++++++++++++++++++++++++++++++ src/libthread/Linux.c | 8 ------- src/libthread/channel.c | 3 --- src/libthread/daemonize.c | 13 +++++------ src/libthread/exec.c | 4 ---- src/libthread/mkfile | 2 ++ src/libthread/pthread.c | 4 ---- src/libthread/thread.c | 5 +---- src/libthread/threadimpl.h | 16 ++++++++++++++ 10 files changed, 118 insertions(+), 40 deletions(-) create mode 100644 src/libthread/FreeBSDasm.s (limited to 'src') diff --git a/src/libthread/FreeBSD.c b/src/libthread/FreeBSD.c index 77c4869a..0fdb54b9 100644 --- a/src/libthread/FreeBSD.c +++ b/src/libthread/FreeBSD.c @@ -1,11 +1,3 @@ -#include "u.h" -#include -#include -#include -#include -#include -#include "libc.h" -#include "thread.h" #include "threadimpl.h" extern int __isthreaded; @@ -70,7 +62,6 @@ _spinlock(spinlock_t *lk) { lock((Lock*)&lk->access_lock); } - __isthreaded = 1; /* * sleep and wakeup @@ -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; +} + diff --git a/src/libthread/FreeBSDasm.s b/src/libthread/FreeBSDasm.s new file mode 100644 index 00000000..f9a80255 --- /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 be97f5a7..103cb428 100644 --- a/src/libthread/Linux.c +++ b/src/libthread/Linux.c @@ -1,11 +1,3 @@ -#include "u.h" -#include -#include -#include -#include -#include -#include "libc.h" -#include "thread.h" #include "threadimpl.h" /* diff --git a/src/libthread/channel.c b/src/libthread/channel.c index c8c96796..4dc51fcf 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 65af29ab..dab6e42b 100644 --- a/src/libthread/daemonize.c +++ b/src/libthread/daemonize.c @@ -1,8 +1,3 @@ -#include -#include -#include -#include -#include #include "threadimpl.h" #undef pipe @@ -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 @@ -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)); diff --git a/src/libthread/exec.c b/src/libthread/exec.c index 6a7ca1db..a81490b1 100644 --- a/src/libthread/exec.c +++ b/src/libthread/exec.c @@ -1,7 +1,3 @@ -#include "u.h" -#include -#include "libc.h" -#include "thread.h" #include "threadimpl.h" static Lock thewaitlock; diff --git a/src/libthread/mkfile b/src/libthread/mkfile index 259bcff1..1e257b3e 100644 --- a/src/libthread/mkfile +++ b/src/libthread/mkfile @@ -39,3 +39,5 @@ test:V: tprimes tspawn CLEANFILES=p1.txt p2.txt tp1.txt tp2.txt + + diff --git a/src/libthread/pthread.c b/src/libthread/pthread.c index c1804a43..8d3c7f9a 100644 --- a/src/libthread/pthread.c +++ b/src/libthread/pthread.c @@ -1,7 +1,3 @@ -#include "u.h" -#include -#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 b41f9f34..92e93940 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 @@ 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. */ diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h index d4acebeb..32afa5fe 100644 --- a/src/libthread/threadimpl.h +++ b/src/libthread/threadimpl.h @@ -1,4 +1,20 @@ +#include "u.h" +#include +#include +#include +#include +#include +#include #include +#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; -- cgit v1.2.3