]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix spurious deadlock crashes
authorDmitriy Vyukov <dvyukov@google.com>
Tue, 16 Oct 2012 10:41:32 +0000 (14:41 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Tue, 16 Oct 2012 10:41:32 +0000 (14:41 +0400)
Fixes #4243.

R=golang-dev, iant
CC=golang-dev, sebastien.paolacci
https://golang.org/cl/6682050

src/pkg/runtime/mheap.c

index 7463b6bff768fa623c76311e1a26525347596e82..0946adcb9f0cb4702b7efca20b32f1cba86334c7 100644 (file)
@@ -343,6 +343,13 @@ MHeap_FreeLocked(MHeap *h, MSpan *s)
                runtime·MSpanList_Insert(&h->large, s);
 }
 
+static void
+forcegchelper(Note *note)
+{
+       runtime·gc(1);
+       runtime·notewakeup(note);
+}
+
 // Release (part of) unused memory to OS.
 // Goroutine created at startup.
 // Loop forever.
@@ -356,7 +363,7 @@ runtime·MHeap_Scavenger(void)
        uintptr released, sumreleased;
        byte *env;
        bool trace;
-       Note note;
+       Note note, *notep;
 
        // If we go two minutes without a garbage collection, force one to run.
        forcegc = 2*60*1e9;
@@ -385,7 +392,15 @@ runtime·MHeap_Scavenger(void)
                now = runtime·nanotime();
                if(now - mstats.last_gc > forcegc) {
                        runtime·unlock(h);
-                       runtime·gc(1);
+                       // The scavenger can not block other goroutines,
+                       // otherwise deadlock detector can fire spuriously.
+                       // GC blocks other goroutines via the runtime·worldsema.
+                       runtime·noteclear(&note);
+                       notep = &note;
+                       runtime·newproc1((byte*)forcegchelper, (byte*)&notep, sizeof(notep), 0, runtime·MHeap_Scavenger);
+                       runtime·entersyscall();
+                       runtime·notesleep(&note);
+                       runtime·exitsyscall();
                        runtime·lock(h);
                        now = runtime·nanotime();
                        if (trace)