aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-11-11 16:54:50 -0500
committerRuss Cox <rsc@golang.org>2014-11-11 16:54:50 -0500
commit9eded54fa3e7c3d1bc593f83e5c448b908299d0e (patch)
tree93ea35fe2741d58c4002b05e08b6f1726d8e0d49 /src
parent37186d91fab5850012b32c21657633d18272537e (diff)
downloadgo-9eded54fa3e7c3d1bc593f83e5c448b908299d0e.tar.xz
[dev.garbage] runtime: concurrent mark fixes
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
Diffstat (limited to 'src')
-rw-r--r--src/runtime/mgc0.c3
-rw-r--r--src/runtime/mgc0.go2
-rw-r--r--src/runtime/runtime.h2
-rw-r--r--src/runtime/stack.c8
-rw-r--r--src/runtime/sys_x86.c1
5 files changed, 13 insertions, 3 deletions
diff --git a/src/runtime/mgc0.c b/src/runtime/mgc0.c
index 8d87107c74..3c4d1afa56 100644
--- a/src/runtime/mgc0.c
+++ b/src/runtime/mgc0.c
@@ -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) {
diff --git a/src/runtime/mgc0.go b/src/runtime/mgc0.go
index 760d2a5453..dc4eec5196 100644
--- a/src/runtime/mgc0.go
+++ b/src/runtime/mgc0.go
@@ -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
}
diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h
index a4186f4505..fec224390c 100644
--- a/src/runtime/runtime.h
+++ b/src/runtime/runtime.h
@@ -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*);
diff --git a/src/runtime/stack.c b/src/runtime/stack.c
index fb23cc1c3b..a4947a53b3 100644
--- a/src/runtime/stack.c
+++ b/src/runtime/stack.c
@@ -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)
diff --git a/src/runtime/sys_x86.c b/src/runtime/sys_x86.c
index a450b3e584..edbe47ff45 100644
--- a/src/runtime/sys_x86.c
+++ b/src/runtime/sys_x86.c
@@ -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.