From 3f834114ab617eb7b414cb12e7ca8085b5fe3a5c Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Fri, 27 Sep 2019 12:27:51 -0400 Subject: runtime: add general suspendG/resumeG Currently, the process of suspending a goroutine is tied to stack scanning. In preparation for non-cooperative preemption, this CL abstracts this into general purpose suspendG/resumeG functions. suspendG and resumeG closely follow the existing scang and restartg functions with one exception: the addition of a _Gpreempted status. Currently, preemption tasks (stack scanning) are carried out by the target goroutine if it's in _Grunning. In this new approach, the task is always carried out by the goroutine that called suspendG. Thus, we need a reliable way to drive the target goroutine out of _Grunning until the requesting goroutine is ready to resume it. The new _Gpreempted state provides the handshake: when a runnable goroutine responds to a preemption request, it now parks itself and enters _Gpreempted. The requesting goroutine races to put it in _Gwaiting, which gives it ownership, but also the responsibility to start it again. This CL adds several TODOs about improving the synchronization on the G status. The existing code already has these problems; we're just taking note of them. The next CL will remove the now-dead scang and preemptscan. For #10958, #24543. Change-Id: I16dbf87bea9d50399cc86719c156f48e67198f16 Reviewed-on: https://go-review.googlesource.com/c/go/+/201137 Run-TryBot: Austin Clements TryBot-Result: Gobot Gobot Reviewed-by: Cherry Zhang --- src/runtime/stack.go | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/runtime/stack.go') diff --git a/src/runtime/stack.go b/src/runtime/stack.go index 93f9769899..3b92c89ff0 100644 --- a/src/runtime/stack.go +++ b/src/runtime/stack.go @@ -1017,6 +1017,11 @@ func newstack() { if thisg.m.p == 0 && thisg.m.locks == 0 { throw("runtime: g is running but p is not") } + + if gp.preemptStop { + preemptPark(gp) // never returns + } + // Synchronize with scang. casgstatus(gp, _Grunning, _Gwaiting) if gp.preemptscan { -- cgit v1.3