libgo: Update to Go 1.3 release.
[official-gcc.git] / libgo / go / sync / pool_test.go
blobc13477de9045d7e033e279f3166a14188c02d95d
1 // Copyright 2013 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 // Pool is no-op under race detector, so all these tests do not work.
6 // +build !race
8 package sync_test
10 import (
11 "runtime"
12 "runtime/debug"
13 . "sync"
14 "sync/atomic"
15 "testing"
16 "time"
19 func TestPool(t *testing.T) {
20 // disable GC so we can control when it happens.
21 defer debug.SetGCPercent(debug.SetGCPercent(-1))
22 var p Pool
23 if p.Get() != nil {
24 t.Fatal("expected empty")
26 p.Put("a")
27 p.Put("b")
28 if g := p.Get(); g != "a" {
29 t.Fatalf("got %#v; want a", g)
31 if g := p.Get(); g != "b" {
32 t.Fatalf("got %#v; want b", g)
34 if g := p.Get(); g != nil {
35 t.Fatalf("got %#v; want nil", g)
38 p.Put("c")
39 debug.SetGCPercent(100) // to allow following GC to actually run
40 runtime.GC()
41 if g := p.Get(); g != nil {
42 t.Fatalf("got %#v; want nil after GC", g)
46 func TestPoolNew(t *testing.T) {
47 // disable GC so we can control when it happens.
48 defer debug.SetGCPercent(debug.SetGCPercent(-1))
50 i := 0
51 p := Pool{
52 New: func() interface{} {
53 i++
54 return i
57 if v := p.Get(); v != 1 {
58 t.Fatalf("got %v; want 1", v)
60 if v := p.Get(); v != 2 {
61 t.Fatalf("got %v; want 2", v)
63 p.Put(42)
64 if v := p.Get(); v != 42 {
65 t.Fatalf("got %v; want 42", v)
67 if v := p.Get(); v != 3 {
68 t.Fatalf("got %v; want 3", v)
72 // Test that Pool does not hold pointers to previously cached
73 // resources
74 func TestPoolGC(t *testing.T) {
75 var p Pool
76 var fin uint32
77 const N = 100
78 for i := 0; i < N; i++ {
79 v := new(string)
80 runtime.SetFinalizer(v, func(vv *string) {
81 atomic.AddUint32(&fin, 1)
83 p.Put(v)
85 for i := 0; i < N; i++ {
86 p.Get()
88 for i := 0; i < 5; i++ {
89 runtime.GC()
90 time.Sleep(time.Duration(i*100+10) * time.Millisecond)
91 // 1 pointer can remain on stack or elsewhere
92 if atomic.LoadUint32(&fin) >= N-1 {
93 return
96 // gccgo has a less precise heap.
97 if runtime.Compiler == "gccgo" && atomic.LoadUint32(&fin) >= N-5 {
98 return
101 t.Fatalf("only %v out of %v resources are finalized",
102 atomic.LoadUint32(&fin), N)
105 func TestPoolStress(t *testing.T) {
106 const P = 10
107 N := int(1e6)
108 if testing.Short() {
109 N /= 100
111 var p Pool
112 done := make(chan bool)
113 for i := 0; i < P; i++ {
114 go func() {
115 var v interface{} = 0
116 for j := 0; j < N; j++ {
117 if v == nil {
118 v = 0
120 p.Put(v)
121 v = p.Get()
122 if v != nil && v.(int) != 0 {
123 t.Fatalf("expect 0, got %v", v)
126 done <- true
129 for i := 0; i < P; i++ {
130 <-done
134 func BenchmarkPool(b *testing.B) {
135 var p Pool
136 b.RunParallel(func(pb *testing.PB) {
137 for pb.Next() {
138 p.Put(1)
139 p.Get()
144 func BenchmarkPoolOverlflow(b *testing.B) {
145 var p Pool
146 b.RunParallel(func(pb *testing.PB) {
147 for pb.Next() {
148 for b := 0; b < 100; b++ {
149 p.Put(1)
151 for b := 0; b < 100; b++ {
152 p.Get()