...
Run Format

Source file test/tinyfin.go

Documentation: test

  // run
  
  // Copyright 2014 The Go Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  // Test finalizers work for tiny (combined) allocations.
  
  package main
  
  import (
  	"runtime"
  	"time"
  )
  
  func main() {
  	// Does not work on gccgo due to partially conservative GC.
  	// Try to enable when we have fully precise GC.
  	if runtime.Compiler == "gccgo" {
  		return
  	}
  	const N = 100
  	finalized := make(chan int32, N)
  	for i := 0; i < N; i++ {
  		x := new(int32) // subject to tiny alloc
  		*x = int32(i)
  		// the closure must be big enough to be combined
  		runtime.SetFinalizer(x, func(p *int32) {
  			finalized <- *p
  		})
  	}
  	runtime.GC()
  	count := 0
  	done := make([]bool, N)
  	timeout := time.After(5*time.Second)
  	for {
  		select {
  		case <-timeout:
  			println("timeout,", count, "finalized so far")
  			panic("not all finalizers are called")
  		case x := <-finalized:
  			// Check that p points to the correct subobject of the tiny allocation.
  			// It's a bit tricky, because we can't capture another variable
  			// with the expected value (it would be combined as well).
  			if x < 0 || x >= N {
  				println("got", x)
  				panic("corrupted")
  			}
  			if done[x] {
  				println("got", x)
  				panic("already finalized")
  			}
  			done[x] = true
  			count++
  			if count > N/10*9 {
  				// Some of the finalizers may not be executed,
  				// if the outermost allocations are combined with something persistent.
  				// Currently 4 int32's are combined into a 16-byte block,
  				// ensure that most of them are finalized.
  				return
  			}
  		}
  	}
  }
  

View as plain text