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() {}