aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2015-03-20 13:34:03 -0400
committerAustin Clements <austin@google.com>2015-03-31 01:05:38 +0000
commita2f3d73fee16ee2a4662593f3bcdd1cdb99a7961 (patch)
treea512b1712a3316fc541b728248bdf859da2ce2a6 /src
parenta4374c1de1d4fd924a11e055ca55efde11b258da (diff)
downloadgo-a2f3d73fee16ee2a4662593f3bcdd1cdb99a7961.tar.xz
runtime: improve comment about non-preemption during GC work
Currently, gcDrainN is documented saying that it must be run on the system stack. In fact, the problem and solution here are somewhat subtler. First, it doesn't have to happen on the system stack, it just has to be non-stoppable (that is, non-preemptible). Second, this isn't specific to gcDrainN (though gcDrainN is perhaps the most surprising instance); it's general to anything that uses the gcWork structure. Move the comment to gcWork and generalize it. Change-Id: I5277b5abb070e47f8d783bc15a310b379c6adc22 Reviewed-on: https://go-review.googlesource.com/8247 Reviewed-by: Rick Hudson <rlh@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/runtime/mgcmark.go3
-rw-r--r--src/runtime/mgcwork.go7
2 files changed, 7 insertions, 3 deletions
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go
index f6452ea133..bdb5888a28 100644
--- a/src/runtime/mgcmark.go
+++ b/src/runtime/mgcmark.go
@@ -366,9 +366,6 @@ func gcDrain(gcw *gcWork) {
}
// gcDrainN scans n objects, blackening grey objects.
-//
-// This MUST be run on the system stack to prevent a stop-the-world
-// while this locally holds GC work buffers.
//go:nowritebarrier
func gcDrainN(gcw *gcWork, n int) {
checknocurrentwbuf()
diff --git a/src/runtime/mgcwork.go b/src/runtime/mgcwork.go
index ecf603a739..f69d6bb6a1 100644
--- a/src/runtime/mgcwork.go
+++ b/src/runtime/mgcwork.go
@@ -41,8 +41,15 @@ func (wp wbufptr) ptr() *workbuf {
// The usual pattern for using gcWork is:
//
// var gcw gcWork
+// disable preemption
// .. call gcw.put() to produce and gcw.get() to consume ..
// gcw.dispose()
+// enable preemption
+//
+// It's important that any use of gcWork during the mark phase prevent
+// the garbage collector from transitioning to mark termination since
+// gcWork may locally hold GC work buffers. This can be done by
+// disabling preemption (systemstack or acquirem).
type gcWork struct {
// Invariant: wbuf is never full or empty
wbuf wbufptr