]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.garbage] runtime: concurrent mark fixes
authorRuss Cox <rsc@golang.org>
Tue, 11 Nov 2014 21:54:50 +0000 (16:54 -0500)
committerRuss Cox <rsc@golang.org>
Tue, 11 Nov 2014 21:54:50 +0000 (16:54 -0500)
Add missing write barrier when initializing state
for newly created goroutine. Add write barrier for
same slot when preempting a goroutine.

Disable write barrier during goroutine death,
because dopanic does pointer writes.

With concurrent mark enabled (not in this CL), all.bash passed once.
The second time, TestGoexitCrash-2 failed.

LGTM=rlh
R=rlh
CC=golang-codereviews
https://golang.org/cl/167610043

src/runtime/mgc0.c
src/runtime/mgc0.go
src/runtime/runtime.h
src/runtime/stack.c
src/runtime/sys_x86.c

index 8d87107c744431260a4d57d49f77f160c1d1f9b3..3c4d1afa56ca63fde06f33acb11d6245ba6bbad9 100644 (file)
@@ -1094,8 +1094,7 @@ shade(byte *b)
 void
 runtime·gcmarkwb_m()
 {
-       byte **slot, *ptr;
-       slot = (byte**)g->m->scalararg[0];
+       byte *ptr;
        ptr = (byte*)g->m->scalararg[1];
 
        switch(runtime·gcphase) {
index 760d2a54537a19f84675a7fcc882282e6f9436ab..dc4eec51969bf9d7b858af0b4c7c119346c74fce 100644 (file)
@@ -109,7 +109,7 @@ func writebarrierptr_nostore(dst *uintptr, src uintptr) {
        }
 
        mp := acquirem()
-       if mp.inwb {
+       if mp.inwb || mp.dying > 0 {
                releasem(mp)
                return
        }
index a4186f4505fe18176dc5997226abce40ec1198be..fec224390c9bd2a5d6492568d1b7f0cb5c28c4d6 100644 (file)
@@ -1121,6 +1121,8 @@ void      runtime·osyield(void);
 void   runtime·lockOSThread(void);
 void   runtime·unlockOSThread(void);
 
+void   runtime·writebarrierptr_nostore(void*, void*);
+
 bool   runtime·showframe(Func*, G*);
 void   runtime·printcreatedby(G*);
 
index fb23cc1c3b8cdbfffc0db6ba54a09e8426fc35e8..a4947a53b3ec557bf690fc3a6a435ac6d401bb55 100644 (file)
@@ -706,6 +706,14 @@ runtime·newstack(void)
                runtime·printf("runtime: split stack overflow: %p < %p\n", sp, gp->stack.lo);
                runtime·throw("runtime: split stack overflow");
        }
+       
+       if(gp->sched.ctxt != nil) {
+               // morestack wrote sched.ctxt on its way in here,
+               // without a write barrier. Run the write barrier now.
+               // It is not possible to be preempted between then
+               // and now, so it's okay.
+               runtime·writebarrierptr_nostore(&gp->sched.ctxt, gp->sched.ctxt);
+       }
 
        if(gp->stackguard0 == (uintptr)StackPreempt) {
                if(gp == g->m->g0)
index a450b3e58443363280950ffcbda63cc537520d5d..edbe47ff45480ee975b824edd73c6f1f21e1b67c 100644 (file)
@@ -20,6 +20,7 @@ runtime·gostartcall(Gobuf *gobuf, void (*fn)(void), void *ctxt)
        gobuf->sp = (uintptr)sp;
        gobuf->pc = (uintptr)fn;
        gobuf->ctxt = ctxt;
+       runtime·writebarrierptr_nostore(&gobuf->ctxt, ctxt);
 }
 
 // Called to rewind context saved during morestack back to beginning of function.