On Thu, Aug 6, 2020 at 7:49 AM HailangGe <[email protected]> wrote: > > Recently I was trying to understand how asynchronous preemption is > implemented in Go 1.14 and > basically figured out the call chain. > > sysmon > ↓ > retake > ↓ > preemptone > ↓ > preemptM > ↓ > signalM(mp, sigPreempt) //send SIGURG to mp > ↓ > doSigPreempt(signal handler) //if isAsyncSafePoint returns true, it > will go on to preempt > ↓ > ctxt.pushCall(funcPC(asyncPreempt)) > ↓ > asyncPreempt > ↓ > asyncPreempt2 > ↓ > mcall(preemptPark) or mcall(gopreempt_m) > > And I wrote a simple program to verify: > ```Go > func main() { > var wg sync.WaitGroup > wg.Add(30) > for i := 0; i < 30; i++ { > go func() { > defer wg.Done() > t := 0 > for i := 0; i < 1e8; i++ { > t += 2 > } > }() > } > wg.Wait() > } > ``` > > As we know general purpose registers RAX/RBX/... are not included in > goroutine context.
That is true but it doesn't matter. asyncPreempt is a GOARCH-specific routine that saves all registers. When the preempted goroutine is resumed, it will return through asyncPreempt and the registers will be restored before continuing with execution. > My problem is how Go judges which instruction is preemptable? is it > determined at compile time? There are other, less common, cases where preemption is not permitted, and, yes, those are marked by the compiler and checked by isAsyncSafePoint. Ian -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAOyqgcU2QjD-gL0URm%3DYWyQh%3DyTr0E93CAVrKkYNirGgNHLjGw%40mail.gmail.com.
