2014-04-11 Marc Glisse <marc.glisse@inria.fr>
[official-gcc.git] / libgo / go / runtime / mfinal_test.go
blob6efef9bb0340e64aca04e6083d07c670cb95d2db
1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package runtime_test
7 import (
8 "runtime"
9 "sync"
10 "sync/atomic"
11 "testing"
12 "time"
15 type Tintptr *int // assignable to *int
16 type Tint int // *Tint implements Tinter, interface{}
18 func (t *Tint) m() {}
20 type Tinter interface {
21 m()
24 func TestFinalizerType(t *testing.T) {
25 if runtime.GOARCH != "amd64" {
26 t.Skipf("Skipping on non-amd64 machine")
29 ch := make(chan bool, 10)
30 finalize := func(x *int) {
31 if *x != 97531 {
32 t.Errorf("finalizer %d, want %d", *x, 97531)
34 ch <- true
37 var finalizerTests = []struct {
38 convert func(*int) interface{}
39 finalizer interface{}
41 {func(x *int) interface{} { return x }, func(v *int) { finalize(v) }},
42 {func(x *int) interface{} { return Tintptr(x) }, func(v Tintptr) { finalize(v) }},
43 {func(x *int) interface{} { return Tintptr(x) }, func(v *int) { finalize(v) }},
44 {func(x *int) interface{} { return (*Tint)(x) }, func(v *Tint) { finalize((*int)(v)) }},
45 {func(x *int) interface{} { return (*Tint)(x) }, func(v Tinter) { finalize((*int)(v.(*Tint))) }},
48 for _, tt := range finalizerTests {
49 go func() {
50 v := new(int)
51 *v = 97531
52 runtime.SetFinalizer(tt.convert(v), tt.finalizer)
53 v = nil
54 }()
55 time.Sleep(1 * time.Second)
56 runtime.GC()
57 select {
58 case <-ch:
59 case <-time.After(time.Second * 4):
60 t.Errorf("finalizer for type %T didn't run", tt.finalizer)
65 type bigValue struct {
66 fill uint64
67 it bool
68 up string
71 func TestFinalizerInterfaceBig(t *testing.T) {
72 if runtime.GOARCH != "amd64" {
73 t.Skipf("Skipping on non-amd64 machine")
75 ch := make(chan bool)
76 go func() {
77 v := &bigValue{0xDEADBEEFDEADBEEF, true, "It matters not how strait the gate"}
78 old := *v
79 runtime.SetFinalizer(v, func(v interface{}) {
80 i, ok := v.(*bigValue)
81 if !ok {
82 t.Errorf("finalizer called with type %T, want *bigValue", v)
84 if *i != old {
85 t.Errorf("finalizer called with %+v, want %+v", *i, old)
87 close(ch)
89 v = nil
90 }()
91 time.Sleep(1 * time.Second)
92 runtime.GC()
93 select {
94 case <-ch:
95 case <-time.After(4 * time.Second):
96 t.Errorf("finalizer for type *bigValue didn't run")
100 func fin(v *int) {
103 func BenchmarkFinalizer(b *testing.B) {
104 const CallsPerSched = 1000
105 procs := runtime.GOMAXPROCS(-1)
106 N := int32(b.N / CallsPerSched)
107 var wg sync.WaitGroup
108 wg.Add(procs)
109 for p := 0; p < procs; p++ {
110 go func() {
111 var data [CallsPerSched]*int
112 for i := 0; i < CallsPerSched; i++ {
113 data[i] = new(int)
115 for atomic.AddInt32(&N, -1) >= 0 {
116 runtime.Gosched()
117 for i := 0; i < CallsPerSched; i++ {
118 runtime.SetFinalizer(data[i], fin)
120 for i := 0; i < CallsPerSched; i++ {
121 runtime.SetFinalizer(data[i], nil)
124 wg.Done()
127 wg.Wait()
130 func BenchmarkFinalizerRun(b *testing.B) {
131 const CallsPerSched = 1000
132 procs := runtime.GOMAXPROCS(-1)
133 N := int32(b.N / CallsPerSched)
134 var wg sync.WaitGroup
135 wg.Add(procs)
136 for p := 0; p < procs; p++ {
137 go func() {
138 for atomic.AddInt32(&N, -1) >= 0 {
139 runtime.Gosched()
140 for i := 0; i < CallsPerSched; i++ {
141 v := new(int)
142 runtime.SetFinalizer(v, fin)
144 runtime.GC()
146 wg.Done()
149 wg.Wait()