github.com/s1s1ty/go@v0.0.0-20180207192209-104445e3140f/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  }