github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/test/tinyfin.go (about) 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