runtime·newm(void) { M *m; m = runtime·malloc(sizeof(M)); mcommoninit(m); if(runtime·iscgo) { CgoThreadStart ts; if(libcgo_thread_start == nil) runtime·throw("libcgo_thread_start missing"); // pthread_create will make us a stack. m->g0 = runtime·malg(-1); ts.m = m; ts.g = m->g0; ts.fn = runtime·mstart; runtime·asmcgocall(libcgo_thread_start, &ts); } else { if(Windows) // windows will layout sched stack on os stack m->g0 = runtime·malg(-1); else m->g0 = runtime·malg(8192); runtime·newosproc(m, m->g0, m->g0->stackbase, runtime·mstart); } return m; }
// Kick off new ms as needed (up to mcpumax). // There are already `other' other cpus that will // start looking for goroutines shortly. // Sched is locked. static void matchmg(void) { G *g; if(m->mallocing || m->gcing) return; while(runtime·sched.mcpu < runtime·sched.mcpumax && (g = gget()) != nil){ M *m; // Find the m that will run g. if((m = mget(g)) == nil){ m = runtime·malloc(sizeof(M)); // Add to runtime·allm so garbage collector doesn't free m // when it is just in a register or thread-local storage. m->alllink = runtime·allm; runtime·allm = m; m->id = runtime·sched.mcount++; if(runtime·iscgo) { CgoThreadStart ts; if(libcgo_thread_start == nil) runtime·throw("libcgo_thread_start missing"); // pthread_create will make us a stack. m->g0 = runtime·malg(-1); ts.m = m; ts.g = m->g0; ts.fn = runtime·mstart; runtime·asmcgocall(libcgo_thread_start, &ts); } else { if(Windows) // windows will layout sched stack on os stack m->g0 = runtime·malg(-1); else m->g0 = runtime·malg(8192); runtime·newosproc(m, m->g0, m->g0->stackbase, runtime·mstart); } } mnextg(m, g); } }
runtime·newm(void) { M *mp; static Type *mtype; // The Go type M if(mtype == nil) { Eface e; runtime·gc_m_ptr(&e); mtype = ((PtrType*)e.type)->elem; } mp = runtime·cnew(mtype); mcommoninit(mp); if(runtime·iscgo) { CgoThreadStart ts; if(libcgo_thread_start == nil) runtime·throw("libcgo_thread_start missing"); // pthread_create will make us a stack. mp->g0 = runtime·malg(-1); ts.m = mp; ts.g = mp->g0; ts.fn = runtime·mstart; runtime·asmcgocall(libcgo_thread_start, &ts); } else { if(Windows) // windows will layout sched stack on os stack mp->g0 = runtime·malg(-1); else mp->g0 = runtime·malg(8192); runtime·newosproc(mp, mp->g0, (byte*)mp->g0->stackbase, runtime·mstart); } return mp; }