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 	"time"
     14 )
     15 
     16 func main() {
     17 	// Does not work on gccgo due to partially conservative GC.
     18 	// Try to enable when we have fully precise GC.
     19 	if runtime.Compiler == "gccgo" {
     20 		return
     21 	}
     22 	const N = 100
     23 	finalized := make(chan int32, N)
     24 	for i := 0; i < N; i++ {
     25 		x := new(int32) // subject to tiny alloc
     26 		*x = int32(i)
     27 		// the closure must be big enough to be combined
     28 		runtime.SetFinalizer(x, func(p *int32) {
     29 			finalized <- *p
     30 		})
     31 	}
     32 	runtime.GC()
     33 	count := 0
     34 	done := make([]bool, N)
     35 	timeout := time.After(5*time.Second)
     36 	for {
     37 		select {
     38 		case <-timeout:
     39 			println("timeout,", count, "finalized so far")
     40 			panic("not all finalizers are called")
     41 		case x := <-finalized:
     42 			// Check that p points to the correct subobject of the tiny allocation.
     43 			// It's a bit tricky, because we can't capture another variable
     44 			// with the expected value (it would be combined as well).
     45 			if x < 0 || x >= N {
     46 				println("got", x)
     47 				panic("corrupted")
     48 			}
     49 			if done[x] {
     50 				println("got", x)
     51 				panic("already finalized")
     52 			}
     53 			done[x] = true
     54 			count++
     55 			if count > N/10*9 {
     56 				// Some of the finalizers may not be executed,
     57 				// if the outermost allocations are combined with something persistent.
     58 				// Currently 4 int32's are combined into a 16-byte block,
     59 				// ensure that most of them are finalized.
     60 				return
     61 			}
     62 		}
     63 	}
     64 }
     65