h = &runtime·mheap;
for(k=0;; k++) {
+ // Return to the scheduler in case the rest of the world is deadlocked.
+ runtime·gosched();
+
runtime·noteclear(¬e);
runtime·entersyscall();
runtime·notetsleep(¬e, tick);
}
}
+// 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
continue;
}
runtime·sched.grunning++;
+ // The work could actually have been the sole scavenger
+ // goroutine. Look for deadlock situation.
+ checkdeadlock();
schedunlock();
return gp;
}
}
// 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;
--- /dev/null
+// $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{}
+}