- 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)
This commit is contained in:
parent
284c9b923a
commit
c26063818f
22
configure.in
22
configure.in
|
@ -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
|
||||||
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
|
||||||
|
|
||||||
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 @@
|
||||||
/* 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 @@
|
||||||
/* 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,19 +153,24 @@ 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)
|
||||||
#define TRAP_sig(context) ((context)->sc_trapno)
|
#define TRAP_sig(context) ((context)->sc_trapno)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __FreeBSD__
|
#ifndef __FreeBSD__
|
||||||
#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 @@
|
||||||
#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;
|
||||||
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[] =
|
||||||
|
|
||||||
#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,
|
||||||
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 )
|
||||||
# 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)
|
||||||
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 @@
|
||||||
* 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;
|
||||||
#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 );
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_THREADS
|
#ifdef USE_THREADS
|
||||||
|
#ifdef linux
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* __errno_location
|
* __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 )
|
||||||
#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 */
|
||||||
|
|
Loading…
Reference in New Issue