aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/mgcsweep.go
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2018-08-23 13:14:19 -0400
committerAustin Clements <austin@google.com>2018-10-02 20:35:35 +0000
commit873bd47dfb34ba4416d4df30180905250b91f137 (patch)
treee2aab44fddcb211ea8e2b72aba68810c3f84c70d /src/runtime/mgcsweep.go
parent457c8f4fe9e4d45f97d0a3f3c4a80789c6616fd6 (diff)
downloadgo-873bd47dfb34ba4416d4df30180905250b91f137.tar.gz
go-873bd47dfb34ba4416d4df30180905250b91f137.zip
runtime: flush mcaches lazily
Currently, all mcaches are flushed during STW mark termination as a root marking job. This is currently necessary because all spans must be out of these caches before sweeping begins to avoid races with allocation and to ensure the spans are in the state expected by sweeping. We do it as a root marking job because mcache flushing is somewhat expensive and O(GOMAXPROCS) and this parallelizes the work across the Ps. However, it's also the last remaining root marking job performed during mark termination. This CL moves mcache flushing out of mark termination and performs it lazily. We keep track of the last sweepgen at which each mcache was flushed and as each P is woken from STW, it observes that its mcache is out-of-date and flushes it. The introduces a complication for spans cached in stale mcaches. These may now be observed by background or proportional sweeping or when attempting to add a finalizer, but aren't in a stable state. For example, they are likely to be on the wrong mcentral list. To fix this, this CL extends the sweepgen protocol to also capture whether a span is cached and, if so, whether or not its cache is stale. This protocol blocks asynchronous sweeping from touching cached spans and makes it the responsibility of mcache flushing to sweep the flushed spans. This eliminates the last mark termination root marking job, which means we can now eliminate that entire infrastructure. Updates #26903. This implements lazy mcache flushing. Change-Id: Iadda7aabe540b2026cffc5195da7be37d5b4125e Reviewed-on: https://go-review.googlesource.com/c/134783 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
Diffstat (limited to 'src/runtime/mgcsweep.go')
-rw-r--r--src/runtime/mgcsweep.go9
1 files changed, 7 insertions, 2 deletions
diff --git a/src/runtime/mgcsweep.go b/src/runtime/mgcsweep.go
index 5cdede002a..00950aede2 100644
--- a/src/runtime/mgcsweep.go
+++ b/src/runtime/mgcsweep.go
@@ -161,7 +161,8 @@ func (s *mspan) ensureSwept() {
}
sg := mheap_.sweepgen
- if atomic.Load(&s.sweepgen) == sg {
+ spangen := atomic.Load(&s.sweepgen)
+ if spangen == sg || spangen == sg+3 {
return
}
// The caller must be sure that the span is a mSpanInUse span.
@@ -170,7 +171,11 @@ func (s *mspan) ensureSwept() {
return
}
// unfortunate condition, and we don't have efficient means to wait
- for atomic.Load(&s.sweepgen) != sg {
+ for {
+ spangen := atomic.Load(&s.sweepgen)
+ if spangen == sg || spangen == sg+3 {
+ break
+ }
osyield()
}
}