// The main goroutine. void runtime·main(void) { // Lock the main goroutine onto this, the main OS thread, // during initialization. Most programs won't care, but a few // do require certain calls to be made by the main thread. // Those can arrange for main.main to run in the main thread // by calling runtime.LockOSThread during initialization // to preserve the lock. runtime·LockOSThread(); // From now on, newgoroutines may use non-main threads. setmcpumax(runtime·gomaxprocs); 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) runtime·UnlockOSThread(); // The deadlock detection has false negatives. // Let scvg start up, to eliminate the false negative // for the trivial program func main() { select{} }. runtime·gosched(); main·main(); runtime·exit(0); for(;;) *(int32*)runtime·main = 0; }
void runtime·unlockOSThread(void) { if(m->locked < LockInternal) runtime·throw("runtime: internal error: misuse of lockOSThread/unlockOSThread"); m->locked -= LockInternal; UnlockOSThread(); }
// The main goroutine. void runtime·main(void) { // Lock the main goroutine onto this, the main OS thread, // during initialization. Most programs won't care, but a few // do require certain calls to be made by the main thread. // Those can arrange for main.main to run in the main thread // by calling runtime.LockOSThread during initialization // to preserve the lock. runtime·LockOSThread(); runtime·sched.init = true; main·init(); runtime·sched.init = false; if(!runtime·sched.lockmain) runtime·UnlockOSThread(); main·main(); runtime·exit(0); for(;;) *(int32*)runtime·main = 0; }
void runtime·UnlockOSThread(void) { m->locked &= ~LockExternal; UnlockOSThread(); }