// 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); scvg->issystem = true; main·init(); runtime·sched.init = false; 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(); if(raceenabled) runtime·racefini(); runtime·exit(0); for(;;) *(int32*)runtime·main = 0; }
static void endcgo(void) { runtime·unlockOSThread(); m->ncgo--; if(m->ncgo == 0) { // We are going back to Go and are not in a recursive // call. Let the GC collect any memory allocated via // _cgo_allocate that is no longer referenced. m->cgomal = nil; } if(raceenabled) runtime·raceacquire(&cgosync); }