1
2
3
4
5
6
7 package atomic_test
8
9 import (
10 "internal/runtime/atomic"
11 "testing"
12 )
13
14 func TestAnd32(t *testing.T) {
15
16 x := uint32(0xffffffff)
17 for i := uint32(0); i < 32; i++ {
18 old := x
19 v := atomic.And32(&x, ^(1 << i))
20 if r := uint32(0xffffffff) << (i + 1); x != r || v != old {
21 t.Fatalf("clearing bit %#x: want %#x, got new %#x and old %#v", uint32(1<<i), r, x, v)
22 }
23 }
24
25
26 a := make([]uint32, 1<<12)
27 for i := range a {
28 a[i] = 0xffffffff
29 }
30
31
32 done := make(chan bool)
33 for i := 0; i < 32; i++ {
34 m := ^uint32(1 << i)
35 go func() {
36 for i := range a {
37 atomic.And(&a[i], m)
38 }
39 done <- true
40 }()
41 }
42 for i := 0; i < 32; i++ {
43 <-done
44 }
45
46
47 for i, v := range a {
48 if v != 0 {
49 t.Fatalf("a[%v] not cleared: want %#x, got %#x", i, uint32(0), v)
50 }
51 }
52 }
53
54 func TestAnd64(t *testing.T) {
55
56 x := uint64(0xffffffffffffffff)
57 sink = &x
58 for i := uint64(0); i < 64; i++ {
59 old := x
60 v := atomic.And64(&x, ^(1 << i))
61 if r := uint64(0xffffffffffffffff) << (i + 1); x != r || v != old {
62 t.Fatalf("clearing bit %#x: want %#x, got new %#x and old %#v", uint64(1<<i), r, x, v)
63 }
64 }
65
66
67 a := make([]uint64, 1<<12)
68 for i := range a {
69 a[i] = 0xffffffffffffffff
70 }
71
72
73 done := make(chan bool)
74 for i := 0; i < 64; i++ {
75 m := ^uint64(1 << i)
76 go func() {
77 for i := range a {
78 atomic.And64(&a[i], m)
79 }
80 done <- true
81 }()
82 }
83 for i := 0; i < 64; i++ {
84 <-done
85 }
86
87
88 for i, v := range a {
89 if v != 0 {
90 t.Fatalf("a[%v] not cleared: want %#x, got %#x", i, uint64(0), v)
91 }
92 }
93 }
94
95 func TestOr32(t *testing.T) {
96
97 x := uint32(0)
98 for i := uint32(0); i < 32; i++ {
99 old := x
100 v := atomic.Or32(&x, 1<<i)
101 if r := (uint32(1) << (i + 1)) - 1; x != r || v != old {
102 t.Fatalf("setting bit %#x: want %#x, got new %#x and old %#v", uint32(1<<i), r, x, v)
103 }
104 }
105
106
107 a := make([]uint32, 1<<12)
108
109
110 done := make(chan bool)
111 for i := 0; i < 32; i++ {
112 m := uint32(1 << i)
113 go func() {
114 for i := range a {
115 atomic.Or32(&a[i], m)
116 }
117 done <- true
118 }()
119 }
120 for i := 0; i < 32; i++ {
121 <-done
122 }
123
124
125 for i, v := range a {
126 if v != 0xffffffff {
127 t.Fatalf("a[%v] not fully set: want %#x, got %#x", i, uint32(0xffffffff), v)
128 }
129 }
130 }
131
132 func TestOr64(t *testing.T) {
133
134 x := uint64(0)
135 sink = &x
136 for i := uint64(0); i < 64; i++ {
137 old := x
138 v := atomic.Or64(&x, 1<<i)
139 if r := (uint64(1) << (i + 1)) - 1; x != r || v != old {
140 t.Fatalf("setting bit %#x: want %#x, got new %#x and old %#v", uint64(1<<i), r, x, v)
141 }
142 }
143
144
145 a := make([]uint64, 1<<12)
146
147
148 done := make(chan bool)
149 for i := 0; i < 64; i++ {
150 m := uint64(1 << i)
151 go func() {
152 for i := range a {
153 atomic.Or64(&a[i], m)
154 }
155 done <- true
156 }()
157 }
158 for i := 0; i < 64; i++ {
159 <-done
160 }
161
162
163 for i, v := range a {
164 if v != 0xffffffffffffffff {
165 t.Fatalf("a[%v] not fully set: want %#x, got %#x", i, uint64(0xffffffffffffffff), v)
166 }
167 }
168 }
169
170 func BenchmarkAnd32(b *testing.B) {
171 var x [128]uint32
172 sink = &x
173 for i := 0; i < b.N; i++ {
174 atomic.And32(&x[63], uint32(i))
175 }
176 }
177
178 func BenchmarkAnd32Parallel(b *testing.B) {
179 var x [128]uint32
180 sink = &x
181 b.RunParallel(func(pb *testing.PB) {
182 i := uint32(0)
183 for pb.Next() {
184 atomic.And32(&x[63], i)
185 i++
186 }
187 })
188 }
189
190 func BenchmarkAnd64(b *testing.B) {
191 var x [128]uint64
192 sink = &x
193 for i := 0; i < b.N; i++ {
194 atomic.And64(&x[63], uint64(i))
195 }
196 }
197
198 func BenchmarkAnd64Parallel(b *testing.B) {
199 var x [128]uint64
200 sink = &x
201 b.RunParallel(func(pb *testing.PB) {
202 i := uint64(0)
203 for pb.Next() {
204 atomic.And64(&x[63], i)
205 i++
206 }
207 })
208 }
209
210 func BenchmarkOr32(b *testing.B) {
211 var x [128]uint32
212 sink = &x
213 for i := 0; i < b.N; i++ {
214 atomic.Or32(&x[63], uint32(i))
215 }
216 }
217
218 func BenchmarkOr32Parallel(b *testing.B) {
219 var x [128]uint32
220 sink = &x
221 b.RunParallel(func(pb *testing.PB) {
222 i := uint32(0)
223 for pb.Next() {
224 atomic.Or32(&x[63], i)
225 i++
226 }
227 })
228 }
229
230 func BenchmarkOr64(b *testing.B) {
231 var x [128]uint64
232 sink = &x
233 for i := 0; i < b.N; i++ {
234 atomic.Or64(&x[63], uint64(i))
235 }
236 }
237
238 func BenchmarkOr64Parallel(b *testing.B) {
239 var x [128]uint64
240 sink = &x
241 b.RunParallel(func(pb *testing.PB) {
242 i := uint64(0)
243 for pb.Next() {
244 atomic.Or64(&x[63], i)
245 i++
246 }
247 })
248 }
249
View as plain text