aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/symtab.go
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2019-10-08 13:23:51 -0400
committerAustin Clements <austin@google.com>2019-11-02 21:51:18 +0000
commit62e53b79227dafc6afcd92240c89acb8c0e1dd56 (patch)
tree40e85fda03128d81c0146857f0456d9ea55c32f0 /src/runtime/symtab.go
parentd16ec137568fb20e674a99c265e7c340c065dd69 (diff)
downloadgo-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/symtab.go')
-rw-r--r--src/runtime/symtab.go19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go
index 35960e89c5..ddcf231929 100644
--- a/src/runtime/symtab.go
+++ b/src/runtime/symtab.go
@@ -784,6 +784,25 @@ func funcspdelta(f funcInfo, targetpc uintptr, cache *pcvalueCache) int32 {
return x
}
+// funcMaxSPDelta returns the maximum spdelta at any point in f.
+func funcMaxSPDelta(f funcInfo) int32 {
+ datap := f.datap
+ p := datap.pclntable[f.pcsp:]
+ pc := f.entry
+ val := int32(-1)
+ max := int32(0)
+ for {
+ var ok bool
+ p, ok = step(p, &pc, &val, pc == f.entry)
+ if !ok {
+ return max
+ }
+ if val > max {
+ max = val
+ }
+ }
+}
+
func pcdatastart(f funcInfo, table int32) int32 {
return *(*int32)(add(unsafe.Pointer(&f.nfuncdata), unsafe.Sizeof(f.nfuncdata)+uintptr(table)*4))
}