Commit 9aa7d136 authored by Russ Cox's avatar Russ Cox

runtime: avoid race with forcegc helper

While we are here, give the gc helper a real function name
that will appear in stack traces.

LGTM=rlh
R=rlh
CC=dvyukov, golang-codereviews
https://golang.org/cl/133470043
parent d8cbbe68
......@@ -2846,9 +2846,12 @@ sysmon(void)
lastgc = runtime·atomicload64(&mstats.last_gc);
if(lastgc != 0 && unixnow - lastgc > forcegcperiod && runtime·atomicload(&runtime·forcegc.idle)) {
runtime·lock(&runtime·forcegc.lock);
runtime·forcegc.idle = 0;
runtime·forcegc.g->schedlink = nil;
injectglist(runtime·forcegc.g);
if(runtime·forcegc.g != nil) {
// Goroutine may be started but has not initialized g yet.
runtime·forcegc.idle = 0;
runtime·forcegc.g->schedlink = nil;
injectglist(runtime·forcegc.g);
}
runtime·unlock(&runtime·forcegc.lock);
}
......
......@@ -31,23 +31,25 @@ var parkunlock_c byte
// start forcegc helper goroutine
func init() {
go func() {
forcegc.g = getg()
forcegc.g.issystem = true
for {
lock(&forcegc.lock)
if forcegc.idle != 0 {
gothrow("forcegc: phase error")
}
atomicstore(&forcegc.idle, 1)
goparkunlock(&forcegc.lock, "force gc (idle)")
// this goroutine is explicitly resumed by sysmon
if debug.gctrace > 0 {
println("GC forced")
}
gogc(1)
go forcegchelper()
}
func forcegchelper() {
forcegc.g = getg()
forcegc.g.issystem = true
for {
lock(&forcegc.lock)
if forcegc.idle != 0 {
gothrow("forcegc: phase error")
}
}()
atomicstore(&forcegc.idle, 1)
goparkunlock(&forcegc.lock, "force gc (idle)")
// this goroutine is explicitly resumed by sysmon
if debug.gctrace > 0 {
println("GC forced")
}
gogc(1)
}
}
// Gosched yields the processor, allowing other goroutines to run. It does not
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment