]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: restore deadlock detection in the simplest case.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Tue, 27 Mar 2012 03:06:20 +0000 (23:06 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 27 Mar 2012 03:06:20 +0000 (23:06 -0400)
Fixes #3342.

R=iant, r, dave, rsc
CC=golang-dev, remy
https://golang.org/cl/5844051

src/pkg/runtime/mheap.c
src/pkg/runtime/proc.c
test/fixedbugs/bug429.go [new file with mode: 0644]
test/golden.out

index c877bfca91b288dc4b9db051101bcc6c5204faa6..9dd50835e79bbbf7570298979232a972f4e63db4 100644 (file)
@@ -358,6 +358,9 @@ runtime·MHeap_Scavenger(void)
 
        h = &runtime·mheap;
        for(k=0;; k++) {
+               // Return to the scheduler in case the rest of the world is deadlocked.
+               runtime·gosched();
+
                runtime·noteclear(&note);
                runtime·entersyscall();
                runtime·notetsleep(&note, tick);
index 962f748ce860f921bfa8b6d9d9a2a02c75e35897..509d8208c88f2101daa9780d4649dc5ceb96004c 100644 (file)
@@ -521,6 +521,16 @@ mnextg(M *m, G *g)
        }
 }
 
+// Check for a deadlock situation.
+static void
+checkdeadlock(void) {
+       if((scvg == nil && runtime·sched.grunning == 0) ||
+          (scvg != nil && runtime·sched.grunning == 1 && runtime·sched.gwait == 0 &&
+           (scvg->status == Grunnable || scvg->status == Grunning || scvg->status == Gsyscall))) {
+               runtime·throw("all goroutines are asleep - deadlock!");
+       }
+}
+
 // Get the next goroutine that m should run.
 // Sched must be locked on entry, is unlocked on exit.
 // Makes sure that at most $GOMAXPROCS g's are
@@ -570,6 +580,9 @@ top:
                                continue;
                        }
                        runtime·sched.grunning++;
+                       // The work could actually have been the sole scavenger
+                       // goroutine. Look for deadlock situation.
+                       checkdeadlock();
                        schedunlock();
                        return gp;
                }
@@ -591,11 +604,7 @@ top:
        }
 
        // Look for deadlock situation.
-       if((scvg == nil && runtime·sched.grunning == 0) ||
-          (scvg != nil && runtime·sched.grunning == 1 && runtime·sched.gwait == 0 &&
-           (scvg->status == Grunning || scvg->status == Gsyscall))) {
-               runtime·throw("all goroutines are asleep - deadlock!");
-       }
+       checkdeadlock();
 
        m->nextg = nil;
        m->waitnextg = 1;
diff --git a/test/fixedbugs/bug429.go b/test/fixedbugs/bug429.go
new file mode 100644 (file)
index 0000000..991a371
--- /dev/null
@@ -0,0 +1,13 @@
+// $G $D/$F.go && $L $F.$A && ! ./$A.out || echo BUG: bug429
+
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Should print deadlock message, not hang.
+
+package main
+
+func main() {
+       select{}
+}
index 764f561969dd6b19531478f40309fe2eac036b6d..376af8e53ccd68e13a3f8e37a9639c98e3e0ed3d 100644 (file)
@@ -15,6 +15,9 @@
 
 == fixedbugs/
 
+=========== fixedbugs/bug429.go
+throw: all goroutines are asleep - deadlock!
+
 == bugs/
 
 =========== bugs/bug395.go