- 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
|
||||
dnl Check for -lxpg4 for FreeBSD
|
||||
AC_CHECK_LIB(xpg4,setrunelocale)
|
||||
dnl Check for -lc_r for FreeBSD
|
||||
AC_CHECK_LIB(c_r,__error)
|
||||
dnl Check for -ldl
|
||||
AC_CHECK_LIB(dl,dlopen)
|
||||
AC_SUBST(XLIB)
|
||||
|
@ -342,13 +344,29 @@ dnl
|
|||
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
|
||||
dnl Linux style errno location
|
||||
dnl
|
||||
AC_CACHE_CHECK("for reentrant libc", wine_cv_libc_reentrant,
|
||||
[AC_TRY_RUN([int myerrno = 0;
|
||||
char buf[256];
|
||||
int *__errno_location(){return &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=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"
|
||||
then
|
||||
AC_DEFINE(NO_REENTRANT_LIBC)
|
||||
|
@ -399,7 +417,7 @@ fi
|
|||
|
||||
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_HEADER_STAT()
|
||||
AC_C_CONST()
|
||||
|
|
|
@ -102,6 +102,9 @@
|
|||
/* Define if you have the memmove function. */
|
||||
#undef HAVE_MEMMOVE
|
||||
|
||||
/* Define if you have the rfork function. */
|
||||
#undef HAVE_RFORK
|
||||
|
||||
/* Define if you have the sendmsg function. */
|
||||
#undef HAVE_SENDMSG
|
||||
|
||||
|
@ -243,6 +246,9 @@
|
|||
/* Define if you have the <wctype.h> header file. */
|
||||
#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). */
|
||||
#undef HAVE_LIBCURSES
|
||||
|
||||
|
|
|
@ -153,19 +153,24 @@ typedef struct _CONTEXT /* Note 1 */
|
|||
#define SS_sig(context) ((context)->sc_ss)
|
||||
|
||||
#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 GS_sig(context) ((context)->sc_gs)
|
||||
#define CR2_sig(context) ((context)->cr2)
|
||||
#define TRAP_sig(context) ((context)->sc_trapno)
|
||||
#endif
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
#define EFL_sig(context) ((context)->sc_eflags)
|
||||
#else
|
||||
#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
|
||||
|
||||
|
||||
|
||||
#define EIP_sig(context) (*((unsigned long*)&(context)->sc_eip))
|
||||
#define ESP_sig(context) (*((unsigned long*)&(context)->sc_esp))
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
|
@ -43,6 +44,10 @@ void (*fnWINE_Debugger)(int,SIGCONTEXT*) = NULL;
|
|||
void (*ctx_debug_call)(int sig,CONTEXT*ctx)=NULL;
|
||||
BOOL (*fnINSTR_EmulateInstruction)(SIGCONTEXT*ctx)=NULL;
|
||||
|
||||
|
||||
#define SIGACTION sigaction
|
||||
#define SIGALTSTACK sigaltstack
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
/* i386 specific faults */
|
||||
|
@ -75,6 +80,7 @@ static const char * const SIGNAL_traps[] =
|
|||
|
||||
#if defined(linux) && defined(__i386__)
|
||||
/* This is the sigaction structure from the Linux 2.1.20 kernel. */
|
||||
|
||||
#undef sa_handler
|
||||
struct kernel_sigaction
|
||||
{
|
||||
|
@ -112,8 +118,19 @@ static __inline__ int wine_sigaction( int sig, struct kernel_sigaction *new,
|
|||
errno = -sig;
|
||||
return -1;
|
||||
}
|
||||
#undef SIGACTION
|
||||
#define SIGACTION wine_sigaction
|
||||
#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 */
|
||||
|
||||
static char SIGNAL_Stack[16384];
|
||||
|
@ -172,7 +189,7 @@ void SIGNAL_SetHandler( int sig, void (*func)(), int flags )
|
|||
# else
|
||||
sig_act.sa_flags = 0;
|
||||
# endif
|
||||
ret = sigaction( sig, &sig_act, NULL );
|
||||
ret = SIGACTION( sig, &sig_act, NULL );
|
||||
|
||||
#endif /* linux && __i386__ */
|
||||
|
||||
|
@ -298,9 +315,9 @@ BOOL SIGNAL_Init(void)
|
|||
ss.ss_sp = SIGNAL_Stack;
|
||||
ss.ss_size = sizeof(SIGNAL_Stack);
|
||||
ss.ss_flags = 0;
|
||||
if (sigaltstack(&ss, NULL) < 0)
|
||||
if (SIGALTSTACK(&ss, NULL) < 0)
|
||||
{
|
||||
perror("sigstack");
|
||||
perror("sigaltstack");
|
||||
return FALSE;
|
||||
}
|
||||
#endif /* HAVE_SIGALTSTACK */
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
* Copyright 1998 Alexandre Julliard
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/* 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. */
|
||||
extern int errno;
|
||||
|
@ -14,11 +16,15 @@ static int *ph_errno = &h_errno;
|
|||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_SYS_SYSCALL_H
|
||||
# include <sys/syscall.h>
|
||||
#endif
|
||||
#include "thread.h"
|
||||
#include "server.h"
|
||||
#include "winbase.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
/* Xlib critical section (FIXME: does not belong here) */
|
||||
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 linux
|
||||
/***********************************************************************
|
||||
* __errno_location
|
||||
*
|
||||
|
@ -72,6 +79,20 @@ int *__h_errno_location()
|
|||
#endif
|
||||
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
|
||||
|
@ -107,7 +128,23 @@ int SYSDEPS_SpawnThread( THDB *thread )
|
|||
#endif
|
||||
|
||||
#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
|
||||
|
||||
#else /* !USE_THREADS */
|
||||
|
|
Loading…
Reference in New Issue