diff options
author | Austin Clements <austin@google.com> | 2019-10-08 13:23:51 -0400 |
---|---|---|
committer | Austin Clements <austin@google.com> | 2019-11-02 21:51:18 +0000 |
commit | 62e53b79227dafc6afcd92240c89acb8c0e1dd56 (patch) | |
tree | 40e85fda03128d81c0146857f0456d9ea55c32f0 /src/runtime/mgcmark.go | |
parent | d16ec137568fb20e674a99c265e7c340c065dd69 (diff) | |
download | go-62e53b79227dafc6afcd92240c89acb8c0e1dd56.tar.gz go-62e53b79227dafc6afcd92240c89acb8c0e1dd56.zip |
runtime: use signals to preempt Gs for suspendG
This adds support for pausing a running G by sending a signal to its
M.
The main complication is that we want to target a G, but can only send
a signal to an M. Hence, the protocol we use is to simply mark the G
for preemption (which we already do) and send the M a "wake up and
look around" signal. The signal checks if it's running a G with a
preemption request and stops it if so in the same way that stack check
preemptions stop Gs. Since the preemption may fail (the G could be
moved or the signal could arrive at an unsafe point), we keep a count
of the number of received preemption signals. This lets stopG detect
if its request failed and should be retried without an explicit
channel back to suspendG.
For #10958, #24543.
Change-Id: I3e1538d5ea5200aeb434374abb5d5fdc56107e53
Reviewed-on: https://go-review.googlesource.com/c/go/+/201760
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/runtime/mgcmark.go')
-rw-r--r-- | src/runtime/mgcmark.go | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go index 0087408a72..10b525b2bc 100644 --- a/src/runtime/mgcmark.go +++ b/src/runtime/mgcmark.go @@ -196,7 +196,7 @@ func markroot(gcw *gcWork, i uint32) { gp.waitsince = work.tstart } - // scang must be done on the system stack in case + // scanstack must be done on the system stack in case // we're trying to scan our own stack. systemstack(func() { // If this is a self-scan, put the user G in @@ -716,6 +716,10 @@ func scanstack(gp *g, gcw *gcWork) { println("stack trace goroutine", gp.goid) } + if debugScanConservative && gp.asyncSafePoint { + print("scanning async preempted goroutine ", gp.goid, " stack [", hex(gp.stack.lo), ",", hex(gp.stack.hi), ")\n") + } + // Scan the saved context register. This is effectively a live // register that gets moved back and forth between the // register and sched.ctxt without a write barrier. |