[Gc] thread suspend on darwin

Paolo Molaro lupus at debian.org
Wed May 19 08:56:00 PDT 2004


On 05/18/04 Andrew Begel wrote:
> You can't just ignore the failed thread_info() and thread_suspend() 
> calls, because in GC_start_world(), you'll encounter them again trying 
> to wake up dead threads. It might be better to add a field to struct 

When I tried it, just replacing the abort with a continue was enough
(since GC_mach_threads_count is not increased that way).

> GC_mach_thread to record if a thread died in the middle of trying to 
> suspend it (it can't die during wake up, since it's suspended and not 
> running), and not wake it up. If memory is at a premium, we could 
> easily overload the GC_mach_thread.already_suspended boolean, since the 
> logic is the same (if a thread was already suspended when we called 
> GC_stop_world(), then GC_start_world() should not try to start it).

The attached patch does this and it seems to work just as well.
The patch doesn't ignore an error on resume and it ignores any error
from the syscall: looking at the header file there are several error
codes that could be returned so checking just for MACH_SEND_INVALID_DEST
seems more fragile to me.

lupus

-- 
-----------------------------------------------------------------
lupus at debian.org                                     debian/rules
lupus at ximian.com                             Monkeys do it better
-------------- next part --------------
Index: darwin_stop_world.c
===================================================================
RCS file: /cvs/public/libgc/darwin_stop_world.c,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 darwin_stop_world.c
--- darwin_stop_world.c	18 May 2004 18:42:27 -0000	1.1.1.2
+++ darwin_stop_world.c	19 May 2004 15:03:51 -0000
@@ -210,7 +210,16 @@ int GC_suspend_thread_list(thread_act_ar
       mach_msg_type_number_t outCount = THREAD_INFO_MAX;
       kern_return_t kern_result = thread_info(thread, THREAD_BASIC_INFO,
 				(thread_info_t)&info, &outCount);
-      if(kern_result != KERN_SUCCESS) ABORT("thread_info failed");
+      if(kern_result != KERN_SUCCESS) {
+	/* the thread may have quit since the thread_threads () call 
+	 * we mark already_suspended so it's not dealt with anymore later
+	 */
+        if (!found) {
+	  GC_mach_threads[GC_mach_threads_count].already_suspended = TRUE;
+    	  GC_mach_threads_count++;
+	}
+	continue;
+      }
 #     if DEBUG_THREADS
         GC_printf2("Thread state for 0x%lx = %d\n", thread, info.run_state);
 #     endif
@@ -225,7 +234,16 @@ int GC_suspend_thread_list(thread_act_ar
 #     endif
       /* Suspend the thread */
       kern_result = thread_suspend(thread);
-      if(kern_result != KERN_SUCCESS) ABORT("thread_suspend failed");
+      if(kern_result != KERN_SUCCESS) {
+	/* the thread may have quit since the thread_threads () call 
+	 * we mark already_suspended so it's not dealt with anymore later
+	 */
+        if (!found) {
+	  GC_mach_threads[GC_mach_threads_count].already_suspended = TRUE;
+    	  GC_mach_threads_count++;
+	}
+	continue;
+      }
     } 
     if (!found) GC_mach_threads_count++;
   }



More information about the Gc mailing list