blob: 8fb109fc06d6b24042e824299fba675799e48aad [file] [log] [blame]
Dmitriy Vyukov1fa70292014-01-24 22:35:11 +04001// 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
9package main
10
11import (
12 "runtime"
13 "sync/atomic"
14 "time"
15)
16
17func 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