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
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 */
......
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