diff options
author | Sebastian Pop <pop@cri.ensmp.fr> | 2006-10-12 05:59:39 +0000 |
---|---|---|
committer | Sebastian Pop <pop@cri.ensmp.fr> | 2006-10-12 05:59:39 +0000 |
commit | 9e5987162de0a269bf1cbdcf9a01fc959de02270 (patch) | |
tree | 17936f0b8a15b40a7b7e8e3b814181196704e872 /boehm-gc | |
parent | b66d28634db198076db2d210e93ec17e2a3b045e (diff) |
* Merge from mainline (r115016:117632).
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/graphite@117659 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'boehm-gc')
-rw-r--r-- | boehm-gc/ChangeLog | 46 | ||||
-rwxr-xr-x | boehm-gc/configure | 162 | ||||
-rw-r--r-- | boehm-gc/configure.ac | 39 | ||||
-rw-r--r-- | boehm-gc/darwin_stop_world.c | 18 | ||||
-rw-r--r-- | boehm-gc/dyn_load.c | 4 | ||||
-rw-r--r-- | boehm-gc/include/gc.h | 22 | ||||
-rw-r--r-- | boehm-gc/include/gc_config.h.in | 9 | ||||
-rw-r--r-- | boehm-gc/include/gc_ext_config.h.in | 2 | ||||
-rw-r--r-- | boehm-gc/include/gc_pthread_redirects.h | 2 | ||||
-rw-r--r-- | boehm-gc/include/private/gcconfig.h | 66 | ||||
-rw-r--r-- | boehm-gc/misc.c | 8 | ||||
-rw-r--r-- | boehm-gc/os_dep.c | 10 | ||||
-rw-r--r-- | boehm-gc/pthread_support.c | 138 |
13 files changed, 431 insertions, 95 deletions
diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog index 6e2b3a86112d..b8183a56989b 100644 --- a/boehm-gc/ChangeLog +++ b/boehm-gc/ChangeLog @@ -1,3 +1,49 @@ +2006-09-26 Jack Howarth <howarth@bromo.med.uc.edu> + + PR target/29180 + * darwin_stop_world.c: Make stack_start unsigned long. + +2006-09-21 Sandro Tolaini <tolaini@libero.it> + + * os_dep.c: Port to Darwin/i386 + * darwin_stop_world.c: Likewise + * include/private/gcconfig.h: Likewise + +2006-06-07 Petr Salinger <Petr.Salinger@seznam.cz> + + * configure.ac: add support for GNU/kFreeBSD, accepted by upstream + for gc 6.8. + * dyn_load.c: Likewise. + * include/gc.h: Likewise. + * private/gcconfig.h: Likewise. + * configure: Regenerate. + * include/gc_config.h.in: Regenerate. + +2006-09-14 Tom Tromey <tromey@redhat.com> + + PR boehm-gc/29068. + * misc.c (GC_init_inner): Don't use GC_get_thread_stack_base on + Solaris. + +2006-08-21 Bryce McKinlay <mckinlay@redhat.com> + + PR libgcj/13212: + * configure.ac: Check for pthread_getattr_np(). Remove + GC_PTHREAD_SYM_VERSION detection. + * include/gc.h (GC_register_my_thread, GC_unregister_my_thread, + GC_get_thread_stack_base): New declarations. + * pthread_support.c (GC_register_my_thread, GC_unregister_my_thread, + GC_get_thread_stack_base): New functions. + (GC_delete_thread): Don't try to free the first_thread. + * misc.c (GC_init_inner): Use GC_get_thread_stack_base() if possible. + (pthread_create_, constr): Removed. + (pthread_create): Don't rename. + * include/gc_ext_config.h.in: Rebuilt. + * include/gc_pthread_redirects.h (pthread_create): Define + unconditionally. + * include/gc_config.h.in: Rebuilt. + * configure: Rebuilt. + 2006-06-21 Keith Seitz <keiths@redhat.com> * pthread_stop_world.c (GC_suspend_handler): Redirect to suspension diff --git a/boehm-gc/configure b/boehm-gc/configure index 2b9d6f5f6e61..00b14305f95b 100755 --- a/boehm-gc/configure +++ b/boehm-gc/configure @@ -5444,6 +5444,32 @@ _ACEOF { echo "$as_me:$LINENO: WARNING: \"Only HP-UX 11 POSIX threads are supported.\"" >&5 echo "$as_me: WARNING: \"Only HP-UX 11 POSIX threads are supported.\"" >&2;} ;; + *-*-kfreebsd*-gnu) + cat >>confdefs.h <<\_ACEOF +#define GC_FREEBSD_THREADS 1 +_ACEOF + + INCLUDES="$INCLUDES -pthread" + THREADDLLIBS=-pthread + cat >>confdefs.h <<\_ACEOF +#define _REENTRANT 1 +_ACEOF + + if test "${enable_parallel_mark}" = yes; then + cat >>confdefs.h <<\_ACEOF +#define PARALLEL_MARK 1 +_ACEOF + + fi + cat >>confdefs.h <<\_ACEOF +#define THREAD_LOCAL_ALLOC 1 +_ACEOF + + cat >>confdefs.h <<\_ACEOF +#define USE_COMPILER_TLS 1 +_ACEOF + + ;; *-*-freebsd*) { echo "$as_me:$LINENO: WARNING: \"FreeBSD does not yet fully support threads with Boehm GC.\"" >&5 echo "$as_me: WARNING: \"FreeBSD does not yet fully support threads with Boehm GC.\"" >&2;} @@ -6445,6 +6471,119 @@ echo "${ECHO_T}yes" >&6 ;; esac +# Checks for pthreads functions +# +oldLIBS="$LIBS" +LIBS="$LIBS $THREADLIBS" + +for ac_func in pthread_getattr_np +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test x$gcc_no_link = xyes; then + { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5 +echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;} + { (exit 1); exit 1; }; } +fi +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +LIBS="$oldLIBS" + # Configuration of machine-dependent code # # We don't set NO_EXECUTE_PERMISSION by default because gcj (and @@ -7313,29 +7452,6 @@ _ACEOF fi -symver= -case "$target" in - *-*-linux* ) - cat > conftest.c <<EOF -#include <pthread.h> -void *tf (void *arg) { (void) arg; return NULL; } -int main (void) { pthread_t th; pthread_create (&th, NULL, tf, NULL); return 0; } -EOF - if $CC $CFLAGS -pthread -o conftest conftest.c > /dev/null 2>&1; then - symver=`readelf -s conftest 2> /dev/null | sed -n '/UND pthread_create@/{s/^.*@//;s/ .*$//;p;q}'` - fi - rm -f conftest conftest.c - ;; -esac -if test -n "$symver"; then - -cat >>confdefs.h <<_ACEOF -#define GC_PTHREAD_SYM_VERSION "$symver" -_ACEOF - -fi - - if test -n "$with_cross_host" && test x"$with_cross_host" != x"no"; then toolexecdir='$(exec_prefix)/$(target_noncanonical)' diff --git a/boehm-gc/configure.ac b/boehm-gc/configure.ac index b1d53cf6a887..45937dcf9b92 100644 --- a/boehm-gc/configure.ac +++ b/boehm-gc/configure.ac @@ -1,4 +1,4 @@ -# Copyright (c) 1999, 2000, 2001, 2002, 2003 by Red Hat, Inc. All rights reserved. +# Copyright (c) 1999, 2000, 2001, 2002, 2003, 2006 by Red Hat, Inc. All rights reserved. # Copyright 2004 Nathanael Nerode # # THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED @@ -155,6 +155,17 @@ case "$THREADS" in *-*-hpux10*) AC_MSG_WARN("Only HP-UX 11 POSIX threads are supported.") ;; + *-*-kfreebsd*-gnu) + AC_DEFINE(GC_FREEBSD_THREADS) + INCLUDES="$INCLUDES -pthread" + THREADDLLIBS=-pthread + AC_DEFINE(_REENTRANT) + if test "${enable_parallel_mark}" = yes; then + AC_DEFINE(PARALLEL_MARK) + fi + AC_DEFINE(THREAD_LOCAL_ALLOC) + AC_DEFINE(USE_COMPILER_TLS, 1,[use tls for boehm]) + ;; *-*-freebsd*) AC_MSG_WARN("FreeBSD does not yet fully support threads with Boehm GC.") AC_DEFINE(GC_FREEBSD_THREADS,1,[support FreeBSD threads]) @@ -329,6 +340,13 @@ case "$host" in ;; esac +# Checks for pthreads functions +# +oldLIBS="$LIBS" +LIBS="$LIBS $THREADLIBS" +AC_CHECK_FUNCS([pthread_getattr_np]) +LIBS="$oldLIBS" + # Configuration of machine-dependent code # # We don't set NO_EXECUTE_PERMISSION by default because gcj (and @@ -488,25 +506,6 @@ if test "${gc_use_mmap}" = "yes"; then AC_DEFINE(USE_MMAP, 1, [use MMAP instead of sbrk to get new memory]) fi -symver= -case "$target" in - *-*-linux* ) - cat > conftest.c <<EOF -#include <pthread.h> -void *tf (void *arg) { (void) arg; return NULL; } -int main (void) { pthread_t th; pthread_create (&th, NULL, tf, NULL); return 0; } -EOF - if $CC $CFLAGS -pthread -o conftest conftest.c > /dev/null 2>&1; then - symver=`readelf -s conftest 2> /dev/null | sed -n '/UND pthread_create@/{s/^.*@//;s/ .*$//;p;q}'` - fi - rm -f conftest conftest.c - ;; -esac -if test -n "$symver"; then - AC_DEFINE_UNQUOTED(GC_PTHREAD_SYM_VERSION, "$symver", [symbol version of pthread_create]) -fi - - if test -n "$with_cross_host" && test x"$with_cross_host" != x"no"; then toolexecdir='$(exec_prefix)/$(target_noncanonical)' diff --git a/boehm-gc/darwin_stop_world.c b/boehm-gc/darwin_stop_world.c index 895fdb61a647..29845923bb5c 100644 --- a/boehm-gc/darwin_stop_world.c +++ b/boehm-gc/darwin_stop_world.c @@ -61,7 +61,7 @@ typedef struct StackFrame { unsigned long savedRTOC; } StackFrame; -unsigned long FindTopOfStack(unsigned int stack_start) { +unsigned long FindTopOfStack(unsigned long stack_start) { StackFrame *frame; if (stack_start == 0) { @@ -125,7 +125,18 @@ void GC_push_all_stacks() { (natural_t*)&state, &thread_state_count); if(r != KERN_SUCCESS) ABORT("thread_get_state failed"); - + +#if defined(I386) + lo = state.esp; + + GC_push_one(state.eax); + GC_push_one(state.ebx); + GC_push_one(state.ecx); + GC_push_one(state.edx); + GC_push_one(state.edi); + GC_push_one(state.esi); + GC_push_one(state.ebp); +#elif defined(POWERPC) lo = (void*)(state . THREAD_FLD (r1) - PPC_RED_ZONE_SIZE); GC_push_one(state . THREAD_FLD (r0)); @@ -159,6 +170,9 @@ void GC_push_all_stacks() { GC_push_one(state . THREAD_FLD (r29)); GC_push_one(state . THREAD_FLD (r30)); GC_push_one(state . THREAD_FLD (r31)); +#else +# error FIXME for non-x86 || ppc architectures +#endif } /* p != me */ if(p->flags & MAIN_THREAD) hi = GC_stackbottom; diff --git a/boehm-gc/dyn_load.c b/boehm-gc/dyn_load.c index 3485474bee51..d82bad8efaed 100644 --- a/boehm-gc/dyn_load.c +++ b/boehm-gc/dyn_load.c @@ -26,7 +26,7 @@ * None of this is safe with dlclose and incremental collection. * But then not much of anything is safe in the presence of dlclose. */ -#if defined(__linux__) && !defined(_GNU_SOURCE) +#if (defined(__linux__) || defined(__GLIBC__)) && !defined(_GNU_SOURCE) /* Can't test LINUX, since this must be define before other includes */ # define _GNU_SOURCE #endif @@ -392,7 +392,7 @@ GC_bool GC_register_main_static_data() /* For glibc 2.2.4+. Unfortunately, it doesn't work for older */ /* versions. Thanks to Jakub Jelinek for most of the code. */ -# if defined(LINUX) /* Are others OK here, too? */ \ +# if (defined(LINUX) || defined (__GLIBC__)) /* Are others OK here, too? */ \ && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \ || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG))) diff --git a/boehm-gc/include/gc.h b/boehm-gc/include/gc.h index e6ab2c608c4a..52ee8056ec41 100644 --- a/boehm-gc/include/gc.h +++ b/boehm-gc/include/gc.h @@ -69,7 +69,6 @@ extern "C" { # endif - /* Define word and signed_word to be unsigned and signed types of the */ /* size as char * or void *. There seems to be no way to do this */ /* even semi-portably. The following is probably no better/worse */ @@ -500,7 +499,7 @@ GC_API GC_PTR GC_malloc_atomic_ignore_off_page GC_PROTO((size_t lb)); # define GC_RETURN_ADDR (GC_word)__return_address #endif -#ifdef __linux__ +#if defined(__linux__) || defined(__GLIBC__) # include <features.h> # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \ && !defined(__ia64__) @@ -912,6 +911,25 @@ GC_API void (*GC_is_visible_print_proc) # if defined(PCR) || defined(GC_SOLARIS_THREADS) || \ defined(GC_PTHREADS) || defined(GC_WIN32_THREADS) /* Any flavor of threads except SRC_M3. */ + +/* Register the current thread as a new thread whose stack(s) should */ +/* be traced by the GC. */ +/* If a platform does not implicitly do so, this must be called before */ +/* a thread can allocate garbage collected memory, or assign pointers */ +/* to the garbage collected heap. Once registered, a thread will be */ +/* stopped during garbage collections. */ +GC_API void GC_register_my_thread GC_PROTO((void)); + +/* Register the current thread, with the indicated stack base, as */ +/* a new thread whose stack(s) should be traced by the GC. If a */ +/* platform does not implicitly do so, this must be called before a */ +/* thread can allocate garbage collected memory, or assign pointers */ +/* to the garbage collected heap. Once registered, a thread will be */ +/* stopped during garbage collections. */ +GC_API void GC_unregister_my_thread GC_PROTO((void)); + +GC_API GC_PTR GC_get_thread_stack_base GC_PROTO((void)); + /* This returns a list of objects, linked through their first */ /* word. Its use can greatly reduce lock contention problems, since */ /* the allocation lock can be acquired and released many fewer times. */ diff --git a/boehm-gc/include/gc_config.h.in b/boehm-gc/include/gc_config.h.in index 401de609ba6a..41028c14eb16 100644 --- a/boehm-gc/include/gc_config.h.in +++ b/boehm-gc/include/gc_config.h.in @@ -45,9 +45,6 @@ /* support for Tru64 pthreads */ #undef GC_OSF1_THREADS -/* symbol version of pthread_create */ -#undef GC_PTHREAD_SYM_VERSION - /* support for Solaris pthreads */ #undef GC_SOLARIS_PTHREADS @@ -81,6 +78,9 @@ /* Define to 1 if you have the <memory.h> header file. */ #undef HAVE_MEMORY_H +/* Define to 1 if you have the `pthread_getattr_np' function. */ +#undef HAVE_PTHREAD_GETATTR_NP + /* Define to 1 if you have the <stdint.h> header file. */ #undef HAVE_STDINT_H @@ -166,6 +166,9 @@ /* define GC_local_malloc() & GC_local_malloc_atomic() */ #undef THREAD_LOCAL_ALLOC +/* use tls for boehm */ +#undef USE_COMPILER_TLS + /* use MMAP instead of sbrk to get new memory */ #undef USE_MMAP diff --git a/boehm-gc/include/gc_ext_config.h.in b/boehm-gc/include/gc_ext_config.h.in index 716143dc62f5..219ba2fb8c8e 100644 --- a/boehm-gc/include/gc_ext_config.h.in +++ b/boehm-gc/include/gc_ext_config.h.in @@ -4,4 +4,4 @@ is used by libjava/include/boehm-gc.h. */ #undef THREAD_LOCAL_ALLOC -#undef GC_PTHREAD_SYM_VERSION +#undef HAVE_PTHREAD_GETATTR_NP diff --git a/boehm-gc/include/gc_pthread_redirects.h b/boehm-gc/include/gc_pthread_redirects.h index f9d4939affcd..842518cfcc48 100644 --- a/boehm-gc/include/gc_pthread_redirects.h +++ b/boehm-gc/include/gc_pthread_redirects.h @@ -68,9 +68,7 @@ # undef pthread_detach #endif -#ifndef GC_PTHREAD_SYM_VERSION # define pthread_create GC_pthread_create -#endif # define pthread_join GC_pthread_join # define pthread_detach GC_pthread_detach diff --git a/boehm-gc/include/private/gcconfig.h b/boehm-gc/include/private/gcconfig.h index c028e5dbf6cf..26db82ee5376 100644 --- a/boehm-gc/include/private/gcconfig.h +++ b/boehm-gc/include/private/gcconfig.h @@ -55,7 +55,7 @@ # endif /* And one for FreeBSD: */ -# if defined(__FreeBSD__) && !defined(FREEBSD) +# if ( defined(__FreeBSD__) || defined(__FreeBSD_kernel__) ) && !defined(FREEBSD) # define FREEBSD # endif @@ -304,7 +304,7 @@ # define mach_type_known # elif defined(__i386__) # define I386 - --> Not really supported, but at least we recognize it. +# define mach_type_known # endif # endif # if defined(NeXT) && defined(mc68000) @@ -1241,8 +1241,15 @@ # ifndef GC_FREEBSD_THREADS # define MPROTECT_VDB # endif -# define SIG_SUSPEND SIGUSR1 -# define SIG_THR_RESTART SIGUSR2 +# ifdef __GLIBC__ +# define SIG_SUSPEND (32+6) +# define SIG_THR_RESTART (32+5) + extern int _end[]; +# define DATAEND (_end) +# else +# define SIG_SUSPEND SIGUSR1 +# define SIG_THR_RESTART SIGUSR2 +# endif # define FREEBSD_STACKBOTTOM # ifdef __ELF__ # define DYNAMIC_LOADING @@ -1301,6 +1308,29 @@ /* # define MPROTECT_VDB Not quite working yet? */ # define DYNAMIC_LOADING # endif +# ifdef DARWIN +# define OS_TYPE "DARWIN" +# define DARWIN_DONT_PARSE_STACK +# define DYNAMIC_LOADING + /* XXX: see get_end(3), get_etext() and get_end() should not be used. + These aren't used when dyld support is enabled (it is by default) */ +# define DATASTART ((ptr_t) get_etext()) +# define DATAEND ((ptr_t) get_end()) +# define STACKBOTTOM ((ptr_t) 0xc0000000) +# define USE_MMAP +# define USE_MMAP_ANON +# define USE_ASM_PUSH_REGS + /* This is potentially buggy. It needs more testing. See the comments in + os_dep.c. It relies on threads to track writes. */ +# ifdef GC_DARWIN_THREADS +/* # define MPROTECT_VDB -- disabled for now. May work for some apps. */ +# endif +# include <unistd.h> +# define GETPAGESIZE() getpagesize() + /* There seems to be some issues with trylock hanging on darwin. This + should be looked into some more */ +# define NO_PTHREAD_TRYLOCK +# endif /* DARWIN */ # endif # ifdef NS32K @@ -1952,6 +1982,28 @@ # define PREFETCH_FOR_WRITE(x) __builtin_prefetch((x), 1) # endif # endif +# ifdef FREEBSD +# define OS_TYPE "FREEBSD" +# ifndef GC_FREEBSD_THREADS +# define MPROTECT_VDB +# endif +# ifdef __GLIBC__ +# define SIG_SUSPEND (32+6) +# define SIG_THR_RESTART (32+5) + extern int _end[]; +# define DATAEND (_end) +# else +# define SIG_SUSPEND SIGUSR1 +# define SIG_THR_RESTART SIGUSR2 +# endif +# define FREEBSD_STACKBOTTOM +# ifdef __ELF__ +# define DYNAMIC_LOADING +# endif + extern char etext[]; + extern char * GC_FreeBSDGetDataStart(); +# define DATASTART GC_FreeBSDGetDataStart(0x1000, &etext) +# endif # ifdef NETBSD # define OS_TYPE "NETBSD" # ifdef __ELF__ @@ -2023,7 +2075,7 @@ # define SUNOS5SIGS # endif -# if defined(FREEBSD) && (__FreeBSD__ >= 4) +# if defined(FREEBSD) && ((__FreeBSD__ >= 4) || (__FreeBSD_kernel__ >= 4)) # define SUNOS5SIGS # endif @@ -2086,7 +2138,7 @@ # define CACHE_LINE_SIZE 32 /* Wild guess */ # endif -# ifdef LINUX +# if defined(LINUX) || defined(__GLIBC__) # define REGISTER_LIBRARIES_EARLY /* We sometimes use dl_iterate_phdr, which may acquire an internal */ /* lock. This isn't safe after the world has stopped. So we must */ @@ -2167,7 +2219,7 @@ #if defined(SPARC) # define CAN_SAVE_CALL_ARGS #endif -#if (defined(I386) || defined(X86_64)) && defined(LINUX) +#if (defined(I386) || defined(X86_64)) && (defined(LINUX) || defined(__GLIBC__)) /* SAVE_CALL_CHAIN is supported if the code is compiled to save */ /* frame pointers by default, i.e. no -fomit-frame-pointer flag. */ # define CAN_SAVE_CALL_ARGS diff --git a/boehm-gc/misc.c b/boehm-gc/misc.c index 89f05ba1dc93..069c7d57ad00 100644 --- a/boehm-gc/misc.c +++ b/boehm-gc/misc.c @@ -674,7 +674,13 @@ void GC_init_inner() # if !defined(THREADS) || defined(GC_PTHREADS) || defined(GC_WIN32_THREADS) \ || defined(GC_SOLARIS_THREADS) if (GC_stackbottom == 0) { - GC_stackbottom = GC_get_stack_base(); + # if defined(GC_PTHREADS) && ! defined(GC_SOLARIS_THREADS) + /* Use thread_stack_base if available, as GC could be initialized from + a thread that is not the "main" thread. */ + GC_stackbottom = GC_get_thread_stack_base(); + # endif + if (GC_stackbottom == 0) + GC_stackbottom = GC_get_stack_base(); # if (defined(LINUX) || defined(HPUX)) && defined(IA64) GC_register_stackbottom = GC_get_register_stack_base(); # endif diff --git a/boehm-gc/os_dep.c b/boehm-gc/os_dep.c index 13692d9bcd65..98ab6be5356e 100644 --- a/boehm-gc/os_dep.c +++ b/boehm-gc/os_dep.c @@ -3802,6 +3802,10 @@ catch_exception_raise( mach_msg_type_number_t exc_state_count = PPC_EXCEPTION_STATE64_COUNT; ppc_exception_state64_t exc_state; # endif +# elif defined(I386) + thread_state_flavor_t flavor = i386_EXCEPTION_STATE; + mach_msg_type_number_t exc_state_count = i386_EXCEPTION_STATE_COUNT; + i386_exception_state_t exc_state; # else # error FIXME for non-ppc darwin # endif @@ -3833,7 +3837,13 @@ catch_exception_raise( } /* This is the address that caused the fault */ +#if defined(POWERPC) addr = (char*) exc_state.dar; +#elif defined (I386) + addr = (char*) exc_state.faultvaddr; +#else +# error FIXME for non POWERPC/I386 +#endif if((HDR(addr)) == 0) { /* Ugh... just like the SIGBUS problem above, it seems we get a bogus diff --git a/boehm-gc/pthread_support.c b/boehm-gc/pthread_support.c index 55872ef65c88..bbda8522c030 100644 --- a/boehm-gc/pthread_support.c +++ b/boehm-gc/pthread_support.c @@ -602,7 +602,9 @@ void GC_delete_thread(pthread_t id) } else { prev -> next = p -> next; } - GC_INTERNAL_FREE(p); + + if (p != &first_thread) + GC_INTERNAL_FREE(p); } /* If a thread has been joined, but we have not yet */ @@ -1124,6 +1126,107 @@ WRAP_FUNC(pthread_detach)(pthread_t thread) GC_bool GC_in_thread_creation = FALSE; +GC_PTR GC_get_thread_stack_base() +{ +# ifdef HAVE_PTHREAD_GETATTR_NP + pthread_t my_pthread; + pthread_attr_t attr; + ptr_t stack_addr; + size_t stack_size; + + my_pthread = pthread_self(); + pthread_getattr_np (my_pthread, &attr); + pthread_attr_getstack (&attr, (void **) &stack_addr, &stack_size); + pthread_attr_destroy (&attr); + +# ifdef DEBUG_THREADS + GC_printf1("attached thread stack address: 0x%x\n", stack_addr); +# endif + +# ifdef STACK_GROWS_DOWN + return stack_addr + stack_size; +# else + return stack_addr - stack_size; +# endif + +# else +# ifdef DEBUG_THREADS + GC_printf1("Can not determine stack base for attached thread"); +# endif + return 0; +# endif +} + +void GC_register_my_thread() +{ + GC_thread me; + pthread_t my_pthread; + + my_pthread = pthread_self(); +# ifdef DEBUG_THREADS + GC_printf1("Attaching thread 0x%lx\n", my_pthread); + GC_printf1("pid = %ld\n", (long) getpid()); +# endif + + /* Check to ensure this thread isn't attached already. */ + LOCK(); + me = GC_lookup_thread (my_pthread); + UNLOCK(); + if (me != 0) + { +# ifdef DEBUG_THREADS + GC_printf1("Attempt to re-attach known thread 0x%lx\n", my_pthread); +# endif + return; + } + + LOCK(); + GC_in_thread_creation = TRUE; + me = GC_new_thread(my_pthread); + GC_in_thread_creation = FALSE; + + me -> flags |= DETACHED; + +#ifdef GC_DARWIN_THREADS + me -> stop_info.mach_thread = mach_thread_self(); +#else + me -> stack_end = GC_get_thread_stack_base(); + if (me -> stack_end == 0) + GC_abort("Can not determine stack base for attached thread"); + +# ifdef STACK_GROWS_DOWN + me -> stop_info.stack_ptr = me -> stack_end - 0x10; +# else + me -> stop_info.stack_ptr = me -> stack_end + 0x10; +# endif +#endif + +# ifdef IA64 + me -> backing_store_end = (ptr_t) + (GC_save_regs_in_stack() & ~(GC_page_size - 1)); + /* This is also < 100% convincing. We should also read this */ + /* from /proc, but the hook to do so isn't there yet. */ +# endif /* IA64 */ + +# if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL) + GC_init_thread_local(me); +# endif + UNLOCK(); +} + +void GC_unregister_my_thread() +{ + pthread_t my_pthread; + + my_pthread = pthread_self(); + +# ifdef DEBUG_THREADS + GC_printf1("Detaching thread 0x%lx\n", my_pthread); +# endif + + GC_thread_exit_proc (0); +} + void * GC_start_routine(void * arg) { int dummy; @@ -1200,37 +1303,8 @@ void * GC_start_routine(void * arg) return(result); } -#ifdef GC_PTHREAD_SYM_VERSION - -/* Force constr to execute prior to main(). */ -static void constr (void) __attribute__ ((constructor)); - -static int -(*pthread_create_)(pthread_t *new_thread, - const pthread_attr_t *attr_in, - void * (*thread_execp)(void *), void *arg); - -static void -constr (void) -{ - /* Get a pointer to the real pthread_create. */ - pthread_create_ = dlvsym (RTLD_NEXT, "pthread_create", - GC_PTHREAD_SYM_VERSION); -} - -#define GC_PTHREAD_CREATE_NAME pthread_create -#define GC_PTHREAD_REAL_NAME (*pthread_create_) - -#else - -#define GC_PTHREAD_CREATE_NAME WRAP_FUNC(pthread_create) -#define GC_PTHREAD_REAL_NAME REAL_FUNC(pthread_create) - -#endif - - int -GC_PTHREAD_CREATE_NAME(pthread_t *new_thread, +WRAP_FUNC(pthread_create)(pthread_t *new_thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { @@ -1291,7 +1365,7 @@ GC_PTHREAD_CREATE_NAME(pthread_t *new_thread, pthread_self()); # endif - result = GC_PTHREAD_REAL_NAME(new_thread, attr, GC_start_routine, si); + result = REAL_FUNC(pthread_create)(new_thread, attr, GC_start_routine, si); # ifdef DEBUG_THREADS GC_printf1("Started thread 0x%X\n", *new_thread); |