Source file src/runtime/testdata/testprog/preempt.go

     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  	// Out of an abundance of caution, also make sure that there are
    24  	// no GCs actively in progress. The sweep phase of a GC cycle
    25  	// for instance tries to preempt Ps at the very beginning.
    26  	runtime.GC()
    27  
    28  	// Start a goroutine with no sync safe-points.
    29  	var ready, ready2 uint32
    30  	go func() {
    31  		for {
    32  			atomic.StoreUint32(&ready, 1)
    33  			dummy()
    34  			dummy()
    35  		}
    36  	}()
    37  	// Also start one with a frameless function.
    38  	// This is an especially interesting case for
    39  	// LR machines.
    40  	go func() {
    41  		atomic.AddUint32(&ready2, 1)
    42  		frameless()
    43  	}()
    44  	// Also test empty infinite loop.
    45  	go func() {
    46  		atomic.AddUint32(&ready2, 1)
    47  		for {
    48  		}
    49  	}()
    50  
    51  	// Wait for the goroutine to stop passing through sync
    52  	// safe-points.
    53  	for atomic.LoadUint32(&ready) == 0 || atomic.LoadUint32(&ready2) < 2 {
    54  		runtime.Gosched()
    55  	}
    56  
    57  	// Run a GC, which will have to stop the goroutine for STW and
    58  	// for stack scanning. If this doesn't work, the test will
    59  	// deadlock and timeout.
    60  	runtime.GC()
    61  
    62  	println("OK")
    63  }
    64  
    65  //go:noinline
    66  func frameless() {
    67  	for i := int64(0); i < 1<<62; i++ {
    68  		out += i * i * i * i * i * 12345
    69  	}
    70  }
    71  
    72  var out int64
    73  
    74  //go:noinline
    75  func dummy() {}
    76  

View as plain text