diff options
| author | Damien Neil <dneil@google.com> | 2025-06-06 12:59:04 -0700 |
|---|---|---|
| committer | Damien Neil <dneil@google.com> | 2025-06-09 11:15:04 -0700 |
| commit | 985d600f3aa8654b854f8b2c822552c052ed3d30 (patch) | |
| tree | 75e72f64c08378a987f2e5e87883a4d91187b097 /src/runtime/testdata | |
| parent | 848a768ba76d7c386c2aa4f05bc2e9e51b5948b9 (diff) | |
| download | go-985d600f3aa8654b854f8b2c822552c052ed3d30.tar.xz | |
runtime: use small struct TestSynctest to ensure cleanups run
Finalizers and cleanup funcs weren't running on the windows-arm64
builder. Put finalizers/cleanups on a small struct containing a pointer
rather than an *int, which fixes the problem.
Also uncomment a synctest.Wait that was accidentally commented out.
Fixes #73977
Change-Id: Ia6f18d74d6fccf2c5a9222317977c7458d67f158
Reviewed-on: https://go-review.googlesource.com/c/go/+/679696
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/runtime/testdata')
| -rw-r--r-- | src/runtime/testdata/testsynctest/main.go | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/src/runtime/testdata/testsynctest/main.go b/src/runtime/testdata/testsynctest/main.go index b47e3fcfc9..973d3eac02 100644 --- a/src/runtime/testdata/testsynctest/main.go +++ b/src/runtime/testdata/testsynctest/main.go @@ -9,6 +9,7 @@ import ( "runtime" "runtime/metrics" "sync/atomic" + "unsafe" ) // This program ensures system goroutines (GC workers, finalizer goroutine) @@ -27,6 +28,11 @@ func numGCCycles() uint64 { return samples[0].Value.Uint64() } +type T struct { + v int + p unsafe.Pointer +} + func main() { // Channels created by a finalizer and cleanup func registered within the bubble. var ( @@ -36,8 +42,8 @@ func main() { synctest.Run(func() { // Start the finalizer and cleanup goroutines. { - p := new(int) - runtime.SetFinalizer(p, func(*int) { + p := new(T) + runtime.SetFinalizer(p, func(*T) { ch := make(chan struct{}) finalizerCh.Store(&ch) }) @@ -47,35 +53,35 @@ func main() { }, struct{}{}) } startingCycles := numGCCycles() - ch1 := make(chan *int) - ch2 := make(chan *int) + ch1 := make(chan *T) + ch2 := make(chan *T) defer close(ch1) go func() { - for i := range ch1 { - v := *i + 1 - ch2 <- &v + for range ch1 { + ch2 <- &T{} } }() - for { + const iterations = 1000 + for range iterations { // Make a lot of short-lived allocations to get the GC working. - for i := 0; i < 1000; i++ { - v := new(int) - *v = i + for range 1000 { + v := new(T) // Set finalizers on these values, just for added stress. - runtime.SetFinalizer(v, func(*int) {}) + runtime.SetFinalizer(v, func(*T) {}) ch1 <- v <-ch2 } // If we've improperly put a GC goroutine into the synctest group, // this Wait is going to hang. - //synctest.Wait() + synctest.Wait() // End the test after a couple of GC cycles have passed. if numGCCycles()-startingCycles > 1 && finalizerCh.Load() != nil && cleanupCh.Load() != nil { - break + return } } + println("finalizers/cleanups failed to run after", iterations, "cycles") }) // Close the channels created by the finalizer and cleanup func. // If the funcs improperly ran inside the bubble, these channels are bubbled |
