aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2015-08-05 11:07:47 -0400
committerAustin Clements <austin@google.com>2015-08-05 17:28:56 +0000
commitd57f03730265c4677ab2ec1ad74cf8cbf592f798 (patch)
tree2344cefe0737b2f39e2b03d2786f47536827f94e
parent3dd3ab41acd5eeef5cfd9e83d75f325178ef6a9c (diff)
downloadgo-d57f03730265c4677ab2ec1ad74cf8cbf592f798.tar.gz
go-d57f03730265c4677ab2ec1ad74cf8cbf592f798.zip
runtime: don't recheck heap trigger for periodic GC
88e945f introduced a non-speculative double check of the heap trigger before actually starting a concurrent GC. This was necessary to fix a race for heap-triggered GC, but broke sysmon-triggered periodic GC, since the heap check will of course fail for periodically triggered GC. Fix this by telling startGC whether or not this GC was triggered by heap size or a timer and only doing the heap size double check for GCs triggered by heap size. Fixes #12026. Change-Id: I7c3f6ec364545c36d619f2b4b3bf3b758e3bcbd6 Reviewed-on: https://go-review.googlesource.com/13168 Reviewed-by: Russ Cox <rsc@golang.org>
-rw-r--r--src/runtime/malloc.go2
-rw-r--r--src/runtime/mgc.go11
-rw-r--r--src/runtime/mheap.go2
-rw-r--r--src/runtime/proc.go2
4 files changed, 11 insertions, 6 deletions
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
index 40f672abb0..353f84083f 100644
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -702,7 +702,7 @@ func mallocgc(size uintptr, typ *_type, flags uint32) unsafe.Pointer {
}
if shouldhelpgc && shouldtriggergc() {
- startGC(gcBackgroundMode)
+ startGC(gcBackgroundMode, false)
} else if gcBlackenEnabled != 0 {
// Assist garbage collector. We delay this until the
// epilogue so that it doesn't interfere with the
diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go
index f7e9908a8a..f7fd4e51d5 100644
--- a/src/runtime/mgc.go
+++ b/src/runtime/mgc.go
@@ -811,7 +811,7 @@ var work struct {
// garbage collection is complete. It may also block the entire
// program.
func GC() {
- startGC(gcForceBlockMode)
+ startGC(gcForceBlockMode, false)
}
const (
@@ -820,7 +820,12 @@ const (
gcForceBlockMode // stop-the-world GC now and wait for sweep
)
-func startGC(mode int) {
+// startGC starts a GC cycle. If mode is gcBackgroundMode, this will
+// start GC in the background and return. Otherwise, this will block
+// until the new GC cycle is started and finishes. If forceTrigger is
+// true, it indicates that GC should be started regardless of the
+// current heap size.
+func startGC(mode int, forceTrigger bool) {
// The gc is turned off (via enablegc) until the bootstrap has completed.
// Also, malloc gets called in the guts of a number of libraries that might be
// holding locks. To avoid deadlocks during stop-the-world, don't bother
@@ -853,7 +858,7 @@ func startGC(mode int) {
// recheck that this really should trigger GC. (For example,
// we may have gone through a whole GC cycle since the
// speculative check.)
- if !shouldtriggergc() {
+ if !(forceTrigger || shouldtriggergc()) {
unlock(&bggc.lock)
return
}
diff --git a/src/runtime/mheap.go b/src/runtime/mheap.go
index be4d612156..bc4e7c1272 100644
--- a/src/runtime/mheap.go
+++ b/src/runtime/mheap.go
@@ -836,7 +836,7 @@ func mHeap_Scavenge(k int32, now, limit uint64) {
//go:linkname runtime_debug_freeOSMemory runtime/debug.freeOSMemory
func runtime_debug_freeOSMemory() {
- startGC(gcForceBlockMode)
+ startGC(gcForceBlockMode, false)
systemstack(func() { mHeap_Scavenge(-1, ^uint64(0), 0) })
}
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index 1a4c6c109f..c5b4a8c9af 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -154,7 +154,7 @@ func forcegchelper() {
if debug.gctrace > 0 {
println("GC forced")
}
- startGC(gcBackgroundMode)
+ startGC(gcBackgroundMode, true)
}
}