Home | History | Annotate | Download | only in test
      1 // run
      2 
      3 // Copyright 2014 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 finalizers work for tiny (combined) allocations.
      8 
      9 package main
     10 
     11 import (
     12 	"runtime"
     13 	"sync/atomic"
     14 	"time"
     15 )
     16 
     17 func main() {
     18 	// Does not work on 32-bits due to partially conservative GC.
     19 	// Try to enable when we have fully precise GC.
     20 	if runtime.GOARCH != "amd64" {
     21 		return
     22 	}
     23 	// Likewise for gccgo.
     24 	if runtime.Compiler == "gccgo" {
     25 		return
     26 	}
     27 	N := int32(100)
     28 	count := N
     29 	done := make([]bool, N)
     30 	for i := int32(0); i < N; i++ {
     31 		x := i // subject to tiny alloc
     32 		// the closure must be big enough to be combined
     33 		runtime.SetFinalizer(&x, func(p *int32) {
     34 			// Check that p points to the correct subobject of the tiny allocation.
     35 			// It's a bit tricky, because we can't capture another variable
     36 			// with the expected value (it would be combined as well).
     37 			if *p < 0 || *p >= N {
     38 				println("got", *p)
     39 				panic("corrupted")
     40 			}
     41 			if done[*p] {
     42 				println("got", *p)
     43 				panic("already finalized")
     44 			}
     45 			done[*p] = true
     46 			atomic.AddInt32(&count, -1)
     47 		})
     48 	}
     49 	for i := 0; i < 4; i++ {
     50 		runtime.GC()
     51 		time.Sleep(10 * time.Millisecond)
     52 	}
     53 	// Some of the finalizers may not be executed,
     54 	// if the outermost allocations are combined with something persistent.
     55 	// Currently 4 int32's are combined into a 16-byte block,
     56 	// ensure that most of them are finalized.
     57 	if count >= N/4 {
     58 		println(count, "out of", N, "finalizer are not called")
     59 		panic("not all finalizers are called")
     60 	}
     61 }
     62 
     63