plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

commit d54ead7fb922cfa661c7b7f0d0b2ba1251cdea7f
parent 9cb22ba60776e22568798b40560543ddf6c8ed2c
Author: rsc <devnull@localhost>
Date:   Tue, 28 Dec 2004 04:20:39 +0000

more freebsd work

Diffstat:
Msrc/libthread/FreeBSD.c | 49++++++++++++++++++++++++++++++++++++++++---------
Asrc/libthread/FreeBSDasm.s | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/libthread/Linux.c | 8--------
Msrc/libthread/channel.c | 3---
Msrc/libthread/daemonize.c | 13+++++--------
Msrc/libthread/exec.c | 4----
Msrc/libthread/mkfile | 2++
Msrc/libthread/pthread.c | 4----
Msrc/libthread/thread.c | 5+----
Msrc/libthread/threadimpl.h | 16++++++++++++++++
10 files changed, 118 insertions(+), 40 deletions(-)

diff --git 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 @@ _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 @@ -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 @@ -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 @@ -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 @@ -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 @@ 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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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;