Work around Android's pthread/kernel_id/fork bug to fix mono multithreading and GC_st...
authorKoushik Dutta <koushd@gmail.com>
Thu, 30 Sep 2010 04:15:42 +0000 (21:15 -0700)
committerGeoff Norton <grompf@sublimeintervention.com>
Fri, 1 Oct 2010 16:33:18 +0000 (12:33 -0400)
libgc/include/private/pthread_support.h
libgc/pthread_stop_world.c
libgc/pthread_support.c

index c2c48c22e01a2c889f0d2f3d8a092d07777f20fd..ec53e46fc45320a4760d073f49469ff4431057fa 100644 (file)
@@ -26,6 +26,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 04eb3712c263d9831af128e93c174c61e813635c..603aff7866221122aaff8bfd42b84f986f0c714a 100644 (file)
@@ -314,6 +314,22 @@ void GC_push_all_stacks()
 pthread_t GC_stopping_thread;
 int GC_stopping_pid;
 
+#ifdef PLATFORM_ANDROID
+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
+
 /* We hold the allocation lock.  Suspend all threads that might        */
 /* still be running.  Return the number of suspend signals that        */
 /* were sent. */
@@ -337,8 +353,12 @@ int GC_suspend_all()
            #if DEBUG_THREADS
              GC_printf1("Sending suspend signal to 0x%lx\n", p -> id);
            #endif
-        
+
+#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? */
@@ -465,8 +485,12 @@ static void pthread_start_world()
            #if DEBUG_THREADS
              GC_printf1("Sending restart signal to 0x%lx\n", p -> id);
            #endif
-        
+
+#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 f0132044a098c982ac032a2695d97f80c87238bc..f70d4f6e731a87cee6bc9dcf3f00d6b7b22b2464 100644 (file)
@@ -692,6 +692,9 @@ 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);