]> granicus.if.org Git - gc/commitdiff
2010-12-26 Ivan Maidanski <ivmai@mail.ru> (mostly really Geoff Norton
authorivmai <ivmai>
Sun, 26 Dec 2010 14:20:38 +0000 (14:20 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 17:06:55 +0000 (21:06 +0400)
                                             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.

ChangeLog
configure
configure.ac
dyn_load.c
include/private/gcconfig.h
include/private/pthread_support.h
pthread_stop_world.c
pthread_support.c

index f44f0382085a685d676df45a520e9dd6381ef7f8..382fa1b005df610d5b411c5a003dade1e8f2b618 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2010-12-26  Ivan Maidanski  <ivmai@mail.ru> (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  <ivmai@mail.ru>
 
        * allchblk.c (GC_freehblk): Print extended error message (done via
index b3c4c5443c17a260a7571b0694cb64f1a210e348..8c64a21785d158d05787b4836d0c362d3821b110 100755 (executable)
--- 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
index 748499dd6744a510cee60cd136e3db728782ecf7..e4c62e747ec8f9ceb59d9f7ad0bcc6905413a648 100644 (file)
@@ -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)
index 9927a21fbb29ea7120f7d6013d856924f65c2490..37dd75a2c7d8d4a05d34dd71172ba382b74b3d31 100644 (file)
@@ -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++)) ) {
index 672e7fbe215e4e4432916ad5cca70e088f3d6765..d85053bd535d27208b70d3d34cf0e9b8da87f9b2 100644 (file)
 #   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__)
 #            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 */
 #     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
 
index ea827c581a861a5e005336a00f586e5dd5eda9a2..e028dfe055b288e8695c2ffcd4e68cd1bb1e1d98 100644 (file)
@@ -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;
 
index 96bd79297e1ee1c45de2f1334c8eb2b3250ca714..64789803741d6e356bbae47e26cc1bd8989dfc7e 100644 (file)
@@ -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? */
index 6041a66a260a2850005ada7d1e1ff6a2c76f9096..26460a7911022a1684228e68cd02ca8e17f0fbde 100644 (file)
@@ -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);