diff options
Diffstat (limited to 'src/runtime/mcleanup_test.go')
| -rw-r--r-- | src/runtime/mcleanup_test.go | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/runtime/mcleanup_test.go b/src/runtime/mcleanup_test.go index d62356feef..22b9eccd20 100644 --- a/src/runtime/mcleanup_test.go +++ b/src/runtime/mcleanup_test.go @@ -5,8 +5,11 @@ package runtime_test import ( + "internal/runtime/atomic" "runtime" + "sync" "testing" + "time" "unsafe" ) @@ -296,3 +299,40 @@ func TestCleanupPointerEqualsArg(t *testing.T) { v = nil runtime.GC() } + +// Checks to make sure cleanups aren't lost when there are a lot of them. +func TestCleanupLost(t *testing.T) { + type T struct { + v int + p unsafe.Pointer + } + + cleanups := 10_000 + if testing.Short() { + cleanups = 100 + } + n := runtime.GOMAXPROCS(-1) + want := n * cleanups + var got atomic.Uint64 + var wg sync.WaitGroup + for i := range n { + wg.Add(1) + go func(i int) { + defer wg.Done() + + for range cleanups { + v := &new(T).v + *v = 97531 + runtime.AddCleanup(v, func(_ int) { + got.Add(1) + }, 97531) + } + }(i) + } + wg.Wait() + runtime.GC() + runtime.BlockUntilEmptyCleanupQueue(int64(10 * time.Second)) + if got := int(got.Load()); got != want { + t.Errorf("expected %d cleanups to be executed, got %d", got, want) + } +} |
