codekingpro/portable-devtools
114k
1// run2 3// Copyright 2014 The Go Authors. All rights reserved.4// Use of this source code is governed by a BSD-style5// license that can be found in the LICENSE file.6 7// Test finalizers work for tiny (combined) allocations.8 9package main10 11import (12 "runtime"13 "time"14)15 16func 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 return21 }22 const N = 10023 finalized := make(chan int32, N)24 for i := 0; i < N; i++ {25 x := new(int32) // subject to tiny alloc26 *x = int32(i)27 // the closure must be big enough to be combined28 runtime.SetFinalizer(x, func(p *int32) {29 finalized <- *p30 })31 }32 runtime.GC()33 count := 034 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 variable44 // 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] = true54 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 return61 }62 }63 }64}65 