1// run 2 3// Copyright 2023 The Go Authors. All rights reserved. 4// Use of this source code is governed by a BSD-style 5// license that can be found in the LICENSE file. 6 7package main 8 9import ( 10 "sync" 11 "time" 12) 13 14type B struct { 15 pid int 16 f func() (uint64, error) 17 wg sync.WaitGroup 18 v uint64 19} 20 21func newB(pid int) *B { 22 return &B{ 23 pid: pid, 24 } 25} 26 27//go:noinline 28func Sq(i int) uint64 { 29 S++ 30 return uint64(i * i) 31} 32 33type RO func(*B) 34 35var ROSL = []RO{ 36 Bad(), 37} 38 39func Bad() RO { 40 return func(b *B) { 41 b.f = func() (uint64, error) { 42 return Sq(b.pid), nil 43 } 44 } 45} 46 47func (b *B) startit() chan<- struct{} { 48 stop := make(chan struct{}) 49 b.wg.Add(1) 50 go func() { 51 defer b.wg.Done() 52 var v uint64 53 for { 54 select { 55 case <-stop: 56 b.v = v 57 return 58 case <-time.After(1 * time.Millisecond): 59 r, err := b.f() 60 if err != nil { 61 panic("bad") 62 } 63 v = r 64 } 65 } 66 }() 67 return stop 68} 69 70var S, G int 71 72//go:noinline 73func rec(x int) int { 74 if x == 0 { 75 return 9 76 } 77 return rec(x-1) + 1 78} 79 80//go:noinline 81func recur(x int) { 82 for i := 0; i < x; i++ { 83 G = rec(i) 84 } 85} 86 87func main() { 88 b := newB(17) 89 for _, opt := range ROSL { 90 opt(b) 91 } 92 stop := b.startit() 93 94 // see if we can get some stack growth/moving 95 recur(10101) 96 97 if stop != nil { 98 stop <- struct{}{} 99 } 100} 101