summaryrefslogtreecommitdiff
path: root/src/pkg/sync/atomic/atomic_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/sync/atomic/atomic_test.go')
-rw-r--r--src/pkg/sync/atomic/atomic_test.go539
1 files changed, 0 insertions, 539 deletions
diff --git a/src/pkg/sync/atomic/atomic_test.go b/src/pkg/sync/atomic/atomic_test.go
deleted file mode 100644
index 119ad0036..000000000
--- a/src/pkg/sync/atomic/atomic_test.go
+++ /dev/null
@@ -1,539 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package atomic_test
-
-import (
- "runtime"
- . "sync/atomic"
- "testing"
- "unsafe"
-)
-
-// Tests of correct behavior, without contention.
-// (Does the function work as advertised?)
-//
-// Test that the Add functions add correctly.
-// Test that the CompareAndSwap functions actually
-// do the comparison and the swap correctly.
-//
-// The loop over power-of-two values is meant to
-// ensure that the operations apply to the full word size.
-// The struct fields x.before and x.after check that the
-// operations do not extend past the full word size.
-
-const (
- magic32 = 0xdedbeef
- magic64 = 0xdeddeadbeefbeef
-)
-
-// Do the 64-bit functions panic? If so, don't bother testing.
-var test64err = func() (err interface{}) {
- defer func() {
- err = recover()
- }()
- var x int64
- AddInt64(&x, 1)
- return nil
-}()
-
-func TestAddInt32(t *testing.T) {
- var x struct {
- before int32
- i int32
- after int32
- }
- x.before = magic32
- x.after = magic32
- var j int32
- for delta := int32(1); delta+delta > delta; delta += delta {
- k := AddInt32(&x.i, delta)
- j += delta
- if x.i != j || k != j {
- t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
- }
- }
- if x.before != magic32 || x.after != magic32 {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
- }
-}
-
-func TestAddUint32(t *testing.T) {
- var x struct {
- before uint32
- i uint32
- after uint32
- }
- x.before = magic32
- x.after = magic32
- var j uint32
- for delta := uint32(1); delta+delta > delta; delta += delta {
- k := AddUint32(&x.i, delta)
- j += delta
- if x.i != j || k != j {
- t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
- }
- }
- if x.before != magic32 || x.after != magic32 {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
- }
-}
-
-func TestAddInt64(t *testing.T) {
- if test64err != nil {
- t.Logf("Skipping 64-bit tests: %v", test64err)
- return
- }
- var x struct {
- before int64
- i int64
- after int64
- }
- x.before = magic64
- x.after = magic64
- var j int64
- for delta := int64(1); delta+delta > delta; delta += delta {
- k := AddInt64(&x.i, delta)
- j += delta
- if x.i != j || k != j {
- t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
- }
- }
- if x.before != magic64 || x.after != magic64 {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, int64(magic64), int64(magic64))
- }
-}
-
-func TestAddUint64(t *testing.T) {
- if test64err != nil {
- t.Logf("Skipping 64-bit tests: %v", test64err)
- return
- }
- var x struct {
- before uint64
- i uint64
- after uint64
- }
- x.before = magic64
- x.after = magic64
- var j uint64
- for delta := uint64(1); delta+delta > delta; delta += delta {
- k := AddUint64(&x.i, delta)
- j += delta
- if x.i != j || k != j {
- t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
- }
- }
- if x.before != magic64 || x.after != magic64 {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
- }
-}
-
-func TestAddUintptr(t *testing.T) {
- var x struct {
- before uintptr
- i uintptr
- after uintptr
- }
- var m uint64 = magic64
- magicptr := uintptr(m)
- x.before = magicptr
- x.after = magicptr
- var j uintptr
- for delta := uintptr(1); delta+delta > delta; delta += delta {
- k := AddUintptr(&x.i, delta)
- j += delta
- if x.i != j || k != j {
- t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
- }
- }
- if x.before != magicptr || x.after != magicptr {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
- }
-}
-
-func TestCompareAndSwapInt32(t *testing.T) {
- var x struct {
- before int32
- i int32
- after int32
- }
- x.before = magic32
- x.after = magic32
- for val := int32(1); val+val > val; val += val {
- x.i = val
- if !CompareAndSwapInt32(&x.i, val, val+1) {
- t.Errorf("should have swapped %#x %#x", val, val+1)
- }
- if x.i != val+1 {
- t.Errorf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
- }
- x.i = val + 1
- if CompareAndSwapInt32(&x.i, val, val+2) {
- t.Errorf("should not have swapped %#x %#x", val, val+2)
- }
- if x.i != val+1 {
- t.Errorf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
- }
- }
- if x.before != magic32 || x.after != magic32 {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
- }
-}
-
-func TestCompareAndSwapUint32(t *testing.T) {
- var x struct {
- before uint32
- i uint32
- after uint32
- }
- x.before = magic32
- x.after = magic32
- for val := uint32(1); val+val > val; val += val {
- x.i = val
- if !CompareAndSwapUint32(&x.i, val, val+1) {
- t.Errorf("should have swapped %#x %#x", val, val+1)
- }
- if x.i != val+1 {
- t.Errorf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
- }
- x.i = val + 1
- if CompareAndSwapUint32(&x.i, val, val+2) {
- t.Errorf("should not have swapped %#x %#x", val, val+2)
- }
- if x.i != val+1 {
- t.Errorf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
- }
- }
- if x.before != magic32 || x.after != magic32 {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
- }
-}
-
-func TestCompareAndSwapInt64(t *testing.T) {
- if test64err != nil {
- t.Logf("Skipping 64-bit tests: %v", test64err)
- return
- }
- var x struct {
- before int64
- i int64
- after int64
- }
- x.before = magic64
- x.after = magic64
- for val := int64(1); val+val > val; val += val {
- x.i = val
- if !CompareAndSwapInt64(&x.i, val, val+1) {
- t.Errorf("should have swapped %#x %#x", val, val+1)
- }
- if x.i != val+1 {
- t.Errorf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
- }
- x.i = val + 1
- if CompareAndSwapInt64(&x.i, val, val+2) {
- t.Errorf("should not have swapped %#x %#x", val, val+2)
- }
- if x.i != val+1 {
- t.Errorf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
- }
- }
- if x.before != magic64 || x.after != magic64 {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
- }
-}
-
-func TestCompareAndSwapUint64(t *testing.T) {
- if test64err != nil {
- t.Logf("Skipping 64-bit tests: %v", test64err)
- return
- }
- var x struct {
- before uint64
- i uint64
- after uint64
- }
- x.before = magic64
- x.after = magic64
- for val := uint64(1); val+val > val; val += val {
- x.i = val
- if !CompareAndSwapUint64(&x.i, val, val+1) {
- t.Errorf("should have swapped %#x %#x", val, val+1)
- }
- if x.i != val+1 {
- t.Errorf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
- }
- x.i = val + 1
- if CompareAndSwapUint64(&x.i, val, val+2) {
- t.Errorf("should not have swapped %#x %#x", val, val+2)
- }
- if x.i != val+1 {
- t.Errorf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
- }
- }
- if x.before != magic64 || x.after != magic64 {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
- }
-}
-
-func TestCompareAndSwapUintptr(t *testing.T) {
- var x struct {
- before uintptr
- i uintptr
- after uintptr
- }
- var m uint64 = magic64
- magicptr := uintptr(m)
- x.before = magicptr
- x.after = magicptr
- for val := uintptr(1); val+val > val; val += val {
- x.i = val
- if !CompareAndSwapUintptr(&x.i, val, val+1) {
- t.Errorf("should have swapped %#x %#x", val, val+1)
- }
- if x.i != val+1 {
- t.Errorf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
- }
- x.i = val + 1
- if CompareAndSwapUintptr(&x.i, val, val+2) {
- t.Errorf("should not have swapped %#x %#x", val, val+2)
- }
- if x.i != val+1 {
- t.Errorf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
- }
- }
- if x.before != magicptr || x.after != magicptr {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
- }
-}
-
-// Tests of correct behavior, with contention.
-// (Is the function atomic?)
-//
-// For each function, we write a "hammer" function that repeatedly
-// uses the atomic operation to add 1 to a value. After running
-// multiple hammers in parallel, check that we end with the correct
-// total.
-
-var hammer32 = []struct {
- name string
- f func(*uint32, int)
-}{
- {"AddInt32", hammerAddInt32},
- {"AddUint32", hammerAddUint32},
- {"AddUintptr", hammerAddUintptr32},
- {"CompareAndSwapInt32", hammerCompareAndSwapInt32},
- {"CompareAndSwapUint32", hammerCompareAndSwapUint32},
- {"CompareAndSwapUintptr", hammerCompareAndSwapUintptr32},
-}
-
-func init() {
- var v uint64 = 1 << 50
- if uintptr(v) != 0 {
- // 64-bit system; clear uintptr tests
- hammer32[2].f = nil
- hammer32[5].f = nil
- }
-}
-
-func hammerAddInt32(uval *uint32, count int) {
- val := (*int32)(unsafe.Pointer(uval))
- for i := 0; i < count; i++ {
- AddInt32(val, 1)
- }
-}
-
-func hammerAddUint32(val *uint32, count int) {
- for i := 0; i < count; i++ {
- AddUint32(val, 1)
- }
-}
-
-func hammerAddUintptr32(uval *uint32, count int) {
- // only safe when uintptr is 32-bit.
- // not called on 64-bit systems.
- val := (*uintptr)(unsafe.Pointer(uval))
- for i := 0; i < count; i++ {
- AddUintptr(val, 1)
- }
-}
-
-func hammerCompareAndSwapInt32(uval *uint32, count int) {
- val := (*int32)(unsafe.Pointer(uval))
- for i := 0; i < count; i++ {
- for {
- v := *val
- if CompareAndSwapInt32(val, v, v+1) {
- break
- }
- }
- }
-}
-
-func hammerCompareAndSwapUint32(val *uint32, count int) {
- for i := 0; i < count; i++ {
- for {
- v := *val
- if CompareAndSwapUint32(val, v, v+1) {
- break
- }
- }
- }
-}
-
-func hammerCompareAndSwapUintptr32(uval *uint32, count int) {
- // only safe when uintptr is 32-bit.
- // not called on 64-bit systems.
- val := (*uintptr)(unsafe.Pointer(uval))
- for i := 0; i < count; i++ {
- for {
- v := *val
- if CompareAndSwapUintptr(val, v, v+1) {
- break
- }
- }
- }
-}
-
-func TestHammer32(t *testing.T) {
- const p = 4
- n := 100000
- if testing.Short() {
- n = 1000
- }
- defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(p))
-
- for _, tt := range hammer32 {
- if tt.f == nil {
- continue
- }
- c := make(chan int)
- var val uint32
- for i := 0; i < p; i++ {
- go func() {
- tt.f(&val, n)
- c <- 1
- }()
- }
- for i := 0; i < p; i++ {
- <-c
- }
- if val != uint32(n)*p {
- t.Errorf("%s: val=%d want %d", tt.name, val, n*p)
- }
- }
-}
-
-var hammer64 = []struct {
- name string
- f func(*uint64, int)
-}{
- {"AddInt64", hammerAddInt64},
- {"AddUint64", hammerAddUint64},
- {"AddUintptr", hammerAddUintptr64},
- {"CompareAndSwapInt64", hammerCompareAndSwapInt64},
- {"CompareAndSwapUint64", hammerCompareAndSwapUint64},
- {"CompareAndSwapUintptr", hammerCompareAndSwapUintptr64},
-}
-
-func init() {
- var v uint64 = 1 << 50
- if uintptr(v) == 0 {
- // 32-bit system; clear uintptr tests
- hammer64[2].f = nil
- hammer64[5].f = nil
- }
-}
-
-func hammerAddInt64(uval *uint64, count int) {
- val := (*int64)(unsafe.Pointer(uval))
- for i := 0; i < count; i++ {
- AddInt64(val, 1)
- }
-}
-
-func hammerAddUint64(val *uint64, count int) {
- for i := 0; i < count; i++ {
- AddUint64(val, 1)
- }
-}
-
-func hammerAddUintptr64(uval *uint64, count int) {
- // only safe when uintptr is 64-bit.
- // not called on 32-bit systems.
- val := (*uintptr)(unsafe.Pointer(uval))
- for i := 0; i < count; i++ {
- AddUintptr(val, 1)
- }
-}
-
-func hammerCompareAndSwapInt64(uval *uint64, count int) {
- val := (*int64)(unsafe.Pointer(uval))
- for i := 0; i < count; i++ {
- for {
- v := *val
- if CompareAndSwapInt64(val, v, v+1) {
- break
- }
- }
- }
-}
-
-func hammerCompareAndSwapUint64(val *uint64, count int) {
- for i := 0; i < count; i++ {
- for {
- v := *val
- if CompareAndSwapUint64(val, v, v+1) {
- break
- }
- }
- }
-}
-
-func hammerCompareAndSwapUintptr64(uval *uint64, count int) {
- // only safe when uintptr is 64-bit.
- // not called on 32-bit systems.
- val := (*uintptr)(unsafe.Pointer(uval))
- for i := 0; i < count; i++ {
- for {
- v := *val
- if CompareAndSwapUintptr(val, v, v+1) {
- break
- }
- }
- }
-}
-
-func TestHammer64(t *testing.T) {
- if test64err != nil {
- t.Logf("Skipping 64-bit tests: %v", test64err)
- return
- }
- const p = 4
- n := 100000
- if testing.Short() {
- n = 1000
- }
- defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(p))
-
- for _, tt := range hammer64 {
- if tt.f == nil {
- continue
- }
- c := make(chan int)
- var val uint64
- for i := 0; i < p; i++ {
- go func() {
- tt.f(&val, n)
- c <- 1
- }()
- }
- for i := 0; i < p; i++ {
- <-c
- }
- if val != uint64(n)*p {
- t.Errorf("%s: val=%d want %d", tt.name, val, n*p)
- }
- }
-}