aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2015-03-13 14:01:16 -0400
committerAustin Clements <austin@google.com>2015-04-21 15:35:14 +0000
commit028f9728473c6e7590ecaa7d30b0288df4a5731a (patch)
tree94126f07beded061cb8dfd859d2997b6dfdcd2ca /src/runtime
parent8e24283a28f9b739cdbd990994c9c98e3855f7ed (diff)
downloadgo-028f9728473c6e7590ecaa7d30b0288df4a5731a.tar.xz
runtime: make gcDrainN in terms of scan work
Currently, the "n" in gcDrainN is in terms of objects to scan. This is used by gchelpwork to perform a limited amount of work on allocation, but is a pretty arbitrary way to bound this amount of work since the number of objects has little relation to how long they take to scan. Modify gcDrainN to perform a fixed amount of scan work instead. For now, gchelpwork still performs a fairly arbitrary amount of scan work, but at least this is much more closely related to how long the work will take. Shortly, we'll use this to precisely control the scan work performed by mutator assists during allocation to achieve the heap size goal. Change-Id: I3cd07fe0516304298a0af188d0ccdf621d4651cc Reviewed-on: https://go-review.googlesource.com/8835 Reviewed-by: Rick Hudson <rlh@golang.org>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/mgcmark.go15
1 files changed, 10 insertions, 5 deletions
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go
index 38a24ff0e8..5868243428 100644
--- a/src/runtime/mgcmark.go
+++ b/src/runtime/mgcmark.go
@@ -190,8 +190,8 @@ func gchelpwork() {
// be more cache friendly.
var gcw gcWork
gcw.initFromCache()
- const n = len(workbuf{}.obj)
- gcDrainN(&gcw, n) // drain upto one buffer's worth of objects
+ const helpScanWork = 500 // pointers to trace
+ gcDrainN(&gcw, helpScanWork)
// TODO(austin): This is the vast majority of our
// disposes. Instead of constantly disposing, keep a
// per-P gcWork cache (probably combined with the
@@ -407,11 +407,16 @@ func gcDrain(gcw *gcWork, flushScanCredit int64) {
checknocurrentwbuf()
}
-// gcDrainN scans n objects, blackening grey objects.
+// gcDrainN blackens grey objects until it has performed roughly
+// scanWork units of scan work. This is best-effort, so it may perform
+// less work if it fails to get a work buffer. Otherwise, it will
+// perform at least n units of work, but may perform more because
+// scanning is always done in whole object increments.
//go:nowritebarrier
-func gcDrainN(gcw *gcWork, n int) {
+func gcDrainN(gcw *gcWork, scanWork int64) {
checknocurrentwbuf()
- for i := 0; i < n; i++ {
+ targetScanWork := gcw.scanWork + scanWork
+ for gcw.scanWork < targetScanWork {
// This might be a good place to add prefetch code...
// if(wbuf.nobj > 4) {
// PREFETCH(wbuf->obj[wbuf.nobj - 3];