Commit c2606381 authored by Marcus Meissner's avatar Marcus Meissner Committed by Alexandre Julliard

- Started multithreading for FreeBSD (incomplete, but some

applications now at least start up again). - Use _thread_sys_sigaction/_thread_sys_sigaltstack. - CR2 on pagefault gets passed in sc_err (some kind of kludge in FreeBSD owns fault handling we can use)
parent 284c9b92
...@@ -91,6 +91,8 @@ then ...@@ -91,6 +91,8 @@ then
fi fi
dnl Check for -lxpg4 for FreeBSD dnl Check for -lxpg4 for FreeBSD
AC_CHECK_LIB(xpg4,setrunelocale) AC_CHECK_LIB(xpg4,setrunelocale)
dnl Check for -lc_r for FreeBSD
AC_CHECK_LIB(c_r,__error)
dnl Check for -ldl dnl Check for -ldl
AC_CHECK_LIB(dl,dlopen) AC_CHECK_LIB(dl,dlopen)
AC_SUBST(XLIB) AC_SUBST(XLIB)
...@@ -342,13 +344,29 @@ dnl ...@@ -342,13 +344,29 @@ dnl
dnl For cross-compiling we blindly assume that libc is reentrant. This is dnl For cross-compiling we blindly assume that libc is reentrant. This is
dnl ok since non-reentrant libc is quite rare (mostly old libc5 versions). dnl ok since non-reentrant libc is quite rare (mostly old libc5 versions).
dnl
dnl Linux style errno location
dnl
AC_CACHE_CHECK("for reentrant libc", wine_cv_libc_reentrant, AC_CACHE_CHECK("for reentrant libc", wine_cv_libc_reentrant,
[AC_TRY_RUN([int myerrno = 0; [AC_TRY_RUN([int myerrno = 0;
char buf[256]; char buf[256];
int *__errno_location(){return &myerrno;} int *__errno_location(){return &myerrno;}
main(){connect(0,buf,255); exit(!myerrno);}], main(){connect(0,buf,255); exit(!myerrno);}],
wine_cv_libc_reentrant=yes, wine_cv_libc_reentrant=no, wine_cv_libc_reentrant=yes, wine_cv_libc_reentrant=no,
wine_cv_libc_reentrant=yes ) ] ) wine_cv_libc_reentrant=yes )
dnl
dnl FreeBSD style errno location
dnl
if test "$wine_cv_libc_reentrant" = "no"
then
AC_TRY_RUN([int myerrno = 0;
char buf[256];
int *__error(){return &myerrno;}
main(){connect(0,buf,255); exit(!myerrno);}],
wine_cv_libc_reentrant=yes, wine_cv_libc_reentrant=no,
wine_cv_libc_reentrant=yes )
fi
])
if test "$wine_cv_libc_reentrant" = "no" if test "$wine_cv_libc_reentrant" = "no"
then then
AC_DEFINE(NO_REENTRANT_LIBC) AC_DEFINE(NO_REENTRANT_LIBC)
...@@ -399,7 +417,7 @@ fi ...@@ -399,7 +417,7 @@ fi
dnl **** Check for functions and header files **** dnl **** Check for functions and header files ****
AC_CHECK_FUNCS(clone getpagesize memmove sendmsg sigaltstack strerror stricmp tcgetattr timegm usleep wait4 waitpid vfscanf) AC_CHECK_FUNCS(rfork clone getpagesize memmove sendmsg sigaltstack strerror stricmp tcgetattr timegm usleep wait4 waitpid vfscanf)
AC_CHECK_HEADERS(wctype.h sys/syscall.h syscall.h sys/param.h sys/vfs.h sys/mount.h sys/statfs.h float.h linux/cdrom.h linux/ucdrom.h sys/cdio.h sys/filio.h sys/modem.h strings.h sys/strtio.h dlfcn.h unistd.h sys/sockio.h net/if.h netinet/in.h sys/file.h libio.h curses.h ncurses.h elf.h arpa/nameser.h resolv.h) AC_CHECK_HEADERS(wctype.h sys/syscall.h syscall.h sys/param.h sys/vfs.h sys/mount.h sys/statfs.h float.h linux/cdrom.h linux/ucdrom.h sys/cdio.h sys/filio.h sys/modem.h strings.h sys/strtio.h dlfcn.h unistd.h sys/sockio.h net/if.h netinet/in.h sys/file.h libio.h curses.h ncurses.h elf.h arpa/nameser.h resolv.h)
AC_HEADER_STAT() AC_HEADER_STAT()
AC_C_CONST() AC_C_CONST()
......
...@@ -102,6 +102,9 @@ ...@@ -102,6 +102,9 @@
/* Define if you have the memmove function. */ /* Define if you have the memmove function. */
#undef HAVE_MEMMOVE #undef HAVE_MEMMOVE
/* Define if you have the rfork function. */
#undef HAVE_RFORK
/* Define if you have the sendmsg function. */ /* Define if you have the sendmsg function. */
#undef HAVE_SENDMSG #undef HAVE_SENDMSG
...@@ -243,6 +246,9 @@ ...@@ -243,6 +246,9 @@
/* Define if you have the <wctype.h> header file. */ /* Define if you have the <wctype.h> header file. */
#undef HAVE_WCTYPE_H #undef HAVE_WCTYPE_H
/* Define if you have the c_r library (-lc_r). */
#undef HAVE_LIBC_R
/* Define if you have the curses library (-lcurses). */ /* Define if you have the curses library (-lcurses). */
#undef HAVE_LIBCURSES #undef HAVE_LIBCURSES
......
...@@ -153,7 +153,9 @@ typedef struct _CONTEXT /* Note 1 */ ...@@ -153,7 +153,9 @@ typedef struct _CONTEXT /* Note 1 */
#define SS_sig(context) ((context)->sc_ss) #define SS_sig(context) ((context)->sc_ss)
#ifdef linux #ifdef linux
/* fs and gs are not supported on *BSD. */ /* FS and GS are now in the sigcontext struct of FreeBSD, but not
* saved by the exception handling. duh.
*/
#define FS_sig(context) ((context)->sc_fs) #define FS_sig(context) ((context)->sc_fs)
#define GS_sig(context) ((context)->sc_gs) #define GS_sig(context) ((context)->sc_gs)
#define CR2_sig(context) ((context)->cr2) #define CR2_sig(context) ((context)->cr2)
...@@ -164,8 +166,11 @@ typedef struct _CONTEXT /* Note 1 */ ...@@ -164,8 +166,11 @@ typedef struct _CONTEXT /* Note 1 */
#define EFL_sig(context) ((context)->sc_eflags) #define EFL_sig(context) ((context)->sc_eflags)
#else #else
#define EFL_sig(context) ((context)->sc_efl) #define EFL_sig(context) ((context)->sc_efl)
/* FreeBSD, see i386/i386/traps.c::trap_pfault va->err kludge */
#define CR2_sig(context) ((context)->sc_err)
#endif #endif
#define EIP_sig(context) (*((unsigned long*)&(context)->sc_eip)) #define EIP_sig(context) (*((unsigned long*)&(context)->sc_eip))
#define ESP_sig(context) (*((unsigned long*)&(context)->sc_esp)) #define ESP_sig(context) (*((unsigned long*)&(context)->sc_esp))
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "config.h" #include "config.h"
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#include <string.h> #include <string.h>
...@@ -43,6 +44,10 @@ void (*fnWINE_Debugger)(int,SIGCONTEXT*) = NULL; ...@@ -43,6 +44,10 @@ void (*fnWINE_Debugger)(int,SIGCONTEXT*) = NULL;
void (*ctx_debug_call)(int sig,CONTEXT*ctx)=NULL; void (*ctx_debug_call)(int sig,CONTEXT*ctx)=NULL;
BOOL (*fnINSTR_EmulateInstruction)(SIGCONTEXT*ctx)=NULL; BOOL (*fnINSTR_EmulateInstruction)(SIGCONTEXT*ctx)=NULL;
#define SIGACTION sigaction
#define SIGALTSTACK sigaltstack
#ifdef __i386__ #ifdef __i386__
/* i386 specific faults */ /* i386 specific faults */
...@@ -75,6 +80,7 @@ static const char * const SIGNAL_traps[] = ...@@ -75,6 +80,7 @@ static const char * const SIGNAL_traps[] =
#if defined(linux) && defined(__i386__) #if defined(linux) && defined(__i386__)
/* This is the sigaction structure from the Linux 2.1.20 kernel. */ /* This is the sigaction structure from the Linux 2.1.20 kernel. */
#undef sa_handler #undef sa_handler
struct kernel_sigaction struct kernel_sigaction
{ {
...@@ -112,8 +118,19 @@ static __inline__ int wine_sigaction( int sig, struct kernel_sigaction *new, ...@@ -112,8 +118,19 @@ static __inline__ int wine_sigaction( int sig, struct kernel_sigaction *new,
errno = -sig; errno = -sig;
return -1; return -1;
} }
#undef SIGACTION
#define SIGACTION wine_sigaction
#endif /* linux && __i386__ */ #endif /* linux && __i386__ */
#ifdef __FreeBSD__
#undef SIGACTION
#define SIGACTION _thread_sys_sigaction
extern int _thread_sys_sigaction(int sig,const struct sigaction*act,struct sigaction* oact);
#undef SIGALTSTACK
#define SIGALTSTACK _thread_sys_sigaltstack
extern int _thread_sys_sigaltstack(const struct sigaltstack *ss,struct sigaltstack *oss);
#endif
/* Signal stack */ /* Signal stack */
static char SIGNAL_Stack[16384]; static char SIGNAL_Stack[16384];
...@@ -172,7 +189,7 @@ void SIGNAL_SetHandler( int sig, void (*func)(), int flags ) ...@@ -172,7 +189,7 @@ void SIGNAL_SetHandler( int sig, void (*func)(), int flags )
# else # else
sig_act.sa_flags = 0; sig_act.sa_flags = 0;
# endif # endif
ret = sigaction( sig, &sig_act, NULL ); ret = SIGACTION( sig, &sig_act, NULL );
#endif /* linux && __i386__ */ #endif /* linux && __i386__ */
...@@ -298,9 +315,9 @@ BOOL SIGNAL_Init(void) ...@@ -298,9 +315,9 @@ BOOL SIGNAL_Init(void)
ss.ss_sp = SIGNAL_Stack; ss.ss_sp = SIGNAL_Stack;
ss.ss_size = sizeof(SIGNAL_Stack); ss.ss_size = sizeof(SIGNAL_Stack);
ss.ss_flags = 0; ss.ss_flags = 0;
if (sigaltstack(&ss, NULL) < 0) if (SIGALTSTACK(&ss, NULL) < 0)
{ {
perror("sigstack"); perror("sigaltstack");
return FALSE; return FALSE;
} }
#endif /* HAVE_SIGALTSTACK */ #endif /* HAVE_SIGALTSTACK */
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
* Copyright 1998 Alexandre Julliard * Copyright 1998 Alexandre Julliard
*/ */
#include "config.h"
/* Get pointers to the static errno and h_errno variables used by Xlib. This /* Get pointers to the static errno and h_errno variables used by Xlib. This
must be done before including <errno.h> makes the variables invisible. */ must be done before including <errno.h> makes the variables invisible. */
extern int errno; extern int errno;
...@@ -14,11 +16,15 @@ static int *ph_errno = &h_errno; ...@@ -14,11 +16,15 @@ static int *ph_errno = &h_errno;
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#ifdef HAVE_SYS_SYSCALL_H
# include <sys/syscall.h>
#endif
#include "thread.h" #include "thread.h"
#include "server.h" #include "server.h"
#include "winbase.h" #include "winbase.h"
#include "debug.h" #include "debug.h"
/* Xlib critical section (FIXME: does not belong here) */ /* Xlib critical section (FIXME: does not belong here) */
CRITICAL_SECTION X11DRV_CritSection = { 0, }; CRITICAL_SECTION X11DRV_CritSection = { 0, };
...@@ -39,6 +45,7 @@ extern int clone( int (*fn)(void *arg), void *stack, int flags, void *arg ); ...@@ -39,6 +45,7 @@ extern int clone( int (*fn)(void *arg), void *stack, int flags, void *arg );
#ifdef USE_THREADS #ifdef USE_THREADS
#ifdef linux
/*********************************************************************** /***********************************************************************
* __errno_location * __errno_location
* *
...@@ -72,6 +79,20 @@ int *__h_errno_location() ...@@ -72,6 +79,20 @@ int *__h_errno_location()
#endif #endif
return &thdb->thread_h_errno; return &thdb->thread_h_errno;
} }
#endif
#ifdef __FreeBSD__
int *__error() {
THDB *thdb = THREAD_Current();
if (!thdb) return perrno;
#ifdef NO_REENTRANT_X11
/* Use static libc errno while running in Xlib. */
if (X11DRV_CritSection.OwningThread == (HANDLE)thdb->server_tid)
return perrno;
#endif
return &thdb->thread_errno;
}
#endif
/*********************************************************************** /***********************************************************************
* SYSDEPS_StartThread * SYSDEPS_StartThread
...@@ -107,7 +128,23 @@ int SYSDEPS_SpawnThread( THDB *thread ) ...@@ -107,7 +128,23 @@ int SYSDEPS_SpawnThread( THDB *thread )
#endif #endif
#ifdef HAVE_RFORK #ifdef HAVE_RFORK
FIXME(thread, "Threads using rfork() not implemented\n" ); DWORD *sp = (DWORD *)thread->teb.stack_top;
*--sp = (DWORD)thread;
*--sp = 0;
*--sp = (DWORD)SYSDEPS_StartThread;
__asm__(
"pushl %2;\n\t" /* RFPROC|RMEM */
"pushl $0;\n\t" /* 0 ? */
"movl %1,%%eax;\n\t" /* SYS_rfork */
".byte 0x9a; .long 0; .word 7;\n\t" /* lcall 7:0... FreeBSD syscall */
"cmpl $0, %%edx;\n\t"
"je 1f;\n\t"
"movl %0,%%esp;\n\t" /* father -> new thread */
"ret;\n"
"1:\n\t" /* child -> caller thread */
"addl $8,%%esp" :
: "r" (sp), "g" (SYS_rfork), "g" (RFPROC|RFMEM)
: "eax", "edx");
#endif #endif
#else /* !USE_THREADS */ #else /* !USE_THREADS */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment