diff mbox

libgo patch committed: Adjust deadlock avoidance

Message ID mcrhbd1bs5z.fsf@google.com
State New
Headers show

Commit Message

Ian Lance Taylor Jan. 22, 2011, 2:15 a.m. UTC
Because the finalizer code can call the malloc code but not vice-versa,
deadlock avoidance should test whether we have the finalizer lock before
testing whether we are doing an malloc.  Otherwise we can have malloc
deciding to run a gc even when the finalizer lock is still held.
Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian
diff mbox

Patch

diff -r f68f39af572b libgo/runtime/go-go.c
--- a/libgo/runtime/go-go.c	Fri Jan 21 17:58:59 2011 -0800
+++ b/libgo/runtime/go-go.c	Fri Jan 21 18:09:14 2011 -0800
@@ -297,6 +297,15 @@ 
 {
   struct M *pm = m;
 
+  if (__sync_bool_compare_and_swap (&pm->holds_finlock, 1, 1))
+    {
+      /* We can't interrupt the thread while it holds the finalizer
+	 lock.  Otherwise we can get into a deadlock when mark calls
+	 runtime_walkfintab.  */
+      __sync_bool_compare_and_swap (&pm->gcing_for_finlock, 0, 1);
+      return;
+    }
+
   if (__sync_bool_compare_and_swap (&pm->mallocing, 1, 1))
     {
       /* m->mallocing was already non-zero.  We can't interrupt the
@@ -315,15 +324,6 @@ 
       return;
     }
 
-  if (__sync_bool_compare_and_swap (&pm->holds_finlock, 1, 1))
-    {
-      /* Similarly, we can't interrupt the thread while it holds the
-	 finalizer lock.  Otherwise we can get into a deadlock when
-	 mark calls runtime_walkfintab.  */
-      __sync_bool_compare_and_swap (&pm->gcing_for_finlock, 0, 1);
-      return;
-    }
-
   stop_for_gc ();
 }