github.com/go-darwin/sys@v0.0.0-20220510002607-68fd01f054ca/testdata/testprog/preempt.go (about) 1 // Copyright 2019 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "runtime" 9 "runtime/debug" 10 "sync/atomic" 11 ) 12 13 func init() { 14 register("AsyncPreempt", AsyncPreempt) 15 } 16 17 func AsyncPreempt() { 18 // Run with just 1 GOMAXPROCS so the runtime is required to 19 // use scheduler preemption. 20 runtime.GOMAXPROCS(1) 21 // Disable GC so we have complete control of what we're testing. 22 debug.SetGCPercent(-1) 23 24 // Start a goroutine with no sync safe-points. 25 var ready, ready2 uint32 26 go func() { 27 for { 28 atomic.StoreUint32(&ready, 1) 29 dummy() 30 dummy() 31 } 32 }() 33 // Also start one with a frameless function. 34 // This is an especially interesting case for 35 // LR machines. 36 go func() { 37 atomic.AddUint32(&ready2, 1) 38 frameless() 39 }() 40 // Also test empty infinite loop. 41 go func() { 42 atomic.AddUint32(&ready2, 1) 43 for { 44 } 45 }() 46 47 // Wait for the goroutine to stop passing through sync 48 // safe-points. 49 for atomic.LoadUint32(&ready) == 0 || atomic.LoadUint32(&ready2) < 2 { 50 runtime.Gosched() 51 } 52 53 // Run a GC, which will have to stop the goroutine for STW and 54 // for stack scanning. If this doesn't work, the test will 55 // deadlock and timeout. 56 runtime.GC() 57 58 println("OK") 59 } 60 61 //go:noinline 62 func frameless() { 63 for i := int64(0); i < 1<<62; i++ { 64 out += i * i * i * i * i * 12345 65 } 66 } 67 68 var out int64 69 70 //go:noinline 71 func dummy() {}