Starting it lazily causes a memory allocation (for the goroutine) during GC.
First use of channels for runtime implementation.
Change-Id: I9cd24dcadbbf0ee5070ee6d0ed7ea415504f316c
Reviewed-on: https://go-review.googlesource.com/6960
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
memstats.next_gc = heapminimum
}
+// gcenable is called after the bulk of the runtime initialization,
+// just before we're about to start letting user code run.
+// It kicks off the background sweeper goroutine and enables GC.
+func gcenable() {
+ c := make(chan int, 1)
+ go bgsweep(c)
+ <-c
+ memstats.enablegc = true // now that runtime is initialized, GC is okay
+}
+
func setGCPercent(in int32) (out int32) {
lock(&mheap_.lock)
out = gcpercent
// Background sweep.
lock(&sweep.lock)
- if !sweep.started {
- go bgsweep()
- sweep.started = true
- } else if sweep.parked {
+ if sweep.parked {
sweep.parked = false
ready(sweep.g)
}
}
}
-func bgsweep() {
+func bgsweep(c chan int) {
sweep.g = getg()
+
+ lock(&sweep.lock)
+ sweep.parked = true
+ c <- 1
+ goparkunlock(&sweep.lock, "GC sweep wait", traceEvGoBlock)
+
for {
for gosweepone() != ^uintptr(0) {
sweep.nbgsweep++
}
}()
- memstats.enablegc = true // now that runtime is initialized, GC is okay
+ gcenable()
if iscgo {
if _cgo_thread_start == nil {