]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: start all threads with runtime.mstart
authorRuss Cox <rsc@golang.org>
Fri, 1 Mar 2013 16:44:43 +0000 (11:44 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 1 Mar 2013 16:44:43 +0000 (11:44 -0500)
Putting the M initialization in multiple places will not scale.
Various code assumes mstart is the start already. Make it so.

R=golang-dev, devon.odell
CC=golang-dev
https://golang.org/cl/7420048

14 files changed:
src/pkg/runtime/proc.c
src/pkg/runtime/runtime.h
src/pkg/runtime/sys_freebsd_386.s
src/pkg/runtime/sys_freebsd_amd64.s
src/pkg/runtime/sys_freebsd_arm.s
src/pkg/runtime/sys_windows_386.s
src/pkg/runtime/sys_windows_amd64.s
src/pkg/runtime/thread_darwin.c
src/pkg/runtime/thread_freebsd.c
src/pkg/runtime/thread_linux.c
src/pkg/runtime/thread_netbsd.c
src/pkg/runtime/thread_openbsd.c
src/pkg/runtime/thread_plan9.c
src/pkg/runtime/thread_windows.c

index 4341ed35694362a8bcfb5057d7a27cffcc2d46e8..b0511cacbabd964c4cdf434e3e58956b031d2b37 100644 (file)
@@ -84,7 +84,7 @@ static void schedule(void);
 static void procresize(int32);
 static void acquirep(P*);
 static P* releasep(void);
-static void newm(void(*)(void), P*, bool, bool);
+static void newm(void(*)(void), P*);
 static void goidle(void);
 static void stopm(void);
 static void startm(P*, bool);
@@ -161,7 +161,7 @@ static FuncVal scavenger = {runtime·MHeap_Scavenger};
 void
 runtime·main(void)
 {
-       newm(sysmon, nil, false, false);
+       newm(sysmon, nil);
 
        // Lock the main goroutine onto this, the main OS thread,
        // during initialization.  Most programs won't care, but a few
@@ -381,6 +381,12 @@ runtime·stoptheworld(void)
        }
 }
 
+static void
+mhelpgc(void)
+{
+       m->helpgc = 1;
+}
+
 void
 runtime·starttheworld(void)
 {
@@ -428,7 +434,7 @@ runtime·starttheworld(void)
                // coordinate.  This lazy approach works out in practice:
                // we don't mind if the first couple gc rounds don't have quite
                // the maximum number of procs.
-               newm(runtime·mstart, nil, true, false);
+               newm(mhelpgc, nil);
        }
 }
 
@@ -460,6 +466,9 @@ runtime·mstart(void)
                if(runtime·iscgo)
                        runtime·newextram();
        }
+       
+       if(m->mstartfn)
+               m->mstartfn();
 
        if(m->helpgc) {
                m->helpgc = false;
@@ -726,16 +735,15 @@ unlockextra(M *mp)
 }
 
 
-// Create a new m.  It will start off with a call to fn.
+// Create a new m.  It will start off with a call to fn, or else the scheduler.
 static void
-newm(void(*fn)(void), P *p, bool helpgc, bool spinning)
+newm(void(*fn)(void), P *p)
 {
        M *mp;
 
        mp = runtime·allocm(p);
        mp->nextp = p;
-       mp->helpgc = helpgc;
-       mp->spinning = spinning;
+       mp->mstartfn = fn;
 
        if(runtime·iscgo) {
                CgoThreadStart ts;
@@ -744,11 +752,11 @@ newm(void(*fn)(void), P *p, bool helpgc, bool spinning)
                        runtime·throw("_cgo_thread_start missing");
                ts.m = mp;
                ts.g = mp->g0;
-               ts.fn = fn;
+               ts.fn = runtime·mstart;
                runtime·asmcgocall(_cgo_thread_start, &ts);
                return;
        }
-       runtime·newosproc(mp, mp->g0, (byte*)mp->g0->stackbase, fn);
+       runtime·newosproc(mp, (byte*)mp->g0->stackbase);
 }
 
 // Stops execution of the current m until new work is available.
@@ -781,12 +789,19 @@ retry:
        m->nextp = nil;
 }
 
+static void
+mspinning(void)
+{
+       m->spinning = true;
+}
+
 // Schedules some M to run the p (creates an M if necessary).
 // If p==nil, tries to get an idle P, if no idle P's returns false.
 static void
 startm(P *p, bool spinning)
 {
        M *mp;
+       void (*fn)(void);
 
        runtime·lock(&runtime·sched);
        if(p == nil) {
@@ -801,7 +816,10 @@ startm(P *p, bool spinning)
        mp = mget();
        runtime·unlock(&runtime·sched);
        if(mp == nil) {
-               newm(runtime·mstart, p, false, spinning);
+               fn = nil;
+               if(spinning)
+                       fn = mspinning;
+               newm(fn, p);
                return;
        }
        if(mp->spinning)
@@ -1887,11 +1905,6 @@ sysmon(void)
        uint32 idle, delay;
        uint32 ticks[MaxGomaxprocs];
 
-       // This is a special dedicated thread that retakes P's from blocking syscalls.
-       // It works w/o mcache nor stackalloc, it may work concurrently with GC.
-       runtime·asminit();
-       runtime·minit();
-
        idle = 0;  // how many cycles in succession we had not wokeup somebody
        delay = 0;
        for(;;) {
index 4440808319687f4edaee33ec31b14056d474c458..602b185ad6b73bd366f33f81f3e0328a72175403 100644 (file)
@@ -702,7 +702,8 @@ void        runtime·exit1(int32);
 void   runtime·ready(G*);
 byte*  runtime·getenv(int8*);
 int32  runtime·atoi(byte*);
-void   runtime·newosproc(M *mp, G *gp, void *stk, void (*fn)(void));
+void   runtime·newosproc(M *mp, void *stk);
+void   runtime·mstart(void);
 G*     runtime·malg(int32);
 void   runtime·asminit(void);
 void   runtime·mpreinit(M*);
index 0b472e30749961b33bdc550ccc62e88c6ba1cc63..d5370267a988c3d806de0ebfec350a8823a559b4 100644 (file)
@@ -38,12 +38,7 @@ TEXT runtime·thr_start(SB),7,$0
        
        MOVL    AX, m(CX)
        CALL    runtime·stackcheck(SB)         // smashes AX
-
-       // newosproc left the function we should call in mp->mstartfn.
-       get_tls(CX)
-       MOVL    m(CX), AX
-       MOVL    m_mstartfn(AX), AX
-       CALL    AX
+       CALL    runtime·mstart(SB)
 
        MOVL    0, AX                   // crash (not reached)
 
index 218851b78212333e1f48df28d19ef529d3504022..40c6237e231d472aaf53b4a07ddbda5118285aeb 100644 (file)
@@ -38,13 +38,8 @@ TEXT runtime·thr_start(SB),7,$0
        MOVQ    m_g0(R13), DI
        MOVQ    DI, g(CX)
 
-       CALL runtime·stackcheck(SB)
-       
-       // newosproc left the function we should call in mp->mstartfn.
-       get_tls(CX)
-       MOVQ    m(CX), AX
-       MOVQ    m_mstartfn(AX), AX
-       CALL    AX
+       CALL    runtime·stackcheck(SB)
+       CALL    runtime·mstart(SB)
 
        MOVQ 0, AX                      // crash (not reached)
 
index d9e3339324330bb0d869491c4f7cca6d0f193599..77050e8d0cd5ae46d7598df63cb978dcd068b80f 100644 (file)
@@ -33,10 +33,7 @@ TEXT runtime·thr_start(SB),7,$0
        // set up g
        MOVW m_g0(R9), R10
        BL runtime·emptyfunc(SB) // fault if stack check is wrong
-
-       // newosproc left the function we should call in mp->tls[2] for us.
-       MOVW    (m_tls+8)(m), R0
-       BL      (R0)
+       BL runtime·mstart(SB)
 
        MOVW $2, R9  // crash (not reached)
        MOVW R9, (R9)
index 2c3c5d465c9db0513b5ba1f78dcf54ada82b3fe6..ca59f0a1d576b05f228d21a3c33023c11578cf50 100644 (file)
@@ -259,12 +259,7 @@ TEXT runtime·tstart(SB),7,$0
        CLD
 
        CALL    runtime·stackcheck(SB) // clobbers AX,CX
-
-       // newosproc left the function we should call in mp->mstartfn.
-       get_tls(CX)
-       MOVL    m(CX), AX
-       MOVL    m_mstartfn(AX), AX
-       CALL    AX
+       CALL    runtime·mstart(SB)
 
        RET
 
index dc9c94ae4c1119950c7bb82ebfe1e1c5891e3a3a..fe88f3b7544ac975470b9f0f54cde0276d27384e 100644 (file)
@@ -329,11 +329,7 @@ TEXT runtime·tstart_stdcall(SB),7,$0
        CLD
 
        CALL    runtime·stackcheck(SB) // clobbers AX,CX
-
-       get_tls(CX)
-       MOVQ    m(CX), AX
-       MOVQ    m_mstartfn(AX), AX
-       CALL    AX
+       CALL    runtime·mstart(SB)
 
        XORL    AX, AX                  // return 0 == success
        RET
index 1400e6e7bc9b1ecf9cefe91a01f76a93c9a1cadf..adb1ffe6acbc46ccc6aaad1de6f3388aef715547 100644 (file)
@@ -87,19 +87,19 @@ runtime·goenvs(void)
 }
 
 void
-runtime·newosproc(M *mp, G *gp, void *stk, void (*fn)(void))
+runtime·newosproc(M *mp, void *stk)
 {
        int32 errno;
        Sigset oset;
 
        mp->tls[0] = mp->id;    // so 386 asm can find it
        if(0){
-               runtime·printf("newosproc stk=%p m=%p g=%p fn=%p id=%d/%d ostk=%p\n",
-                       stk, mp, gp, fn, mp->id, (int32)mp->tls[0], &mp);
+               runtime·printf("newosproc stk=%p m=%p g=%p id=%d/%d ostk=%p\n",
+                       stk, mp, mp->g0, mp->id, (int32)mp->tls[0], &mp);
        }
 
        runtime·sigprocmask(SIG_SETMASK, &sigset_all, &oset);
-       errno = runtime·bsdthread_create(stk, mp, gp, fn);
+       errno = runtime·bsdthread_create(stk, mp, mp->g0, runtime·mstart);
        runtime·sigprocmask(SIG_SETMASK, &oset, nil);
 
        if(errno < 0) {
index aae52ea379c5bb48a1e8e240269ed9ddc9c4d54f..3ae14ee0a0d31388539a9dce02ab3cfb36ca2586 100644 (file)
@@ -77,18 +77,14 @@ runtime·futexwakeup(uint32 *addr, uint32 cnt)
 void runtime·thr_start(void*);
 
 void
-runtime·newosproc(M *mp, G *gp, void *stk, void (*fn)(void))
+runtime·newosproc(M *mp, void *stk)
 {
        ThrParam param;
        Sigset oset;
 
-       // thr_start assumes gp == mp->g0
-       if(gp != mp->g0)
-               runtime·throw("invalid newosproc gp");
-
        if(0){
-               runtime·printf("newosproc stk=%p m=%p g=%p fn=%p id=%d/%d ostk=%p\n",
-                       stk, mp, gp, fn, mp->id, (int32)mp->tls[0], &mp);
+               runtime·printf("newosproc stk=%p m=%p g=%p id=%d/%d ostk=%p\n",
+                       stk, mp, mp->g0, mp->id, (int32)mp->tls[0], &mp);
        }
 
        runtime·sigprocmask(&sigset_all, &oset);
@@ -96,15 +92,18 @@ runtime·newosproc(M *mp, G *gp, void *stk, void (*fn)(void))
 
        param.start_func = runtime·thr_start;
        param.arg = (byte*)mp;
-       param.stack_base = (void*)gp->stackbase;
-       param.stack_size = (byte*)stk - (byte*)gp->stackbase;
+       
+       // NOTE(rsc): This code is confused. stackbase is the top of the stack
+       // and is equal to stk. However, it's working, so I'm not changing it.
+       param.stack_base = (void*)mp->g0->stackbase;
+       param.stack_size = (byte*)stk - (byte*)mp->g0->stackbase;
+
        param.child_tid = (intptr*)&mp->procid;
        param.parent_tid = nil;
        param.tls_base = (void*)&mp->tls[0];
        param.tls_size = sizeof mp->tls;
 
        mp->tls[0] = mp->id;    // so 386 asm can find it
-       mp->mstartfn = fn;
 
        runtime·thr_new(&param, sizeof param);
        runtime·sigprocmask(&oset, nil);
index 3f450580692587873374a837fc88303aebe27441..78ddef878b84c72e5e7cfe8ce2fdef8b55d0df1b 100644 (file)
@@ -124,7 +124,7 @@ enum
 };
 
 void
-runtime·newosproc(M *mp, G *gp, void *stk, void (*fn)(void))
+runtime·newosproc(M *mp, void *stk)
 {
        int32 ret;
        int32 flags;
@@ -142,14 +142,14 @@ runtime·newosproc(M *mp, G *gp, void *stk, void (*fn)(void))
 
        mp->tls[0] = mp->id;    // so 386 asm can find it
        if(0){
-               runtime·printf("newosproc stk=%p m=%p g=%p fn=%p clone=%p id=%d/%d ostk=%p\n",
-                       stk, mp, gp, fn, runtime·clone, mp->id, (int32)mp->tls[0], &mp);
+               runtime·printf("newosproc stk=%p m=%p g=%p clone=%p id=%d/%d ostk=%p\n",
+                       stk, mp, mp->g0, runtime·clone, mp->id, (int32)mp->tls[0], &mp);
        }
 
        // Disable signals during clone, so that the new thread starts
        // with signals disabled.  It will enable them in minit.
        runtime·rtsigprocmask(SIG_SETMASK, &sigset_all, &oset, sizeof oset);
-       ret = runtime·clone(flags, stk, mp, gp, fn);
+       ret = runtime·clone(flags, stk, mp, mp->g0, runtime·mstart);
        runtime·rtsigprocmask(SIG_SETMASK, &oset, nil, sizeof oset);
 
        if(ret < 0) {
index b9ec33acd5f2c0f649cd05251c027d8dfd0ef2bc..f333c6dd8ea2d1ca1193b338318c5565dec06dec 100644 (file)
@@ -145,15 +145,15 @@ runtime·semawakeup(M *mp)
 }
 
 void
-runtime·newosproc(M *mp, G *gp, void *stk, void (*fn)(void))
+runtime·newosproc(M *mp, void *stk)
 {
        UcontextT uc;
        int32 ret;
 
        if(0) {
                runtime·printf(
-                       "newosproc stk=%p m=%p g=%p fn=%p id=%d/%d ostk=%p\n",
-                       stk, mp, gp, fn, mp->id, (int32)mp->tls[0], &mp);
+                       "newosproc stk=%p m=%p g=%p id=%d/%d ostk=%p\n",
+                       stk, mp, mp->g0, mp->id, (int32)mp->tls[0], &mp);
        }
 
        mp->tls[0] = mp->id;    // so 386 asm can find it
@@ -164,7 +164,7 @@ runtime·newosproc(M *mp, G *gp, void *stk, void (*fn)(void))
        uc.uc_link = nil;
        uc.uc_sigmask = sigset_all;
 
-       runtime·lwp_mcontext_init(&uc.uc_mcontext, stk, mp, gp, fn);
+       runtime·lwp_mcontext_init(&uc.uc_mcontext, stk, mp, mp->g0, runtime·mstart);
 
        ret = runtime·lwp_create(&uc, 0, &mp->procid);
 
index f35c3bb4413eb024516699dc909910b847da204d..9150efaa1b030f33631780ecf0c72972d9453698 100644 (file)
@@ -123,7 +123,7 @@ runtime·semawakeup(M *mp)
 }
 
 void
-runtime·newosproc(M *mp, G *gp, void *stk, void (*fn)(void))
+runtime·newosproc(M *mp, void *stk)
 {
        Tfork param;
        Sigset oset;
@@ -132,7 +132,7 @@ runtime·newosproc(M *mp, G *gp, void *stk, void (*fn)(void))
        if(0) {
                runtime·printf(
                        "newosproc stk=%p m=%p g=%p fn=%p id=%d/%d ostk=%p\n",
-                       stk, mp, gp, fn, mp->id, (int32)mp->tls[0], &mp);
+                       stk, mp, mp->g0, fn, mp->id, (int32)mp->tls[0], &mp);
        }
 
        mp->tls[0] = mp->id;    // so 386 asm can find it
@@ -142,7 +142,7 @@ runtime·newosproc(M *mp, G *gp, void *stk, void (*fn)(void))
        param.tf_stack = stk;
 
        oset = runtime·sigprocmask(SIG_SETMASK, sigset_all);
-       ret = runtime·tfork((byte*)&param, sizeof(param), mp, gp, fn);
+       ret = runtime·tfork((byte*)&param, sizeof(param), mp, mp->g0, runtime·mstart);
        runtime·sigprocmask(SIG_SETMASK, oset);
 
        if(ret < 0) {
index 866b1e7806f92b00f13b225b0381e3acb7be4a49..e1c7334cfb20f3cd51ccdcd797003098e0cf96cd 100644 (file)
@@ -223,15 +223,15 @@ runtime·exit(int32 e)
 }
 
 void
-runtime·newosproc(M *mp, G *gp, void *stk, void (*fn)(void))
+runtime·newosproc(M *mp, void *stk)
 {
        mp->tls[0] = mp->id;    // so 386 asm can find it
        if(0){
                runtime·printf("newosproc stk=%p m=%p g=%p fn=%p rfork=%p id=%d/%d ostk=%p\n",
-                       stk, mp, gp, fn, runtime·rfork, mp->id, (int32)mp->tls[0], &mp);
+                       stk, mp, mp->g0, fn, runtime·rfork, mp->id, (int32)mp->tls[0], &mp);
        }
 
-       if(runtime·rfork(RFPROC|RFMEM|RFNOWAIT, stk, mp, gp, fn) < 0)
+       if(runtime·rfork(RFPROC|RFMEM|RFNOWAIT, stk, mp, mp->g0, runtime·mstart) < 0)
                runtime·throw("newosproc: rfork failed");
 }
 
index 06326c2187a646771c119f3e41d878e7ce3521ef..ae4e82e50eda4d7fea094b7f644c6b96869e6fd8 100644 (file)
@@ -187,18 +187,12 @@ runtime·semacreate(void)
 #define STACK_SIZE_PARAM_IS_A_RESERVATION ((uintptr)0x00010000)
 
 void
-runtime·newosproc(M *mp, G *gp, void *stk, void (*fn)(void))
+runtime·newosproc(M *mp, void *stk)
 {
        void *thandle;
 
        USED(stk);
 
-       // assume gp == mp->g0
-       if(gp != mp->g0)
-               runtime·throw("invalid newosproc gp");
-
-       mp->mstartfn = fn;
-
        thandle = runtime·stdcall(runtime·CreateThread, 6,
                nil, (uintptr)0x20000, runtime·tstart_stdcall, mp,
                STACK_SIZE_PARAM_IS_A_RESERVATION, nil);