}
// Release (part of) unused memory to OS.
-// Goroutine created in runtime·schedinit.
+// Goroutine created at startup.
// Loop forever.
void
runtime·MHeap_Scavenger(void)
mstats.enablegc = 1;
m->nomemprof--;
-
- scvg = runtime·newproc1((byte*)runtime·MHeap_Scavenger, nil, 0, 0, runtime·schedinit);
}
extern void main·init(void);
// to preserve the lock.
runtime·LockOSThread();
runtime·sched.init = true;
+ scvg = runtime·newproc1((byte*)runtime·MHeap_Scavenger, nil, 0, 0, runtime·main);
main·init();
runtime·sched.init = false;
if(!runtime·sched.lockmain)
mput(m);
}
- // Look for deadlock situation: one single active g which happens to be scvg.
- if(runtime·sched.grunning == 1 && runtime·sched.gwait == 0) {
- if(scvg->status == Grunning || scvg->status == Gsyscall)
- runtime·throw("all goroutines are asleep - deadlock!");
+ // 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!");
}
m->nextg = nil;
--- /dev/null
+// 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.
+
+package runtime_test
+
+import (
+ . "runtime"
+ "syscall"
+ "testing"
+)
+
+var pid, tid int
+
+func init() {
+ // Record pid and tid of init thread for use during test.
+ // The call to LockOSThread is just to exercise it;
+ // we can't test that it does anything.
+ // Instead we're testing that the conditions are good
+ // for how it is used in init (must be on main thread).
+ pid, tid = syscall.Getpid(), syscall.Gettid()
+ LockOSThread()
+}
+
+func TestLockOSThread(t *testing.T) {
+ if pid != tid {
+ t.Fatalf("pid=%d but tid=%d", pid, tid)
+ }
+}