modernc.org/gc@v1.0.1-0.20240304020402-f0dba7c97c2b/testdata/errchk/test/mallocfin.go (about) 1 // run 2 3 // Copyright 2009 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 7 // Test basic operation of finalizers. 8 9 package main 10 11 import ( 12 "runtime" 13 "time" 14 ) 15 16 const N = 250 17 18 type A struct { 19 b *B 20 n int 21 } 22 23 type B struct { 24 n int 25 } 26 27 var i int 28 var nfinal int 29 var final [N]int 30 31 // the unused return is to test finalizers with return values 32 func finalA(a *A) (unused [N]int) { 33 if final[a.n] != 0 { 34 println("finalA", a.n, final[a.n]) 35 panic("fail") 36 } 37 final[a.n] = 1 38 return 39 } 40 41 func finalB(b *B) { 42 if final[b.n] != 1 { 43 println("finalB", b.n, final[b.n]) 44 panic("fail") 45 } 46 final[b.n] = 2 47 nfinal++ 48 } 49 50 func nofinalB(b *B) { 51 panic("nofinalB run") 52 } 53 54 func main() { 55 runtime.GOMAXPROCS(4) 56 for i = 0; i < N; i++ { 57 b := &B{i} 58 a := &A{b, i} 59 c := new(B) 60 runtime.SetFinalizer(c, nofinalB) 61 runtime.SetFinalizer(b, finalB) 62 runtime.SetFinalizer(a, finalA) 63 runtime.SetFinalizer(c, nil) 64 } 65 for i := 0; i < N; i++ { 66 runtime.GC() 67 runtime.Gosched() 68 time.Sleep(1e6) 69 if nfinal >= N*8/10 { 70 break 71 } 72 } 73 if nfinal < N*8/10 { 74 println("not enough finalizing:", nfinal, "/", N) 75 panic("fail") 76 } 77 }