Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1598)

Delta Between Two Patch Sets: src/pkg/sync/pool_test.go

Issue 41860043: code review 41860043: sync: add Pool type (Closed)
Left Patch Set: diff -r c37a24ac952c https://go.googlecode.com/hg/ Created 10 years, 3 months ago
Right Patch Set: diff -r 477af6a8e51f https://go.googlecode.com/hg/ Created 10 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/pkg/sync/pool.go ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Copyright 2013 The Go Authors. All rights reserved. 1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 package sync_test 5 package sync_test
6 6
7 import ( 7 import (
8 "runtime" 8 "runtime"
9 "runtime/debug"
9 . "sync" 10 . "sync"
11 "sync/atomic"
10 "testing" 12 "testing"
13 "time"
14 "unsafe"
11 ) 15 )
12 16
13 func TestPoolNumGC(t *testing.T) {
14 var n1, n2 uint32
15 runtime.GC()
16 Sync_readNumGC(&n1)
17 runtime.GC()
18 Sync_readNumGC(&n2)
19 if n2 <= n1 {
20 t.Errorf("gc count didn't increment: %d -> %d", n1, n2)
21 }
22 }
23
24 func TestPool(t *testing.T) { 17 func TestPool(t *testing.T) {
18 // disable GC so we can control when it happens.
19 defer debug.SetGCPercent(debug.SetGCPercent(-1))
25 var p Pool 20 var p Pool
26 if p.Get() != nil { 21 if p.Get() != nil {
27 t.Fatal("expected empty") 22 t.Fatal("expected empty")
28 } 23 }
29 p.Put("a") 24 p.Put("a")
30 p.Put("b") 25 p.Put("b")
31 if g := p.Get(); g != "b" { 26 if g := p.Get(); g != "b" {
32 t.Fatalf("got %#v; want b", g) 27 t.Fatalf("got %#v; want b", g)
33 } 28 }
34 if g := p.Get(); g != "a" { 29 if g := p.Get(); g != "a" {
35 t.Fatalf("got %#v; want a", g) 30 t.Fatalf("got %#v; want a", g)
36 } 31 }
37 if g := p.Get(); g != nil { 32 if g := p.Get(); g != nil {
38 t.Fatalf("got %#v; want nil", g) 33 t.Fatalf("got %#v; want nil", g)
39 } 34 }
40 35
41 p.Put("c") 36 p.Put("c")
37 debug.SetGCPercent(100) // to allow following GC to actually run
42 runtime.GC() 38 runtime.GC()
43 if g := p.Get(); g != nil { 39 if g := p.Get(); g != nil {
44 t.Fatalf("got %#v; want nil after GC", g) 40 t.Fatalf("got %#v; want nil after GC", g)
45 } 41 }
46 } 42 }
47 43
48 func BenchmarkPool1(b *testing.B) { 44 func TestPoolNew(t *testing.T) {
49 » var p Pool 45 » // disable GC so we can control when it happens.
50 » for i := 0; i < b.N; i++ { 46 » defer debug.SetGCPercent(debug.SetGCPercent(-1))
51 » » p.Put(1) 47
52 » » p.Get() 48 » i := 0
49 » p := Pool{
50 » » New: func() interface{} {
51 » » » i++
52 » » » return i
53 » » },
54 » }
55 » if v := p.Get(); v != 1 {
56 » » t.Fatalf("got %v; want 1", v)
57 » }
58 » if v := p.Get(); v != 2 {
59 » » t.Fatalf("got %v; want 2", v)
60 » }
61 » p.Put(42)
62 » if v := p.Get(); v != 42 {
63 » » t.Fatalf("got %v; want 42", v)
64 » }
65 » if v := p.Get(); v != 3 {
66 » » t.Fatalf("got %v; want 3", v)
53 } 67 }
54 } 68 }
55 69
56 func BenchmarkPool2(b *testing.B) { 70 // Test that Pool does not hold pointers to previously cached
57 » defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2)) 71 // resources
72 func TestPoolGC(t *testing.T) {
73 » var p Pool
74 » var fin uint32
75 » const N = 100
76 » for i := 0; i < N; i++ {
77 » » v := new(int)
78 » » runtime.SetFinalizer(v, func(vv *int) {
79 » » » atomic.AddUint32(&fin, 1)
80 » » })
81 » » p.Put(v)
82 » }
83 » for i := 0; i < N; i++ {
84 » » p.Get()
85 » }
86 » for i := 0; i < 5; i++ {
87 » » runtime.GC()
88 » » time.Sleep(time.Millisecond)
89 » » // 1 pointer can remain on stack or elsewhere
90 » » if atomic.LoadUint32(&fin) >= N-1 {
91 » » » return
92 » » }
93 » }
94 » t.Fatalf("only %v out of %v resources are finalized",
95 » » atomic.LoadUint32(&fin), N)
96 }
97
98 func TestPoolStress(t *testing.T) {
99 » const P = 10
100 » N := int(1e6)
101 » if testing.Short() {
102 » » N /= 100
103 » }
104 » var p Pool
105 » done := make(chan bool)
106 » for i := 0; i < P; i++ {
107 » » go func() {
108 » » » var v interface{} = 0
109 » » » for j := 0; j < N; j++ {
110 » » » » if v == nil {
111 » » » » » v = 0
112 » » » » }
113 » » » » p.Put(v)
114 » » » » v = p.Get()
115 » » » » if v != nil && v.(int) != 0 {
116 » » » » » t.Fatalf("expect 0, got %v", v)
117 » » » » }
118 » » » }
119 » » » done <- true
120 » » }()
121 » }
122 » for i := 0; i < P; i++ {
123 » » <-done
124 » }
125 }
126
127 func BenchmarkPool(b *testing.B) {
128 » procs := runtime.GOMAXPROCS(-1)
129 » var dec func() bool
130 » if unsafe.Sizeof(b.N) == 8 {
131 » » n := int64(b.N)
132 » » dec = func() bool {
133 » » » return atomic.AddInt64(&n, -1) >= 0
134 » » }
135 » } else {
136 » » n := int32(b.N)
137 » » dec = func() bool {
138 » » » return atomic.AddInt32(&n, -1) >= 0
139 » » }
140 » }
58 var p Pool 141 var p Pool
59 var wg WaitGroup 142 var wg WaitGroup
60 » for i := 0; i < 2; i++ { 143 » for i := 0; i < procs; i++ {
61 wg.Add(1) 144 wg.Add(1)
62 go func() { 145 go func() {
63 defer wg.Done() 146 defer wg.Done()
64 » » » for i := 0; i < b.N; i += 2 { 147 » » » for dec() {
65 p.Put(1) 148 p.Put(1)
66 p.Get() 149 p.Get()
67 } 150 }
68 }() 151 }()
69 } 152 }
70 wg.Wait() 153 wg.Wait()
71 } 154 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b