From: ivmai Date: Sun, 26 Dec 2010 14:20:38 +0000 (+0000) Subject: 2010-12-26 Ivan Maidanski (mostly really Geoff Norton X-Git-Tag: gc7_2alpha5-20110107~6 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7b66e36f08dd096bc6df1ebc362d2689264f7825;p=gc 2010-12-26 Ivan Maidanski (mostly really Geoff Norton and Jonathan Pryor) * configure.ac: Use AC_CHECK_LIB() to check for pthread instead of just blindly linking to -lpthread, as Android includes pthread support within libc and does not provide a separate libpthread. * dyn_load.c (GC_register_dynamic_libraries): Skip current link map entry if l_addr is NULL (Android/bionic only). * pthread_stop_world.c (android_thread_kill): New internal function (Android only). * pthread_stop_world.c (GC_suspend_all, GC_start_world): Call android_thread_kill (based on tkill) instead of pthread_kill on Android (since pthread_kill cannot be used safely on the platform). * pthread_support.c (GC_new_thread): Store thread Id (obtained from gettid) for use by android_thread_kill (Android only). * include/private/pthread_support.h (GC_Thread_Rep): Add kernel_id structure member (Android only). * include/private/gcconfig.h: Recognize __x86_64 macro as a synonym of __x86_64__ (Darwin); define __environ macro (Android on M68K). * configure: Regenerate. --- diff --git a/ChangeLog b/ChangeLog index f44f0382..382fa1b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2010-12-26 Ivan Maidanski (mostly really Geoff Norton + and Jonathan Pryor) + + * configure.ac: Use AC_CHECK_LIB() to check for pthread instead of + just blindly linking to -lpthread, as Android includes pthread + support within libc and does not provide a separate libpthread. + * dyn_load.c (GC_register_dynamic_libraries): Skip current link map + entry if l_addr is NULL (Android/bionic only). + * pthread_stop_world.c (android_thread_kill): New internal function + (Android only). + * pthread_stop_world.c (GC_suspend_all, GC_start_world): Call + android_thread_kill (based on tkill) instead of pthread_kill on + Android (since pthread_kill cannot be used safely on the platform). + * pthread_support.c (GC_new_thread): Store thread Id (obtained from + gettid) for use by android_thread_kill (Android only). + * include/private/pthread_support.h (GC_Thread_Rep): Add kernel_id + structure member (Android only). + * include/private/gcconfig.h: Recognize __x86_64 macro as a synonym + of __x86_64__ (Darwin); define __environ macro (Android on M68K). + * configure: Regenerate. + 2010-12-02 Ivan Maidanski * allchblk.c (GC_freehblk): Print extended error message (done via diff --git a/configure b/configure index b3c4c544..8c64a217 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac Revision: 1.62 . +# From configure.ac Revision: 1.63 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.67 for gc 7.2alpha5. # @@ -5007,7 +5007,46 @@ case "$THREADS" in ;; posix | pthreads) THREADS=posix - THREADDLLIBS=-lpthread + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_self in -lpthread" >&5 +$as_echo_n "checking for pthread_self in -lpthread... " >&6; } +if test "${ac_cv_lib_pthread_pthread_self+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_self (); +int +main () +{ +return pthread_self (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_pthread_pthread_self=yes +else + ac_cv_lib_pthread_pthread_self=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_self" >&5 +$as_echo "$ac_cv_lib_pthread_pthread_self" >&6; } +if test "x$ac_cv_lib_pthread_pthread_self" = x""yes; then : + THREADDLLIBS="-lpthread" +fi + case "$host" in x86-*-linux* | ia64-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* | alpha-*-linux* | sparc*-*-linux*) $as_echo "#define GC_LINUX_THREADS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index 748499dd..e4c62e74 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ AC_CONFIG_SRCDIR(gcj_mlc.c) AC_CONFIG_MACRO_DIR([m4]) AC_CANONICAL_TARGET AC_PREREQ(2.53) -AC_REVISION($Revision: 1.63 $) +AC_REVISION($Revision: 1.64 $) GC_SET_VERSION AM_INIT_AUTOMAKE([foreign dist-bzip2 nostdinc]) AM_CONFIG_HEADER([include/private/config.h]) @@ -108,7 +108,7 @@ case "$THREADS" in ;; posix | pthreads) THREADS=posix - THREADDLLIBS=-lpthread + AC_CHECK_LIB(pthread, pthread_self, THREADDLLIBS="-lpthread",,) case "$host" in x86-*-linux* | ia64-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* | alpha-*-linux* | sparc*-*-linux*) AC_DEFINE(GC_LINUX_THREADS) diff --git a/dyn_load.c b/dyn_load.c index 9927a21f..37dd75a2 100644 --- a/dyn_load.c +++ b/dyn_load.c @@ -199,6 +199,10 @@ GC_INNER void GC_register_dynamic_libraries(void) int i; e = (ElfW(Ehdr) *) lm->l_addr; +# ifdef PLATFORM_ANDROID + if (e == NULL) + continue; +# endif p = ((ElfW(Phdr) *)(((char *)(e)) + e->e_phoff)); offset = ((unsigned long)(lm->l_addr)); for( i = 0; i < (int)(e->e_phnum); ((i++),(p++)) ) { @@ -652,6 +656,10 @@ GC_INNER void GC_register_dynamic_libraries(void) int i; e = (ElfW(Ehdr) *) lm->l_addr; +# ifdef PLATFORM_ANDROID + if (e == NULL) + continue; +# endif p = ((ElfW(Phdr) *)(((char *)(e)) + e->e_phoff)); offset = ((unsigned long)(lm->l_addr)); for( i = 0; i < (int)(e->e_phnum); ((i++),(p++)) ) { diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index 672e7fbe..d85053bd 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -322,7 +322,7 @@ # if defined(__ppc__) || defined(__ppc64__) # define POWERPC # define mach_type_known -# elif defined(__x86_64__) +# elif defined(__x86_64__) || defined(__x86_64) # define X86_64 # define mach_type_known # elif defined(__i386__) @@ -711,6 +711,9 @@ # if defined(__GLIBC__)&& __GLIBC__>=2 # define SEARCH_FOR_DATA_START # else /* !GLIBC2 */ +# ifdef PLATFORM_ANDROID +# define __environ environ +# endif extern char **__environ; # define DATASTART ((ptr_t)(&__environ)) /* hideous kludge: __environ is the first */ @@ -1378,7 +1381,7 @@ # 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 +# define NO_PTHREAD_TRYLOCK # endif /* DARWIN */ # endif diff --git a/include/private/pthread_support.h b/include/private/pthread_support.h index ea827c58..e028dfe0 100644 --- a/include/private/pthread_support.h +++ b/include/private/pthread_support.h @@ -46,6 +46,9 @@ typedef struct GC_Thread_Rep { /* guaranteed to be dead, but we may */ /* not yet have registered the join.) */ pthread_t id; +# ifdef PLATFORM_ANDROID + pid_t kernel_id; +# endif /* Extra bookkeeping information the stopping code uses */ struct thread_stop_info stop_info; diff --git a/pthread_stop_world.c b/pthread_stop_world.c index 96bd7929..64789803 100644 --- a/pthread_stop_world.c +++ b/pthread_stop_world.c @@ -360,6 +360,22 @@ GC_INNER void GC_push_all_stacks(void) int GC_stopping_pid = 0; #endif +#ifdef PLATFORM_ANDROID + static int android_thread_kill(pid_t tid, int sig) + { + int ret; + int old_errno = errno; + + ret = tkill(tid, sig); + if (ret < 0) { + ret = errno; + errno = old_errno; + } + + return ret; + } +#endif /* PLATFORM_ANDROID */ + /* We hold the allocation lock. Suspend all threads that might */ /* still be running. Return the number of suspend signals that */ /* were sent. */ @@ -402,7 +418,11 @@ STATIC int GC_suspend_all(void) p -> stop_info.stack_ptr = *(ptr_t *)((char *)p -> id + UTHREAD_SP_OFFSET); # else - result = pthread_kill(p -> id, SIG_SUSPEND); +# ifndef PLATFORM_ANDROID + result = pthread_kill(p -> id, SIG_SUSPEND); +# else + result = android_thread_kill(p -> kernel_id, SIG_SUSPEND); +# endif switch(result) { case ESRCH: /* Not really there anymore. Possible? */ @@ -541,9 +561,13 @@ GC_INNER void GC_start_world(void) # ifdef GC_OPENBSD_THREADS if (pthread_resume_np(p -> id) != 0) - ABORT("pthread_kill failed"); + ABORT("pthread_resume_np failed"); # else - result = pthread_kill(p -> id, SIG_THR_RESTART); +# ifndef PLATFORM_ANDROID + result = pthread_kill(p -> id, SIG_THR_RESTART); +# else + result = android_thread_kill(p -> kernel_id, SIG_THR_RESTART); +# endif switch(result) { case ESRCH: /* Not really there anymore. Possible? */ diff --git a/pthread_support.c b/pthread_support.c index 6041a66a..26460a79 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -460,6 +460,9 @@ STATIC GC_thread GC_new_thread(pthread_t id) if (result == 0) return(0); } result -> id = id; +# ifdef PLATFORM_ANDROID + result -> kernel_id = gettid(); +# endif result -> next = GC_threads[hv]; GC_threads[hv] = result; GC_ASSERT(result -> flags == 0 && result -> thread_blocked == 0);