diff options
author | Russ Cox <rsc@golang.org> | 2014-09-08 00:08:51 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2014-09-08 00:08:51 -0400 |
commit | 8528da672cc093d4dd06732819abc1f7b6b5a46e (patch) | |
tree | 334be80d4a4c85b77db6f6fdb67cbf0528cba5f5 /src/pkg/sync/atomic | |
parent | 73bcb69f272cbf34ddcc9daa56427a8683b5a95d (diff) | |
download | go-8528da672cc093d4dd06732819abc1f7b6b5a46e.tar.gz |
build: move package sources from src/pkg to src
Preparation was in CL 134570043.
This CL contains only the effect of 'hg mv src/pkg/* src'.
For more about the move, see golang.org/s/go14nopkg.
Diffstat (limited to 'src/pkg/sync/atomic')
-rw-r--r-- | src/pkg/sync/atomic/64bit_arm.go | 46 | ||||
-rw-r--r-- | src/pkg/sync/atomic/asm_386.s | 214 | ||||
-rw-r--r-- | src/pkg/sync/atomic/asm_amd64.s | 146 | ||||
-rw-r--r-- | src/pkg/sync/atomic/asm_amd64p32.s | 159 | ||||
-rw-r--r-- | src/pkg/sync/atomic/asm_arm.s | 197 | ||||
-rw-r--r-- | src/pkg/sync/atomic/asm_freebsd_arm.s | 109 | ||||
-rw-r--r-- | src/pkg/sync/atomic/asm_linux_arm.s | 216 | ||||
-rw-r--r-- | src/pkg/sync/atomic/asm_nacl_arm.s | 109 | ||||
-rw-r--r-- | src/pkg/sync/atomic/asm_netbsd_arm.s | 109 | ||||
-rw-r--r-- | src/pkg/sync/atomic/atomic_linux_arm_test.go | 14 | ||||
-rw-r--r-- | src/pkg/sync/atomic/atomic_test.go | 1509 | ||||
-rw-r--r-- | src/pkg/sync/atomic/doc.go | 149 | ||||
-rw-r--r-- | src/pkg/sync/atomic/export_linux_arm_test.go | 9 | ||||
-rw-r--r-- | src/pkg/sync/atomic/race.s | 8 |
14 files changed, 0 insertions, 2994 deletions
diff --git a/src/pkg/sync/atomic/64bit_arm.go b/src/pkg/sync/atomic/64bit_arm.go deleted file mode 100644 index c08f214c7..000000000 --- a/src/pkg/sync/atomic/64bit_arm.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2012 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 - -func loadUint64(addr *uint64) (val uint64) { - for { - val = *addr - if CompareAndSwapUint64(addr, val, val) { - break - } - } - return -} - -func storeUint64(addr *uint64, val uint64) { - for { - old := *addr - if CompareAndSwapUint64(addr, old, val) { - break - } - } - return -} - -func addUint64(val *uint64, delta uint64) (new uint64) { - for { - old := *val - new = old + delta - if CompareAndSwapUint64(val, old, new) { - break - } - } - return -} - -func swapUint64(addr *uint64, new uint64) (old uint64) { - for { - old = *addr - if CompareAndSwapUint64(addr, old, new) { - break - } - } - return -} diff --git a/src/pkg/sync/atomic/asm_386.s b/src/pkg/sync/atomic/asm_386.s deleted file mode 100644 index 740dfe76b..000000000 --- a/src/pkg/sync/atomic/asm_386.s +++ /dev/null @@ -1,214 +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. - -// +build !race - -#include "textflag.h" - -TEXT ·SwapInt32(SB),NOSPLIT,$0-12 - JMP ·SwapUint32(SB) - -TEXT ·SwapUint32(SB),NOSPLIT,$0-12 - MOVL addr+0(FP), BP - MOVL new+4(FP), AX - XCHGL AX, 0(BP) - MOVL AX, old+8(FP) - RET - -TEXT ·SwapInt64(SB),NOSPLIT,$0-20 - JMP ·SwapUint64(SB) - -TEXT ·SwapUint64(SB),NOSPLIT,$0-20 - // no XCHGQ so use CMPXCHG8B loop - MOVL addr+0(FP), BP - TESTL $7, BP - JZ 2(PC) - MOVL 0, AX // crash with nil ptr deref - // CX:BX = new - MOVL new_lo+4(FP), BX - MOVL new_hi+8(FP), CX - // DX:AX = *addr - MOVL 0(BP), AX - MOVL 4(BP), DX -swaploop: - // if *addr == DX:AX - // *addr = CX:BX - // else - // DX:AX = *addr - // all in one instruction - LOCK - CMPXCHG8B 0(BP) - JNZ swaploop - - // success - // return DX:AX - MOVL AX, old_lo+12(FP) - MOVL DX, old_hi+16(FP) - RET - -TEXT ·SwapUintptr(SB),NOSPLIT,$0-12 - JMP ·SwapUint32(SB) - -TEXT ·SwapPointer(SB),NOSPLIT,$0-12 - JMP ·SwapUint32(SB) - -TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-13 - JMP ·CompareAndSwapUint32(SB) - -TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-13 - MOVL addr+0(FP), BP - MOVL old+4(FP), AX - MOVL new+8(FP), CX - // CMPXCHGL was introduced on the 486. - LOCK - CMPXCHGL CX, 0(BP) - SETEQ swapped+12(FP) - RET - -TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-13 - JMP ·CompareAndSwapUint32(SB) - -TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0-13 - JMP ·CompareAndSwapUint32(SB) - -TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-21 - JMP ·CompareAndSwapUint64(SB) - -TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$0-21 - MOVL addr+0(FP), BP - TESTL $7, BP - JZ 2(PC) - MOVL 0, AX // crash with nil ptr deref - MOVL old_lo+4(FP), AX - MOVL old_hi+8(FP), DX - MOVL new_lo+12(FP), BX - MOVL new_hi+16(FP), CX - // CMPXCHG8B was introduced on the Pentium. - LOCK - CMPXCHG8B 0(BP) - SETEQ swapped+20(FP) - RET - -TEXT ·AddInt32(SB),NOSPLIT,$0-12 - JMP ·AddUint32(SB) - -TEXT ·AddUint32(SB),NOSPLIT,$0-12 - MOVL addr+0(FP), BP - MOVL delta+4(FP), AX - MOVL AX, CX - // XADD was introduced on the 486. - LOCK - XADDL AX, 0(BP) - ADDL AX, CX - MOVL CX, new+8(FP) - RET - -TEXT ·AddUintptr(SB),NOSPLIT,$0-12 - JMP ·AddUint32(SB) - -TEXT ·AddInt64(SB),NOSPLIT,$0-20 - JMP ·AddUint64(SB) - -TEXT ·AddUint64(SB),NOSPLIT,$0-20 - // no XADDQ so use CMPXCHG8B loop - MOVL addr+0(FP), BP - TESTL $7, BP - JZ 2(PC) - MOVL 0, AX // crash with nil ptr deref - // DI:SI = delta - MOVL delta_lo+4(FP), SI - MOVL delta_hi+8(FP), DI - // DX:AX = *addr - MOVL 0(BP), AX - MOVL 4(BP), DX -addloop: - // CX:BX = DX:AX (*addr) + DI:SI (delta) - MOVL AX, BX - MOVL DX, CX - ADDL SI, BX - ADCL DI, CX - - // if *addr == DX:AX { - // *addr = CX:BX - // } else { - // DX:AX = *addr - // } - // all in one instruction - LOCK - CMPXCHG8B 0(BP) - - JNZ addloop - - // success - // return CX:BX - MOVL BX, new_lo+12(FP) - MOVL CX, new_hi+16(FP) - RET - -TEXT ·LoadInt32(SB),NOSPLIT,$0-8 - JMP ·LoadUint32(SB) - -TEXT ·LoadUint32(SB),NOSPLIT,$0-8 - MOVL addr+0(FP), AX - MOVL 0(AX), AX - MOVL AX, val+4(FP) - RET - -TEXT ·LoadInt64(SB),NOSPLIT,$0-12 - JMP ·LoadUint64(SB) - -TEXT ·LoadUint64(SB),NOSPLIT,$0-12 - MOVL addr+0(FP), AX - TESTL $7, AX - JZ 2(PC) - MOVL 0, AX // crash with nil ptr deref - // MOVQ and EMMS were introduced on the Pentium MMX. - // MOVQ (%EAX), %MM0 - BYTE $0x0f; BYTE $0x6f; BYTE $0x00 - // MOVQ %MM0, 0x8(%ESP) - BYTE $0x0f; BYTE $0x7f; BYTE $0x44; BYTE $0x24; BYTE $0x08 - EMMS - RET - -TEXT ·LoadUintptr(SB),NOSPLIT,$0-8 - JMP ·LoadUint32(SB) - -TEXT ·LoadPointer(SB),NOSPLIT,$0-8 - JMP ·LoadUint32(SB) - -TEXT ·StoreInt32(SB),NOSPLIT,$0-8 - JMP ·StoreUint32(SB) - -TEXT ·StoreUint32(SB),NOSPLIT,$0-8 - MOVL addr+0(FP), BP - MOVL val+4(FP), AX - XCHGL AX, 0(BP) - RET - -TEXT ·StoreInt64(SB),NOSPLIT,$0-12 - JMP ·StoreUint64(SB) - -TEXT ·StoreUint64(SB),NOSPLIT,$0-12 - MOVL addr+0(FP), AX - TESTL $7, AX - JZ 2(PC) - MOVL 0, AX // crash with nil ptr deref - // MOVQ and EMMS were introduced on the Pentium MMX. - // MOVQ 0x8(%ESP), %MM0 - BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08 - // MOVQ %MM0, (%EAX) - BYTE $0x0f; BYTE $0x7f; BYTE $0x00 - EMMS - // This is essentially a no-op, but it provides required memory fencing. - // It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2). - XORL AX, AX - LOCK - XADDL AX, (SP) - RET - -TEXT ·StoreUintptr(SB),NOSPLIT,$0-8 - JMP ·StoreUint32(SB) - -TEXT ·StorePointer(SB),NOSPLIT,$0-8 - JMP ·StoreUint32(SB) diff --git a/src/pkg/sync/atomic/asm_amd64.s b/src/pkg/sync/atomic/asm_amd64.s deleted file mode 100644 index 6e53ebedd..000000000 --- a/src/pkg/sync/atomic/asm_amd64.s +++ /dev/null @@ -1,146 +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. - -// +build !race - -#include "textflag.h" - -TEXT ·SwapInt32(SB),NOSPLIT,$0-20 - JMP ·SwapUint32(SB) - -TEXT ·SwapUint32(SB),NOSPLIT,$0-20 - MOVQ addr+0(FP), BP - MOVL new+8(FP), AX - XCHGL AX, 0(BP) - MOVL AX, old+16(FP) - RET - -TEXT ·SwapInt64(SB),NOSPLIT,$0-24 - JMP ·SwapUint64(SB) - -TEXT ·SwapUint64(SB),NOSPLIT,$0-24 - MOVQ addr+0(FP), BP - MOVQ new+8(FP), AX - XCHGQ AX, 0(BP) - MOVQ AX, old+16(FP) - RET - -TEXT ·SwapUintptr(SB),NOSPLIT,$0-24 - JMP ·SwapUint64(SB) - -TEXT ·SwapPointer(SB),NOSPLIT,$0-24 - JMP ·SwapUint64(SB) - -TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-17 - JMP ·CompareAndSwapUint32(SB) - -TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-17 - MOVQ addr+0(FP), BP - MOVL old+8(FP), AX - MOVL new+12(FP), CX - LOCK - CMPXCHGL CX, 0(BP) - SETEQ swapped+16(FP) - RET - -TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-25 - JMP ·CompareAndSwapUint64(SB) - -TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0-25 - JMP ·CompareAndSwapUint64(SB) - -TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-25 - JMP ·CompareAndSwapUint64(SB) - -TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$0-25 - MOVQ addr+0(FP), BP - MOVQ old+8(FP), AX - MOVQ new+16(FP), CX - LOCK - CMPXCHGQ CX, 0(BP) - SETEQ swapped+24(FP) - RET - -TEXT ·AddInt32(SB),NOSPLIT,$0-20 - JMP ·AddUint32(SB) - -TEXT ·AddUint32(SB),NOSPLIT,$0-20 - MOVQ addr+0(FP), BP - MOVL delta+8(FP), AX - MOVL AX, CX - LOCK - XADDL AX, 0(BP) - ADDL AX, CX - MOVL CX, new+16(FP) - RET - -TEXT ·AddUintptr(SB),NOSPLIT,$0-24 - JMP ·AddUint64(SB) - -TEXT ·AddInt64(SB),NOSPLIT,$0-24 - JMP ·AddUint64(SB) - -TEXT ·AddUint64(SB),NOSPLIT,$0-24 - MOVQ addr+0(FP), BP - MOVQ delta+8(FP), AX - MOVQ AX, CX - LOCK - XADDQ AX, 0(BP) - ADDQ AX, CX - MOVQ CX, new+16(FP) - RET - -TEXT ·LoadInt32(SB),NOSPLIT,$0-12 - JMP ·LoadUint32(SB) - -TEXT ·LoadUint32(SB),NOSPLIT,$0-12 - MOVQ addr+0(FP), AX - MOVL 0(AX), AX - MOVL AX, val+8(FP) - RET - -TEXT ·LoadInt64(SB),NOSPLIT,$0-16 - JMP ·LoadUint64(SB) - -TEXT ·LoadUint64(SB),NOSPLIT,$0-16 - MOVQ addr+0(FP), AX - MOVQ 0(AX), AX - MOVQ AX, val+8(FP) - RET - -TEXT ·LoadUintptr(SB),NOSPLIT,$0-16 - JMP ·LoadPointer(SB) - -TEXT ·LoadPointer(SB),NOSPLIT,$0-16 - MOVQ addr+0(FP), AX - MOVQ 0(AX), AX - MOVQ AX, val+8(FP) - RET - -TEXT ·StoreInt32(SB),NOSPLIT,$0-12 - JMP ·StoreUint32(SB) - -TEXT ·StoreUint32(SB),NOSPLIT,$0-12 - MOVQ addr+0(FP), BP - MOVL val+8(FP), AX - XCHGL AX, 0(BP) - RET - -TEXT ·StoreInt64(SB),NOSPLIT,$0-16 - JMP ·StoreUint64(SB) - -TEXT ·StoreUint64(SB),NOSPLIT,$0-16 - MOVQ addr+0(FP), BP - MOVQ val+8(FP), AX - XCHGQ AX, 0(BP) - RET - -TEXT ·StoreUintptr(SB),NOSPLIT,$0-16 - JMP ·StorePointer(SB) - -TEXT ·StorePointer(SB),NOSPLIT,$0-16 - MOVQ addr+0(FP), BP - MOVQ val+8(FP), AX - XCHGQ AX, 0(BP) - RET diff --git a/src/pkg/sync/atomic/asm_amd64p32.s b/src/pkg/sync/atomic/asm_amd64p32.s deleted file mode 100644 index d77cc2c08..000000000 --- a/src/pkg/sync/atomic/asm_amd64p32.s +++ /dev/null @@ -1,159 +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. - -#include "textflag.h" - -TEXT ·SwapInt32(SB),NOSPLIT,$0-12 - JMP ·SwapUint32(SB) - -TEXT ·SwapUint32(SB),NOSPLIT,$0-12 - MOVL addr+0(FP), BX - MOVL new+4(FP), AX - XCHGL AX, 0(BX) - MOVL AX, old+8(FP) - RET - -TEXT ·SwapInt64(SB),NOSPLIT,$0-24 - JMP ·SwapUint64(SB) - -TEXT ·SwapUint64(SB),NOSPLIT,$0-24 - MOVL addr+0(FP), BX - TESTL $7, BX - JZ 2(PC) - MOVL 0, BX // crash with nil ptr deref - MOVQ new+8(FP), AX - XCHGQ AX, 0(BX) - MOVQ AX, old+16(FP) - RET - -TEXT ·SwapUintptr(SB),NOSPLIT,$0-12 - JMP ·SwapUint32(SB) - -TEXT ·SwapPointer(SB),NOSPLIT,$0-12 - JMP ·SwapUint32(SB) - -TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-17 - JMP ·CompareAndSwapUint32(SB) - -TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-17 - MOVL addr+0(FP), BX - MOVL old+4(FP), AX - MOVL new+8(FP), CX - LOCK - CMPXCHGL CX, 0(BX) - SETEQ swapped+16(FP) - RET - -TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-17 - JMP ·CompareAndSwapUint32(SB) - -TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0-17 - JMP ·CompareAndSwapUint32(SB) - -TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-25 - JMP ·CompareAndSwapUint64(SB) - -TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$0-25 - MOVL addr+0(FP), BX - TESTL $7, BX - JZ 2(PC) - MOVL 0, BX // crash with nil ptr deref - MOVQ old+8(FP), AX - MOVQ new+16(FP), CX - LOCK - CMPXCHGQ CX, 0(BX) - SETEQ swapped+24(FP) - RET - -TEXT ·AddInt32(SB),NOSPLIT,$0-12 - JMP ·AddUint32(SB) - -TEXT ·AddUint32(SB),NOSPLIT,$0-12 - MOVL addr+0(FP), BX - MOVL delta+4(FP), AX - MOVL AX, CX - LOCK - XADDL AX, 0(BX) - ADDL AX, CX - MOVL CX, new+8(FP) - RET - -TEXT ·AddUintptr(SB),NOSPLIT,$0-12 - JMP ·AddUint32(SB) - -TEXT ·AddInt64(SB),NOSPLIT,$0-24 - JMP ·AddUint64(SB) - -TEXT ·AddUint64(SB),NOSPLIT,$0-24 - MOVL addr+0(FP), BX - TESTL $7, BX - JZ 2(PC) - MOVL 0, BX // crash with nil ptr deref - MOVQ delta+8(FP), AX - MOVQ AX, CX - LOCK - XADDQ AX, 0(BX) - ADDQ AX, CX - MOVQ CX, new+16(FP) - RET - -TEXT ·LoadInt32(SB),NOSPLIT,$0-12 - JMP ·LoadUint32(SB) - -TEXT ·LoadUint32(SB),NOSPLIT,$0-12 - MOVL addr+0(FP), AX - MOVL 0(AX), AX - MOVL AX, val+8(FP) - RET - -TEXT ·LoadInt64(SB),NOSPLIT,$0-16 - JMP ·LoadUint64(SB) - -TEXT ·LoadUint64(SB),NOSPLIT,$0-16 - MOVL addr+0(FP), AX - TESTL $7, AX - JZ 2(PC) - MOVL 0, AX // crash with nil ptr deref - MOVQ 0(AX), AX - MOVQ AX, val+8(FP) - RET - -TEXT ·LoadUintptr(SB),NOSPLIT,$0-12 - JMP ·LoadPointer(SB) - -TEXT ·LoadPointer(SB),NOSPLIT,$0-12 - MOVL addr+0(FP), AX - MOVL 0(AX), AX - MOVL AX, val+8(FP) - RET - -TEXT ·StoreInt32(SB),NOSPLIT,$0-8 - JMP ·StoreUint32(SB) - -TEXT ·StoreUint32(SB),NOSPLIT,$0-8 - MOVL addr+0(FP), BX - MOVL val+4(FP), AX - XCHGL AX, 0(BX) - RET - -TEXT ·StoreInt64(SB),NOSPLIT,$0-16 - JMP ·StoreUint64(SB) - -TEXT ·StoreUint64(SB),NOSPLIT,$0-16 - MOVL addr+0(FP), BX - TESTL $7, BX - JZ 2(PC) - MOVL 0, BX // crash with nil ptr deref - MOVQ val+8(FP), AX - XCHGQ AX, 0(BX) - RET - -TEXT ·StoreUintptr(SB),NOSPLIT,$0-8 - JMP ·StorePointer(SB) - -TEXT ·StorePointer(SB),NOSPLIT,$0-8 - MOVL addr+0(FP), BX - MOVL val+4(FP), AX - XCHGL AX, 0(BX) - RET diff --git a/src/pkg/sync/atomic/asm_arm.s b/src/pkg/sync/atomic/asm_arm.s deleted file mode 100644 index 47639a80e..000000000 --- a/src/pkg/sync/atomic/asm_arm.s +++ /dev/null @@ -1,197 +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. - -// +build !race - -#include "textflag.h" - -// ARM atomic operations, for use by asm_$(GOOS)_arm.s. - -TEXT ·armCompareAndSwapUint32(SB),NOSPLIT,$0-13 - MOVW addr+0(FP), R1 - MOVW old+4(FP), R2 - MOVW new+8(FP), R3 -casloop: - // LDREX and STREX were introduced in ARMv6. - LDREX (R1), R0 - CMP R0, R2 - BNE casfail - STREX R3, (R1), R0 - CMP $0, R0 - BNE casloop - MOVW $1, R0 - MOVBU R0, ret+12(FP) - RET -casfail: - MOVW $0, R0 - MOVBU R0, ret+12(FP) - RET - -TEXT ·armCompareAndSwapUint64(SB),NOSPLIT,$0-21 - BL fastCheck64<>(SB) - MOVW addr+0(FP), R1 - // make unaligned atomic access panic - AND.S $7, R1, R2 - BEQ 2(PC) - MOVW R2, (R2) - MOVW oldlo+4(FP), R2 - MOVW oldhi+8(FP), R3 - MOVW newlo+12(FP), R4 - MOVW newhi+16(FP), R5 -cas64loop: - // LDREXD and STREXD were introduced in ARMv6k. - LDREXD (R1), R6 // loads R6 and R7 - CMP R2, R6 - BNE cas64fail - CMP R3, R7 - BNE cas64fail - STREXD R4, (R1), R0 // stores R4 and R5 - CMP $0, R0 - BNE cas64loop - MOVW $1, R0 - MOVBU R0, ret+20(FP) - RET -cas64fail: - MOVW $0, R0 - MOVBU R0, ret+20(FP) - RET - -TEXT ·armAddUint32(SB),NOSPLIT,$0-12 - MOVW addr+0(FP), R1 - MOVW delta+4(FP), R2 -addloop: - // LDREX and STREX were introduced in ARMv6. - LDREX (R1), R3 - ADD R2, R3 - STREX R3, (R1), R0 - CMP $0, R0 - BNE addloop - MOVW R3, ret+8(FP) - RET - -TEXT ·armAddUint64(SB),NOSPLIT,$0-20 - BL fastCheck64<>(SB) - MOVW addr+0(FP), R1 - // make unaligned atomic access panic - AND.S $7, R1, R2 - BEQ 2(PC) - MOVW R2, (R2) - MOVW deltalo+4(FP), R2 - MOVW deltahi+8(FP), R3 -add64loop: - // LDREXD and STREXD were introduced in ARMv6k. - LDREXD (R1), R4 // loads R4 and R5 - ADD.S R2, R4 - ADC R3, R5 - STREXD R4, (R1), R0 // stores R4 and R5 - CMP $0, R0 - BNE add64loop - MOVW R4, retlo+12(FP) - MOVW R5, rethi+16(FP) - RET - -TEXT ·armSwapUint32(SB),NOSPLIT,$0-12 - MOVW addr+0(FP), R1 - MOVW new+4(FP), R2 -swaploop: - // LDREX and STREX were introduced in ARMv6. - LDREX (R1), R3 - STREX R2, (R1), R0 - CMP $0, R0 - BNE swaploop - MOVW R3, old+8(FP) - RET - -TEXT ·armSwapUint64(SB),NOSPLIT,$0-20 - BL fastCheck64<>(SB) - MOVW addr+0(FP), R1 - // make unaligned atomic access panic - AND.S $7, R1, R2 - BEQ 2(PC) - MOVW R2, (R2) - MOVW newlo+4(FP), R2 - MOVW newhi+8(FP), R3 -swap64loop: - // LDREXD and STREXD were introduced in ARMv6k. - LDREXD (R1), R4 // loads R4 and R5 - STREXD R2, (R1), R0 // stores R2 and R3 - CMP $0, R0 - BNE swap64loop - MOVW R4, oldlo+12(FP) - MOVW R5, oldhi+16(FP) - RET - -TEXT ·armLoadUint64(SB),NOSPLIT,$0-12 - BL fastCheck64<>(SB) - MOVW addr+0(FP), R1 - // make unaligned atomic access panic - AND.S $7, R1, R2 - BEQ 2(PC) - MOVW R2, (R2) -load64loop: - LDREXD (R1), R2 // loads R2 and R3 - STREXD R2, (R1), R0 // stores R2 and R3 - CMP $0, R0 - BNE load64loop - MOVW R2, vallo+4(FP) - MOVW R3, valhi+8(FP) - RET - -TEXT ·armStoreUint64(SB),NOSPLIT,$0-12 - BL fastCheck64<>(SB) - MOVW addr+0(FP), R1 - // make unaligned atomic access panic - AND.S $7, R1, R2 - BEQ 2(PC) - MOVW R2, (R2) - MOVW vallo+4(FP), R2 - MOVW valhi+8(FP), R3 -store64loop: - LDREXD (R1), R4 // loads R4 and R5 - STREXD R2, (R1), R0 // stores R2 and R3 - CMP $0, R0 - BNE store64loop - RET - -// Check for broken 64-bit LDREXD as found in QEMU. -// LDREXD followed by immediate STREXD should succeed. -// If it fails, try a few times just to be sure (maybe our thread got -// rescheduled between the two instructions) and then panic. -// A bug in some copies of QEMU makes STREXD never succeed, -// which will make uses of the 64-bit atomic operations loop forever. -// If things are working, set okLDREXD to avoid future checks. -// https://bugs.launchpad.net/qemu/+bug/670883. -TEXT check64<>(SB),NOSPLIT,$16-0 - MOVW $10, R1 - // 8-aligned stack address scratch space. - MOVW $8(R13), R5 - AND $~7, R5 -loop: - LDREXD (R5), R2 - STREXD R2, (R5), R0 - CMP $0, R0 - BEQ ok - SUB $1, R1 - CMP $0, R1 - BNE loop - // Must be buggy QEMU. - BL ·panic64(SB) -ok: - RET - -// Fast, cached version of check. No frame, just MOVW CMP RET after first time. -TEXT fastCheck64<>(SB),NOSPLIT,$-4 - MOVW ok64<>(SB), R0 - CMP $0, R0 // have we been here before? - RET.NE - B slowCheck64<>(SB) - -TEXT slowCheck64<>(SB),NOSPLIT,$0-0 - BL check64<>(SB) - // Still here, must be okay. - MOVW $1, R0 - MOVW R0, ok64<>(SB) - RET - -GLOBL ok64<>(SB), $4 diff --git a/src/pkg/sync/atomic/asm_freebsd_arm.s b/src/pkg/sync/atomic/asm_freebsd_arm.s deleted file mode 100644 index 06b975e89..000000000 --- a/src/pkg/sync/atomic/asm_freebsd_arm.s +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2012 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. - -#include "textflag.h" - -// FreeBSD/ARM atomic operations. -// TODO(minux): this only supports ARMv6K or higher. - -TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0 - B ·CompareAndSwapUint32(SB) - -TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0 - B ·armCompareAndSwapUint32(SB) - -TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0 - B ·CompareAndSwapUint32(SB) - -TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0 - B ·CompareAndSwapUint32(SB) - -TEXT ·AddInt32(SB),NOSPLIT,$0 - B ·AddUint32(SB) - -TEXT ·AddUint32(SB),NOSPLIT,$0 - B ·armAddUint32(SB) - -TEXT ·AddUintptr(SB),NOSPLIT,$0 - B ·AddUint32(SB) - -TEXT ·SwapInt32(SB),NOSPLIT,$0 - B ·SwapUint32(SB) - -TEXT ·SwapUint32(SB),NOSPLIT,$0 - B ·armSwapUint32(SB) - -TEXT ·SwapUintptr(SB),NOSPLIT,$0 - B ·SwapUint32(SB) - -TEXT ·SwapPointer(SB),NOSPLIT,$0 - B ·SwapUint32(SB) - -TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0 - B ·CompareAndSwapUint64(SB) - -TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$-4 - B ·armCompareAndSwapUint64(SB) - -TEXT ·AddInt64(SB),NOSPLIT,$0 - B ·addUint64(SB) - -TEXT ·AddUint64(SB),NOSPLIT,$0 - B ·addUint64(SB) - -TEXT ·SwapInt64(SB),NOSPLIT,$0 - B ·swapUint64(SB) - -TEXT ·SwapUint64(SB),NOSPLIT,$0 - B ·swapUint64(SB) - -TEXT ·LoadInt32(SB),NOSPLIT,$0 - B ·LoadUint32(SB) - -TEXT ·LoadUint32(SB),NOSPLIT,$0-8 - MOVW addr+0(FP), R1 -load32loop: - LDREX (R1), R2 // loads R2 - STREX R2, (R1), R0 // stores R2 - CMP $0, R0 - BNE load32loop - MOVW R2, val+4(FP) - RET - -TEXT ·LoadInt64(SB),NOSPLIT,$0 - B ·loadUint64(SB) - -TEXT ·LoadUint64(SB),NOSPLIT,$0 - B ·loadUint64(SB) - -TEXT ·LoadUintptr(SB),NOSPLIT,$0 - B ·LoadUint32(SB) - -TEXT ·LoadPointer(SB),NOSPLIT,$0 - B ·LoadUint32(SB) - -TEXT ·StoreInt32(SB),NOSPLIT,$0 - B ·StoreUint32(SB) - -TEXT ·StoreUint32(SB),NOSPLIT,$0-8 - MOVW addr+0(FP), R1 - MOVW val+4(FP), R2 -storeloop: - LDREX (R1), R4 // loads R4 - STREX R2, (R1), R0 // stores R2 - CMP $0, R0 - BNE storeloop - RET - -TEXT ·StoreInt64(SB),NOSPLIT,$0 - B ·storeUint64(SB) - -TEXT ·StoreUint64(SB),NOSPLIT,$0 - B ·storeUint64(SB) - -TEXT ·StoreUintptr(SB),NOSPLIT,$0 - B ·StoreUint32(SB) - -TEXT ·StorePointer(SB),NOSPLIT,$0 - B ·StoreUint32(SB) diff --git a/src/pkg/sync/atomic/asm_linux_arm.s b/src/pkg/sync/atomic/asm_linux_arm.s deleted file mode 100644 index 63f1f9e38..000000000 --- a/src/pkg/sync/atomic/asm_linux_arm.s +++ /dev/null @@ -1,216 +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. - -// +build !race - -#include "textflag.h" - -// Linux/ARM atomic operations. - -// Because there is so much variation in ARM devices, -// the Linux kernel provides an appropriate compare-and-swap -// implementation at address 0xffff0fc0. Caller sets: -// R0 = old value -// R1 = new value -// R2 = addr -// LR = return address -// The function returns with CS true if the swap happened. -// http://lxr.linux.no/linux+v2.6.37.2/arch/arm/kernel/entry-armv.S#L850 -// On older kernels (before 2.6.24) the function can incorrectly -// report a conflict, so we have to double-check the compare ourselves -// and retry if necessary. -// -// http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b49c0f24cf6744a3f4fd09289fe7cade349dead5 -// -TEXT cas<>(SB),NOSPLIT,$0 - MOVW $0xffff0fc0, PC - -TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0 - B ·CompareAndSwapUint32(SB) - -// Implement using kernel cas for portability. -TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-13 - MOVW addr+0(FP), R2 - // trigger potential paging fault here, - // because we don't know how to traceback through __kuser_cmpxchg - MOVW (R2), R0 - MOVW old+4(FP), R0 -casagain: - MOVW new+8(FP), R1 - BL cas<>(SB) - BCC cascheck - MOVW $1, R0 -casret: - MOVB R0, swapped+12(FP) - RET -cascheck: - // Kernel lies; double-check. - MOVW addr+0(FP), R2 - MOVW old+4(FP), R0 - MOVW 0(R2), R3 - CMP R0, R3 - BEQ casagain - MOVW $0, R0 - B casret - -TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0 - B ·CompareAndSwapUint32(SB) - -TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0 - B ·CompareAndSwapUint32(SB) - -TEXT ·AddInt32(SB),NOSPLIT,$0 - B ·AddUint32(SB) - -// Implement using kernel cas for portability. -TEXT ·AddUint32(SB),NOSPLIT,$0-12 - MOVW addr+0(FP), R2 - MOVW delta+4(FP), R4 -addloop1: - MOVW 0(R2), R0 - MOVW R0, R1 - ADD R4, R1 - BL cas<>(SB) - BCC addloop1 - MOVW R1, new+8(FP) - RET - -TEXT ·AddUintptr(SB),NOSPLIT,$0 - B ·AddUint32(SB) - -TEXT ·SwapInt32(SB),NOSPLIT,$0 - B ·SwapUint32(SB) - -// Implement using kernel cas for portability. -TEXT ·SwapUint32(SB),NOSPLIT,$0-12 - MOVW addr+0(FP), R2 - MOVW new+4(FP), R1 -swaploop1: - MOVW 0(R2), R0 - MOVW R0, R4 // cas smashes R0 - BL cas<>(SB) - BCC swaploop1 - MOVW R4, old+8(FP) - RET - -TEXT ·SwapUintptr(SB),NOSPLIT,$0 - B ·SwapUint32(SB) - -TEXT ·SwapPointer(SB),NOSPLIT,$0 - B ·SwapUint32(SB) - -TEXT cas64<>(SB),NOSPLIT,$0 - MOVW $0xffff0f60, PC // __kuser_cmpxchg64: Linux-3.1 and above - -TEXT kernelCAS64<>(SB),NOSPLIT,$0-21 - // int (*__kuser_cmpxchg64_t)(const int64_t *oldval, const int64_t *newval, volatile int64_t *ptr); - MOVW addr+0(FP), R2 // ptr - // trigger potential paging fault here, - // because we don't know how to traceback through __kuser_cmpxchg64 - MOVW (R2), R0 - // make unaligned atomic access panic - AND.S $7, R2, R1 - BEQ 2(PC) - MOVW R1, (R1) - MOVW $4(FP), R0 // oldval - MOVW $12(FP), R1 // newval - BL cas64<>(SB) - MOVW.CS $1, R0 // C is set if the kernel has changed *ptr - MOVW.CC $0, R0 - MOVW R0, 20(FP) - RET - -TEXT ·generalCAS64(SB),NOSPLIT,$0-21 - B runtime·cas64(SB) - -GLOBL armCAS64(SB), $4 - -TEXT setupAndCallCAS64<>(SB),NOSPLIT,$-4-21 - MOVW $0xffff0ffc, R0 // __kuser_helper_version - MOVW (R0), R0 - // __kuser_cmpxchg64 only present if helper version >= 5 - CMP $5, R0 - MOVW.CS $kernelCAS64<>(SB), R1 - MOVW.CS R1, armCAS64(SB) - MOVW.CS R1, PC - MOVB runtime·armArch(SB), R0 - // LDREXD, STREXD only present on ARMv6K or higher - CMP $6, R0 // TODO(minux): how to differentiate ARMv6 with ARMv6K? - MOVW.CS $·armCompareAndSwapUint64(SB), R1 - MOVW.CS R1, armCAS64(SB) - MOVW.CS R1, PC - // we are out of luck, can only use runtime's emulated 64-bit cas - MOVW $·generalCAS64(SB), R1 - MOVW R1, armCAS64(SB) - MOVW R1, PC - -TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0 - B ·CompareAndSwapUint64(SB) - -TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$-4-21 - MOVW armCAS64(SB), R0 - CMP $0, R0 - MOVW.NE R0, PC - B setupAndCallCAS64<>(SB) - -TEXT ·AddInt64(SB),NOSPLIT,$0 - B ·addUint64(SB) - -TEXT ·AddUint64(SB),NOSPLIT,$0 - B ·addUint64(SB) - -TEXT ·SwapInt64(SB),NOSPLIT,$0 - B ·swapUint64(SB) - -TEXT ·SwapUint64(SB),NOSPLIT,$0 - B ·swapUint64(SB) - -TEXT ·LoadInt32(SB),NOSPLIT,$0 - B ·LoadUint32(SB) - -TEXT ·LoadUint32(SB),NOSPLIT,$0-8 - MOVW addr+0(FP), R2 -loadloop1: - MOVW 0(R2), R0 - MOVW R0, R1 - BL cas<>(SB) - BCC loadloop1 - MOVW R1, val+4(FP) - RET - -TEXT ·LoadInt64(SB),NOSPLIT,$0 - B ·loadUint64(SB) - -TEXT ·LoadUint64(SB),NOSPLIT,$0 - B ·loadUint64(SB) - -TEXT ·LoadUintptr(SB),NOSPLIT,$0 - B ·LoadUint32(SB) - -TEXT ·LoadPointer(SB),NOSPLIT,$0 - B ·LoadUint32(SB) - -TEXT ·StoreInt32(SB),NOSPLIT,$0 - B ·StoreUint32(SB) - -TEXT ·StoreUint32(SB),NOSPLIT,$0-8 - MOVW addr+0(FP), R2 - MOVW val+4(FP), R1 -storeloop1: - MOVW 0(R2), R0 - BL cas<>(SB) - BCC storeloop1 - RET - -TEXT ·StoreInt64(SB),NOSPLIT,$0 - B ·storeUint64(SB) - -TEXT ·StoreUint64(SB),NOSPLIT,$0 - B ·storeUint64(SB) - -TEXT ·StoreUintptr(SB),NOSPLIT,$0 - B ·StoreUint32(SB) - -TEXT ·StorePointer(SB),NOSPLIT,$0 - B ·StoreUint32(SB) diff --git a/src/pkg/sync/atomic/asm_nacl_arm.s b/src/pkg/sync/atomic/asm_nacl_arm.s deleted file mode 100644 index 76f623336..000000000 --- a/src/pkg/sync/atomic/asm_nacl_arm.s +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2014 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. - -#include "textflag.h" - -// NaCl/ARM atomic operations. -// NaCl/ARM explicitly targets ARMv7A. - -TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0 - B ·CompareAndSwapUint32(SB) - -TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0 - B ·armCompareAndSwapUint32(SB) - -TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0 - B ·CompareAndSwapUint32(SB) - -TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0 - B ·CompareAndSwapUint32(SB) - -TEXT ·AddInt32(SB),NOSPLIT,$0 - B ·AddUint32(SB) - -TEXT ·AddUint32(SB),NOSPLIT,$0 - B ·armAddUint32(SB) - -TEXT ·AddUintptr(SB),NOSPLIT,$0 - B ·AddUint32(SB) - -TEXT ·SwapInt32(SB),NOSPLIT,$0 - B ·SwapUint32(SB) - -TEXT ·SwapUint32(SB),NOSPLIT,$0 - B ·armSwapUint32(SB) - -TEXT ·SwapUintptr(SB),NOSPLIT,$0 - B ·SwapUint32(SB) - -TEXT ·SwapPointer(SB),NOSPLIT,$0 - B ·SwapUint32(SB) - -TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0 - B ·CompareAndSwapUint64(SB) - -TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$-4 - B ·armCompareAndSwapUint64(SB) - -TEXT ·AddInt64(SB),NOSPLIT,$0 - B ·addUint64(SB) - -TEXT ·AddUint64(SB),NOSPLIT,$0 - B ·addUint64(SB) - -TEXT ·SwapInt64(SB),NOSPLIT,$0 - B ·swapUint64(SB) - -TEXT ·SwapUint64(SB),NOSPLIT,$0 - B ·swapUint64(SB) - -TEXT ·LoadInt32(SB),NOSPLIT,$0 - B ·LoadUint32(SB) - -TEXT ·LoadUint32(SB),NOSPLIT,$0-8 - MOVW addr+0(FP), R1 -load32loop: - LDREX (R1), R2 // loads R2 - STREX R2, (R1), R0 // stores R2 - CMP $0, R0 - BNE load32loop - MOVW R2, val+4(FP) - RET - -TEXT ·LoadInt64(SB),NOSPLIT,$0 - B ·loadUint64(SB) - -TEXT ·LoadUint64(SB),NOSPLIT,$0 - B ·loadUint64(SB) - -TEXT ·LoadUintptr(SB),NOSPLIT,$0 - B ·LoadUint32(SB) - -TEXT ·LoadPointer(SB),NOSPLIT,$0 - B ·LoadUint32(SB) - -TEXT ·StoreInt32(SB),NOSPLIT,$0 - B ·StoreUint32(SB) - -TEXT ·StoreUint32(SB),NOSPLIT,$0-8 - MOVW addr+0(FP), R1 - MOVW val+4(FP), R2 -storeloop: - LDREX (R1), R4 // loads R4 - STREX R2, (R1), R0 // stores R2 - CMP $0, R0 - BNE storeloop - RET - -TEXT ·StoreInt64(SB),NOSPLIT,$0 - B ·storeUint64(SB) - -TEXT ·StoreUint64(SB),NOSPLIT,$0 - B ·storeUint64(SB) - -TEXT ·StoreUintptr(SB),NOSPLIT,$0 - B ·StoreUint32(SB) - -TEXT ·StorePointer(SB),NOSPLIT,$0 - B ·StoreUint32(SB) diff --git a/src/pkg/sync/atomic/asm_netbsd_arm.s b/src/pkg/sync/atomic/asm_netbsd_arm.s deleted file mode 100644 index dbe80898f..000000000 --- a/src/pkg/sync/atomic/asm_netbsd_arm.s +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2013 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. - -#include "textflag.h" - -// NetBSD/ARM atomic operations. -// TODO(minux): this only supports ARMv6K or higher. - -TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0 - B ·CompareAndSwapUint32(SB) - -TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0 - B ·armCompareAndSwapUint32(SB) - -TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0 - B ·CompareAndSwapUint32(SB) - -TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0 - B ·CompareAndSwapUint32(SB) - -TEXT ·AddInt32(SB),NOSPLIT,$0 - B ·AddUint32(SB) - -TEXT ·AddUint32(SB),NOSPLIT,$0 - B ·armAddUint32(SB) - -TEXT ·AddUintptr(SB),NOSPLIT,$0 - B ·AddUint32(SB) - -TEXT ·SwapInt32(SB),NOSPLIT,$0 - B ·SwapUint32(SB) - -TEXT ·SwapUint32(SB),NOSPLIT,$0 - B ·armSwapUint32(SB) - -TEXT ·SwapUintptr(SB),NOSPLIT,$0 - B ·SwapUint32(SB) - -TEXT ·SwapPointer(SB),NOSPLIT,$0 - B ·SwapUint32(SB) - -TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0 - B ·CompareAndSwapUint64(SB) - -TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$-4 - B ·armCompareAndSwapUint64(SB) - -TEXT ·AddInt64(SB),NOSPLIT,$0 - B ·addUint64(SB) - -TEXT ·AddUint64(SB),NOSPLIT,$0 - B ·addUint64(SB) - -TEXT ·SwapInt64(SB),NOSPLIT,$0 - B ·swapUint64(SB) - -TEXT ·SwapUint64(SB),NOSPLIT,$0 - B ·swapUint64(SB) - -TEXT ·LoadInt32(SB),NOSPLIT,$0 - B ·LoadUint32(SB) - -TEXT ·LoadUint32(SB),NOSPLIT,$0-8 - MOVW addr+0(FP), R1 -load32loop: - LDREX (R1), R2 // loads R2 - STREX R2, (R1), R0 // stores R2 - CMP $0, R0 - BNE load32loop - MOVW R2, val+4(FP) - RET - -TEXT ·LoadInt64(SB),NOSPLIT,$0 - B ·loadUint64(SB) - -TEXT ·LoadUint64(SB),NOSPLIT,$0 - B ·loadUint64(SB) - -TEXT ·LoadUintptr(SB),NOSPLIT,$0 - B ·LoadUint32(SB) - -TEXT ·LoadPointer(SB),NOSPLIT,$0 - B ·LoadUint32(SB) - -TEXT ·StoreInt32(SB),NOSPLIT,$0 - B ·StoreUint32(SB) - -TEXT ·StoreUint32(SB),NOSPLIT,$0-8 - MOVW addr+0(FP), R1 - MOVW val+4(FP), R2 -storeloop: - LDREX (R1), R4 // loads R4 - STREX R2, (R1), R0 // stores R2 - CMP $0, R0 - BNE storeloop - RET - -TEXT ·StoreInt64(SB),NOSPLIT,$0 - B ·storeUint64(SB) - -TEXT ·StoreUint64(SB),NOSPLIT,$0 - B ·storeUint64(SB) - -TEXT ·StoreUintptr(SB),NOSPLIT,$0 - B ·StoreUint32(SB) - -TEXT ·StorePointer(SB),NOSPLIT,$0 - B ·StoreUint32(SB) diff --git a/src/pkg/sync/atomic/atomic_linux_arm_test.go b/src/pkg/sync/atomic/atomic_linux_arm_test.go deleted file mode 100644 index b6965b99b..000000000 --- a/src/pkg/sync/atomic/atomic_linux_arm_test.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2013 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 ( - . "sync/atomic" - "testing" -) - -func TestGeneralCAS64(t *testing.T) { - testCompareAndSwapUint64(t, GeneralCAS64) -} diff --git a/src/pkg/sync/atomic/atomic_test.go b/src/pkg/sync/atomic/atomic_test.go deleted file mode 100644 index 9f13af48b..000000000 --- a/src/pkg/sync/atomic/atomic_test.go +++ /dev/null @@ -1,1509 +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 ( - "fmt" - "runtime" - "strings" - . "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 TestSwapInt32(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 := SwapInt32(&x.i, delta) - if x.i != delta || k != j { - t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k) - } - j = delta - } - if x.before != magic32 || x.after != magic32 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32) - } -} - -func TestSwapUint32(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 := SwapUint32(&x.i, delta) - if x.i != delta || k != j { - t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k) - } - j = delta - } - if x.before != magic32 || x.after != magic32 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32) - } -} - -func TestSwapInt64(t *testing.T) { - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - 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 := SwapInt64(&x.i, delta) - if x.i != delta || k != j { - t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k) - } - j = delta - } - if x.before != magic64 || x.after != magic64 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64)) - } -} - -func TestSwapUint64(t *testing.T) { - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - 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 := SwapUint64(&x.i, delta) - if x.i != delta || k != j { - t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k) - } - j = delta - } - if x.before != magic64 || x.after != magic64 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64)) - } -} - -func TestSwapUintptr(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 := SwapUintptr(&x.i, delta) - if x.i != delta || k != j { - t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k) - } - j = delta - } - if x.before != magicptr || x.after != magicptr { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr) - } -} - -func TestSwapPointer(t *testing.T) { - var x struct { - before uintptr - i unsafe.Pointer - 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 := SwapPointer(&x.i, unsafe.Pointer(delta)) - if uintptr(x.i) != delta || uintptr(k) != j { - t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k) - } - j = delta - } - if x.before != magicptr || x.after != magicptr { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr) - } -} - -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.Skipf("Skipping 64-bit tests: %v", test64err) - } - 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.Skipf("Skipping 64-bit tests: %v", test64err) - } - 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.Fatalf("should have swapped %#x %#x", val, val+1) - } - if x.i != val+1 { - t.Fatalf("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.Fatalf("should not have swapped %#x %#x", val, val+2) - } - if x.i != val+1 { - t.Fatalf("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.Fatalf("should have swapped %#x %#x", val, val+1) - } - if x.i != val+1 { - t.Fatalf("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.Fatalf("should not have swapped %#x %#x", val, val+2) - } - if x.i != val+1 { - t.Fatalf("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.Skipf("Skipping 64-bit tests: %v", test64err) - } - 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.Fatalf("should have swapped %#x %#x", val, val+1) - } - if x.i != val+1 { - t.Fatalf("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.Fatalf("should not have swapped %#x %#x", val, val+2) - } - if x.i != val+1 { - t.Fatalf("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, cas func(*uint64, uint64, uint64) bool) { - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - 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 !cas(&x.i, val, val+1) { - t.Fatalf("should have swapped %#x %#x", val, val+1) - } - if x.i != val+1 { - t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1) - } - x.i = val + 1 - if cas(&x.i, val, val+2) { - t.Fatalf("should not have swapped %#x %#x", val, val+2) - } - if x.i != val+1 { - t.Fatalf("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) { - testCompareAndSwapUint64(t, CompareAndSwapUint64) -} - -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.Fatalf("should have swapped %#x %#x", val, val+1) - } - if x.i != val+1 { - t.Fatalf("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.Fatalf("should not have swapped %#x %#x", val, val+2) - } - if x.i != val+1 { - t.Fatalf("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) - } -} - -func TestCompareAndSwapPointer(t *testing.T) { - var x struct { - before uintptr - i unsafe.Pointer - 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 = unsafe.Pointer(val) - if !CompareAndSwapPointer(&x.i, unsafe.Pointer(val), unsafe.Pointer(val+1)) { - t.Fatalf("should have swapped %#x %#x", val, val+1) - } - if x.i != unsafe.Pointer(val+1) { - t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1) - } - x.i = unsafe.Pointer(val + 1) - if CompareAndSwapPointer(&x.i, unsafe.Pointer(val), unsafe.Pointer(val+2)) { - t.Fatalf("should not have swapped %#x %#x", val, val+2) - } - if x.i != unsafe.Pointer(val+1) { - t.Fatalf("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) - } -} - -func TestLoadInt32(t *testing.T) { - var x struct { - before int32 - i int32 - after int32 - } - x.before = magic32 - x.after = magic32 - for delta := int32(1); delta+delta > delta; delta += delta { - k := LoadInt32(&x.i) - if k != x.i { - t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k) - } - x.i += delta - } - if x.before != magic32 || x.after != magic32 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32) - } -} - -func TestLoadUint32(t *testing.T) { - var x struct { - before uint32 - i uint32 - after uint32 - } - x.before = magic32 - x.after = magic32 - for delta := uint32(1); delta+delta > delta; delta += delta { - k := LoadUint32(&x.i) - if k != x.i { - t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k) - } - x.i += delta - } - if x.before != magic32 || x.after != magic32 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32) - } -} - -func TestLoadInt64(t *testing.T) { - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - var x struct { - before int64 - i int64 - after int64 - } - x.before = magic64 - x.after = magic64 - for delta := int64(1); delta+delta > delta; delta += delta { - k := LoadInt64(&x.i) - if k != x.i { - t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k) - } - x.i += delta - } - if x.before != magic64 || x.after != magic64 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64)) - } -} - -func TestLoadUint64(t *testing.T) { - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - var x struct { - before uint64 - i uint64 - after uint64 - } - x.before = magic64 - x.after = magic64 - for delta := uint64(1); delta+delta > delta; delta += delta { - k := LoadUint64(&x.i) - if k != x.i { - t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k) - } - x.i += delta - } - if x.before != magic64 || x.after != magic64 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64)) - } -} - -func TestLoadUintptr(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 delta := uintptr(1); delta+delta > delta; delta += delta { - k := LoadUintptr(&x.i) - if k != x.i { - t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k) - } - x.i += delta - } - if x.before != magicptr || x.after != magicptr { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr) - } -} - -func TestLoadPointer(t *testing.T) { - var x struct { - before uintptr - i unsafe.Pointer - after uintptr - } - var m uint64 = magic64 - magicptr := uintptr(m) - x.before = magicptr - x.after = magicptr - for delta := uintptr(1); delta+delta > delta; delta += delta { - k := LoadPointer(&x.i) - if k != x.i { - t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k) - } - x.i = unsafe.Pointer(uintptr(x.i) + delta) - } - if x.before != magicptr || x.after != magicptr { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr) - } -} - -func TestStoreInt32(t *testing.T) { - var x struct { - before int32 - i int32 - after int32 - } - x.before = magic32 - x.after = magic32 - v := int32(0) - for delta := int32(1); delta+delta > delta; delta += delta { - StoreInt32(&x.i, v) - if x.i != v { - t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v) - } - v += delta - } - if x.before != magic32 || x.after != magic32 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32) - } -} - -func TestStoreUint32(t *testing.T) { - var x struct { - before uint32 - i uint32 - after uint32 - } - x.before = magic32 - x.after = magic32 - v := uint32(0) - for delta := uint32(1); delta+delta > delta; delta += delta { - StoreUint32(&x.i, v) - if x.i != v { - t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v) - } - v += delta - } - if x.before != magic32 || x.after != magic32 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32) - } -} - -func TestStoreInt64(t *testing.T) { - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - var x struct { - before int64 - i int64 - after int64 - } - x.before = magic64 - x.after = magic64 - v := int64(0) - for delta := int64(1); delta+delta > delta; delta += delta { - StoreInt64(&x.i, v) - if x.i != v { - t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v) - } - v += delta - } - if x.before != magic64 || x.after != magic64 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64)) - } -} - -func TestStoreUint64(t *testing.T) { - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - var x struct { - before uint64 - i uint64 - after uint64 - } - x.before = magic64 - x.after = magic64 - v := uint64(0) - for delta := uint64(1); delta+delta > delta; delta += delta { - StoreUint64(&x.i, v) - if x.i != v { - t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v) - } - v += delta - } - if x.before != magic64 || x.after != magic64 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64)) - } -} - -func TestStoreUintptr(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 - v := uintptr(0) - for delta := uintptr(1); delta+delta > delta; delta += delta { - StoreUintptr(&x.i, v) - if x.i != v { - t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v) - } - v += delta - } - if x.before != magicptr || x.after != magicptr { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr) - } -} - -func TestStorePointer(t *testing.T) { - var x struct { - before uintptr - i unsafe.Pointer - after uintptr - } - var m uint64 = magic64 - magicptr := uintptr(m) - x.before = magicptr - x.after = magicptr - v := unsafe.Pointer(uintptr(0)) - for delta := uintptr(1); delta+delta > delta; delta += delta { - StorePointer(&x.i, unsafe.Pointer(v)) - if x.i != v { - t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v) - } - v = unsafe.Pointer(uintptr(v) + delta) - } - 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. -// Swap can't add 1, so it uses a different scheme. -// The functions repeatedly generate a pseudo-random number such that -// low bits are equal to high bits, swap, check that the old value -// has low and high bits equal. - -var hammer32 = map[string]func(*uint32, int){ - "SwapInt32": hammerSwapInt32, - "SwapUint32": hammerSwapUint32, - "SwapUintptr": hammerSwapUintptr32, - "SwapPointer": hammerSwapPointer32, - "AddInt32": hammerAddInt32, - "AddUint32": hammerAddUint32, - "AddUintptr": hammerAddUintptr32, - "CompareAndSwapInt32": hammerCompareAndSwapInt32, - "CompareAndSwapUint32": hammerCompareAndSwapUint32, - "CompareAndSwapUintptr": hammerCompareAndSwapUintptr32, - "CompareAndSwapPointer": hammerCompareAndSwapPointer32, -} - -func init() { - var v uint64 = 1 << 50 - if uintptr(v) != 0 { - // 64-bit system; clear uintptr tests - delete(hammer32, "SwapUintptr") - delete(hammer32, "SwapPointer") - delete(hammer32, "AddUintptr") - delete(hammer32, "CompareAndSwapUintptr") - delete(hammer32, "CompareAndSwapPointer") - } -} - -func hammerSwapInt32(uaddr *uint32, count int) { - addr := (*int32)(unsafe.Pointer(uaddr)) - seed := int(uintptr(unsafe.Pointer(&count))) - for i := 0; i < count; i++ { - new := uint32(seed+i)<<16 | uint32(seed+i)<<16>>16 - old := uint32(SwapInt32(addr, int32(new))) - if old>>16 != old<<16>>16 { - panic(fmt.Sprintf("SwapInt32 is not atomic: %v", old)) - } - } -} - -func hammerSwapUint32(addr *uint32, count int) { - seed := int(uintptr(unsafe.Pointer(&count))) - for i := 0; i < count; i++ { - new := uint32(seed+i)<<16 | uint32(seed+i)<<16>>16 - old := SwapUint32(addr, new) - if old>>16 != old<<16>>16 { - panic(fmt.Sprintf("SwapUint32 is not atomic: %v", old)) - } - } -} - -func hammerSwapUintptr32(uaddr *uint32, count int) { - // only safe when uintptr is 32-bit. - // not called on 64-bit systems. - addr := (*uintptr)(unsafe.Pointer(uaddr)) - seed := int(uintptr(unsafe.Pointer(&count))) - for i := 0; i < count; i++ { - new := uintptr(seed+i)<<16 | uintptr(seed+i)<<16>>16 - old := SwapUintptr(addr, new) - if old>>16 != old<<16>>16 { - panic(fmt.Sprintf("SwapUintptr is not atomic: %#08x", old)) - } - } -} - -func hammerSwapPointer32(uaddr *uint32, count int) { - // only safe when uintptr is 32-bit. - // not called on 64-bit systems. - addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr)) - seed := int(uintptr(unsafe.Pointer(&count))) - for i := 0; i < count; i++ { - new := uintptr(seed+i)<<16 | uintptr(seed+i)<<16>>16 - old := uintptr(SwapPointer(addr, unsafe.Pointer(new))) - if old>>16 != old<<16>>16 { - panic(fmt.Sprintf("SwapPointer is not atomic: %#08x", old)) - } - } -} - -func hammerAddInt32(uaddr *uint32, count int) { - addr := (*int32)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - AddInt32(addr, 1) - } -} - -func hammerAddUint32(addr *uint32, count int) { - for i := 0; i < count; i++ { - AddUint32(addr, 1) - } -} - -func hammerAddUintptr32(uaddr *uint32, count int) { - // only safe when uintptr is 32-bit. - // not called on 64-bit systems. - addr := (*uintptr)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - AddUintptr(addr, 1) - } -} - -func hammerCompareAndSwapInt32(uaddr *uint32, count int) { - addr := (*int32)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - for { - v := LoadInt32(addr) - if CompareAndSwapInt32(addr, v, v+1) { - break - } - } - } -} - -func hammerCompareAndSwapUint32(addr *uint32, count int) { - for i := 0; i < count; i++ { - for { - v := LoadUint32(addr) - if CompareAndSwapUint32(addr, v, v+1) { - break - } - } - } -} - -func hammerCompareAndSwapUintptr32(uaddr *uint32, count int) { - // only safe when uintptr is 32-bit. - // not called on 64-bit systems. - addr := (*uintptr)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - for { - v := LoadUintptr(addr) - if CompareAndSwapUintptr(addr, v, v+1) { - break - } - } - } -} - -func hammerCompareAndSwapPointer32(uaddr *uint32, count int) { - // only safe when uintptr is 32-bit. - // not called on 64-bit systems. - addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - for { - v := LoadPointer(addr) - if CompareAndSwapPointer(addr, v, unsafe.Pointer(uintptr(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 name, testf := range hammer32 { - c := make(chan int) - var val uint32 - for i := 0; i < p; i++ { - go func() { - defer func() { - if err := recover(); err != nil { - t.Error(err.(string)) - } - c <- 1 - }() - testf(&val, n) - }() - } - for i := 0; i < p; i++ { - <-c - } - if !strings.HasPrefix(name, "Swap") && val != uint32(n)*p { - t.Fatalf("%s: val=%d want %d", name, val, n*p) - } - } -} - -var hammer64 = map[string]func(*uint64, int){ - "SwapInt64": hammerSwapInt64, - "SwapUint64": hammerSwapUint64, - "SwapUintptr": hammerSwapUintptr64, - "SwapPointer": hammerSwapPointer64, - "AddInt64": hammerAddInt64, - "AddUint64": hammerAddUint64, - "AddUintptr": hammerAddUintptr64, - "CompareAndSwapInt64": hammerCompareAndSwapInt64, - "CompareAndSwapUint64": hammerCompareAndSwapUint64, - "CompareAndSwapUintptr": hammerCompareAndSwapUintptr64, - "CompareAndSwapPointer": hammerCompareAndSwapPointer64, -} - -func init() { - var v uint64 = 1 << 50 - if uintptr(v) == 0 { - // 32-bit system; clear uintptr tests - delete(hammer64, "SwapUintptr") - delete(hammer64, "SwapPointer") - delete(hammer64, "AddUintptr") - delete(hammer64, "CompareAndSwapUintptr") - delete(hammer64, "CompareAndSwapPointer") - } -} - -func hammerSwapInt64(uaddr *uint64, count int) { - addr := (*int64)(unsafe.Pointer(uaddr)) - seed := int(uintptr(unsafe.Pointer(&count))) - for i := 0; i < count; i++ { - new := uint64(seed+i)<<32 | uint64(seed+i)<<32>>32 - old := uint64(SwapInt64(addr, int64(new))) - if old>>32 != old<<32>>32 { - panic(fmt.Sprintf("SwapInt64 is not atomic: %v", old)) - } - } -} - -func hammerSwapUint64(addr *uint64, count int) { - seed := int(uintptr(unsafe.Pointer(&count))) - for i := 0; i < count; i++ { - new := uint64(seed+i)<<32 | uint64(seed+i)<<32>>32 - old := SwapUint64(addr, new) - if old>>32 != old<<32>>32 { - panic(fmt.Sprintf("SwapUint64 is not atomic: %v", old)) - } - } -} - -func hammerSwapUintptr64(uaddr *uint64, count int) { - // only safe when uintptr is 64-bit. - // not called on 32-bit systems. - addr := (*uintptr)(unsafe.Pointer(uaddr)) - seed := int(uintptr(unsafe.Pointer(&count))) - for i := 0; i < count; i++ { - new := uintptr(seed+i)<<32 | uintptr(seed+i)<<32>>32 - old := SwapUintptr(addr, new) - if old>>32 != old<<32>>32 { - panic(fmt.Sprintf("SwapUintptr is not atomic: %v", old)) - } - } -} - -func hammerSwapPointer64(uaddr *uint64, count int) { - // only safe when uintptr is 64-bit. - // not called on 32-bit systems. - addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr)) - seed := int(uintptr(unsafe.Pointer(&count))) - for i := 0; i < count; i++ { - new := uintptr(seed+i)<<32 | uintptr(seed+i)<<32>>32 - old := uintptr(SwapPointer(addr, unsafe.Pointer(new))) - if old>>32 != old<<32>>32 { - panic(fmt.Sprintf("SwapPointer is not atomic: %v", old)) - } - } -} - -func hammerAddInt64(uaddr *uint64, count int) { - addr := (*int64)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - AddInt64(addr, 1) - } -} - -func hammerAddUint64(addr *uint64, count int) { - for i := 0; i < count; i++ { - AddUint64(addr, 1) - } -} - -func hammerAddUintptr64(uaddr *uint64, count int) { - // only safe when uintptr is 64-bit. - // not called on 32-bit systems. - addr := (*uintptr)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - AddUintptr(addr, 1) - } -} - -func hammerCompareAndSwapInt64(uaddr *uint64, count int) { - addr := (*int64)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - for { - v := LoadInt64(addr) - if CompareAndSwapInt64(addr, v, v+1) { - break - } - } - } -} - -func hammerCompareAndSwapUint64(addr *uint64, count int) { - for i := 0; i < count; i++ { - for { - v := LoadUint64(addr) - if CompareAndSwapUint64(addr, v, v+1) { - break - } - } - } -} - -func hammerCompareAndSwapUintptr64(uaddr *uint64, count int) { - // only safe when uintptr is 64-bit. - // not called on 32-bit systems. - addr := (*uintptr)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - for { - v := LoadUintptr(addr) - if CompareAndSwapUintptr(addr, v, v+1) { - break - } - } - } -} - -func hammerCompareAndSwapPointer64(uaddr *uint64, count int) { - // only safe when uintptr is 64-bit. - // not called on 32-bit systems. - addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - for { - v := LoadPointer(addr) - if CompareAndSwapPointer(addr, v, unsafe.Pointer(uintptr(v)+1)) { - break - } - } - } -} - -func TestHammer64(t *testing.T) { - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - const p = 4 - n := 100000 - if testing.Short() { - n = 1000 - } - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(p)) - - for name, testf := range hammer64 { - c := make(chan int) - var val uint64 - for i := 0; i < p; i++ { - go func() { - defer func() { - if err := recover(); err != nil { - t.Error(err.(string)) - } - c <- 1 - }() - testf(&val, n) - }() - } - for i := 0; i < p; i++ { - <-c - } - if !strings.HasPrefix(name, "Swap") && val != uint64(n)*p { - t.Fatalf("%s: val=%d want %d", name, val, n*p) - } - } -} - -func hammerStoreLoadInt32(t *testing.T, paddr unsafe.Pointer) { - addr := (*int32)(paddr) - v := LoadInt32(addr) - vlo := v & ((1 << 16) - 1) - vhi := v >> 16 - if vlo != vhi { - t.Fatalf("Int32: %#x != %#x", vlo, vhi) - } - new := v + 1 + 1<<16 - if vlo == 1e4 { - new = 0 - } - StoreInt32(addr, new) -} - -func hammerStoreLoadUint32(t *testing.T, paddr unsafe.Pointer) { - addr := (*uint32)(paddr) - v := LoadUint32(addr) - vlo := v & ((1 << 16) - 1) - vhi := v >> 16 - if vlo != vhi { - t.Fatalf("Uint32: %#x != %#x", vlo, vhi) - } - new := v + 1 + 1<<16 - if vlo == 1e4 { - new = 0 - } - StoreUint32(addr, new) -} - -func hammerStoreLoadInt64(t *testing.T, paddr unsafe.Pointer) { - addr := (*int64)(paddr) - v := LoadInt64(addr) - vlo := v & ((1 << 32) - 1) - vhi := v >> 32 - if vlo != vhi { - t.Fatalf("Int64: %#x != %#x", vlo, vhi) - } - new := v + 1 + 1<<32 - StoreInt64(addr, new) -} - -func hammerStoreLoadUint64(t *testing.T, paddr unsafe.Pointer) { - addr := (*uint64)(paddr) - v := LoadUint64(addr) - vlo := v & ((1 << 32) - 1) - vhi := v >> 32 - if vlo != vhi { - t.Fatalf("Uint64: %#x != %#x", vlo, vhi) - } - new := v + 1 + 1<<32 - StoreUint64(addr, new) -} - -func hammerStoreLoadUintptr(t *testing.T, paddr unsafe.Pointer) { - addr := (*uintptr)(paddr) - var test64 uint64 = 1 << 50 - arch32 := uintptr(test64) == 0 - v := LoadUintptr(addr) - new := v - if arch32 { - vlo := v & ((1 << 16) - 1) - vhi := v >> 16 - if vlo != vhi { - t.Fatalf("Uintptr: %#x != %#x", vlo, vhi) - } - new = v + 1 + 1<<16 - if vlo == 1e4 { - new = 0 - } - } else { - vlo := v & ((1 << 32) - 1) - vhi := v >> 32 - if vlo != vhi { - t.Fatalf("Uintptr: %#x != %#x", vlo, vhi) - } - inc := uint64(1 + 1<<32) - new = v + uintptr(inc) - } - StoreUintptr(addr, new) -} - -func hammerStoreLoadPointer(t *testing.T, paddr unsafe.Pointer) { - addr := (*unsafe.Pointer)(paddr) - var test64 uint64 = 1 << 50 - arch32 := uintptr(test64) == 0 - v := uintptr(LoadPointer(addr)) - new := v - if arch32 { - vlo := v & ((1 << 16) - 1) - vhi := v >> 16 - if vlo != vhi { - t.Fatalf("Pointer: %#x != %#x", vlo, vhi) - } - new = v + 1 + 1<<16 - if vlo == 1e4 { - new = 0 - } - } else { - vlo := v & ((1 << 32) - 1) - vhi := v >> 32 - if vlo != vhi { - t.Fatalf("Pointer: %#x != %#x", vlo, vhi) - } - inc := uint64(1 + 1<<32) - new = v + uintptr(inc) - } - StorePointer(addr, unsafe.Pointer(new)) -} - -func TestHammerStoreLoad(t *testing.T) { - var tests []func(*testing.T, unsafe.Pointer) - tests = append(tests, hammerStoreLoadInt32, hammerStoreLoadUint32, - hammerStoreLoadUintptr, hammerStoreLoadPointer) - if test64err == nil { - tests = append(tests, hammerStoreLoadInt64, hammerStoreLoadUint64) - } - n := int(1e6) - if testing.Short() { - n = int(1e4) - } - const procs = 8 - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(procs)) - for _, tt := range tests { - c := make(chan int) - var val uint64 - for p := 0; p < procs; p++ { - go func() { - for i := 0; i < n; i++ { - tt(t, unsafe.Pointer(&val)) - } - c <- 1 - }() - } - for p := 0; p < procs; p++ { - <-c - } - } -} - -func TestStoreLoadSeqCst32(t *testing.T) { - if runtime.NumCPU() == 1 { - t.Skipf("Skipping test on %v processor machine", runtime.NumCPU()) - } - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) - N := int32(1e3) - if testing.Short() { - N = int32(1e2) - } - c := make(chan bool, 2) - X := [2]int32{} - ack := [2][3]int32{{-1, -1, -1}, {-1, -1, -1}} - for p := 0; p < 2; p++ { - go func(me int) { - he := 1 - me - for i := int32(1); i < N; i++ { - StoreInt32(&X[me], i) - my := LoadInt32(&X[he]) - StoreInt32(&ack[me][i%3], my) - for w := 1; LoadInt32(&ack[he][i%3]) == -1; w++ { - if w%1000 == 0 { - runtime.Gosched() - } - } - his := LoadInt32(&ack[he][i%3]) - if (my != i && my != i-1) || (his != i && his != i-1) { - t.Fatalf("invalid values: %d/%d (%d)", my, his, i) - } - if my != i && his != i { - t.Fatalf("store/load are not sequentially consistent: %d/%d (%d)", my, his, i) - } - StoreInt32(&ack[me][(i-1)%3], -1) - } - c <- true - }(p) - } - <-c - <-c -} - -func TestStoreLoadSeqCst64(t *testing.T) { - if runtime.NumCPU() == 1 { - t.Skipf("Skipping test on %v processor machine", runtime.NumCPU()) - } - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) - N := int64(1e3) - if testing.Short() { - N = int64(1e2) - } - c := make(chan bool, 2) - X := [2]int64{} - ack := [2][3]int64{{-1, -1, -1}, {-1, -1, -1}} - for p := 0; p < 2; p++ { - go func(me int) { - he := 1 - me - for i := int64(1); i < N; i++ { - StoreInt64(&X[me], i) - my := LoadInt64(&X[he]) - StoreInt64(&ack[me][i%3], my) - for w := 1; LoadInt64(&ack[he][i%3]) == -1; w++ { - if w%1000 == 0 { - runtime.Gosched() - } - } - his := LoadInt64(&ack[he][i%3]) - if (my != i && my != i-1) || (his != i && his != i-1) { - t.Fatalf("invalid values: %d/%d (%d)", my, his, i) - } - if my != i && his != i { - t.Fatalf("store/load are not sequentially consistent: %d/%d (%d)", my, his, i) - } - StoreInt64(&ack[me][(i-1)%3], -1) - } - c <- true - }(p) - } - <-c - <-c -} - -func TestStoreLoadRelAcq32(t *testing.T) { - if runtime.NumCPU() == 1 { - t.Skipf("Skipping test on %v processor machine", runtime.NumCPU()) - } - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) - N := int32(1e3) - if testing.Short() { - N = int32(1e2) - } - c := make(chan bool, 2) - type Data struct { - signal int32 - pad1 [128]int8 - data1 int32 - pad2 [128]int8 - data2 float32 - } - var X Data - for p := int32(0); p < 2; p++ { - go func(p int32) { - for i := int32(1); i < N; i++ { - if (i+p)%2 == 0 { - X.data1 = i - X.data2 = float32(i) - StoreInt32(&X.signal, i) - } else { - for w := 1; LoadInt32(&X.signal) != i; w++ { - if w%1000 == 0 { - runtime.Gosched() - } - } - d1 := X.data1 - d2 := X.data2 - if d1 != i || d2 != float32(i) { - t.Fatalf("incorrect data: %d/%g (%d)", d1, d2, i) - } - } - } - c <- true - }(p) - } - <-c - <-c -} - -func TestStoreLoadRelAcq64(t *testing.T) { - if runtime.NumCPU() == 1 { - t.Skipf("Skipping test on %v processor machine", runtime.NumCPU()) - } - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) - N := int64(1e3) - if testing.Short() { - N = int64(1e2) - } - c := make(chan bool, 2) - type Data struct { - signal int64 - pad1 [128]int8 - data1 int64 - pad2 [128]int8 - data2 float64 - } - var X Data - for p := int64(0); p < 2; p++ { - go func(p int64) { - for i := int64(1); i < N; i++ { - if (i+p)%2 == 0 { - X.data1 = i - X.data2 = float64(i) - StoreInt64(&X.signal, i) - } else { - for w := 1; LoadInt64(&X.signal) != i; w++ { - if w%1000 == 0 { - runtime.Gosched() - } - } - d1 := X.data1 - d2 := X.data2 - if d1 != i || d2 != float64(i) { - t.Fatalf("incorrect data: %d/%g (%d)", d1, d2, i) - } - } - } - c <- true - }(p) - } - <-c - <-c -} - -func shouldPanic(t *testing.T, name string, f func()) { - defer func() { - if recover() == nil { - t.Errorf("%s did not panic", name) - } - }() - f() -} - -func TestUnaligned64(t *testing.T) { - // Unaligned 64-bit atomics on 32-bit systems are - // a continual source of pain. Test that on 32-bit systems they crash - // instead of failing silently. - if unsafe.Sizeof(int(0)) != 4 { - t.Skip("test only runs on 32-bit systems") - } - - x := make([]uint32, 4) - p := (*uint64)(unsafe.Pointer(&x[1])) // misaligned - - shouldPanic(t, "LoadUint64", func() { LoadUint64(p) }) - shouldPanic(t, "StoreUint64", func() { StoreUint64(p, 1) }) - shouldPanic(t, "CompareAndSwapUint64", func() { CompareAndSwapUint64(p, 1, 2) }) - shouldPanic(t, "AddUint64", func() { AddUint64(p, 3) }) -} - -func TestNilDeref(t *testing.T) { - if p := runtime.GOOS + "/" + runtime.GOARCH; p == "freebsd/arm" || p == "netbsd/arm" { - t.Skipf("issue 7338: skipping test on %q", p) - } - funcs := [...]func(){ - func() { CompareAndSwapInt32(nil, 0, 0) }, - func() { CompareAndSwapInt64(nil, 0, 0) }, - func() { CompareAndSwapUint32(nil, 0, 0) }, - func() { CompareAndSwapUint64(nil, 0, 0) }, - func() { CompareAndSwapUintptr(nil, 0, 0) }, - func() { CompareAndSwapPointer(nil, nil, nil) }, - func() { SwapInt32(nil, 0) }, - func() { SwapUint32(nil, 0) }, - func() { SwapInt64(nil, 0) }, - func() { SwapUint64(nil, 0) }, - func() { SwapUintptr(nil, 0) }, - func() { SwapPointer(nil, nil) }, - func() { AddInt32(nil, 0) }, - func() { AddUint32(nil, 0) }, - func() { AddInt64(nil, 0) }, - func() { AddUint64(nil, 0) }, - func() { AddUintptr(nil, 0) }, - func() { LoadInt32(nil) }, - func() { LoadInt64(nil) }, - func() { LoadUint32(nil) }, - func() { LoadUint64(nil) }, - func() { LoadUintptr(nil) }, - func() { LoadPointer(nil) }, - func() { StoreInt32(nil, 0) }, - func() { StoreInt64(nil, 0) }, - func() { StoreUint32(nil, 0) }, - func() { StoreUint64(nil, 0) }, - func() { StoreUintptr(nil, 0) }, - func() { StorePointer(nil, nil) }, - } - for _, f := range funcs { - func() { - defer func() { - runtime.GC() - recover() - }() - f() - }() - } -} diff --git a/src/pkg/sync/atomic/doc.go b/src/pkg/sync/atomic/doc.go deleted file mode 100644 index 10fb8c917..000000000 --- a/src/pkg/sync/atomic/doc.go +++ /dev/null @@ -1,149 +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 provides low-level atomic memory primitives -// useful for implementing synchronization algorithms. -// -// These functions require great care to be used correctly. -// Except for special, low-level applications, synchronization is better -// done with channels or the facilities of the sync package. -// Share memory by communicating; -// don't communicate by sharing memory. -// -// The swap operation, implemented by the SwapT functions, is the atomic -// equivalent of: -// -// old = *addr -// *addr = new -// return old -// -// The compare-and-swap operation, implemented by the CompareAndSwapT -// functions, is the atomic equivalent of: -// -// if *addr == old { -// *addr = new -// return true -// } -// return false -// -// The add operation, implemented by the AddT functions, is the atomic -// equivalent of: -// -// *addr += delta -// return *addr -// -// The load and store operations, implemented by the LoadT and StoreT -// functions, are the atomic equivalents of "return *addr" and -// "*addr = val". -// -package atomic - -import ( - "unsafe" -) - -// BUG(rsc): On x86-32, the 64-bit functions use instructions unavailable before the Pentium MMX. -// -// On non-Linux ARM, the 64-bit functions use instructions unavailable before the ARMv6k core. -// -// On both ARM and x86-32, it is the caller's responsibility to arrange for 64-bit -// alignment of 64-bit words accessed atomically. The first word in a global -// variable or in an allocated struct or slice can be relied upon to be -// 64-bit aligned. - -// SwapInt32 atomically stores new into *addr and returns the previous *addr value. -func SwapInt32(addr *int32, new int32) (old int32) - -// SwapInt64 atomically stores new into *addr and returns the previous *addr value. -func SwapInt64(addr *int64, new int64) (old int64) - -// SwapUint32 atomically stores new into *addr and returns the previous *addr value. -func SwapUint32(addr *uint32, new uint32) (old uint32) - -// SwapUint64 atomically stores new into *addr and returns the previous *addr value. -func SwapUint64(addr *uint64, new uint64) (old uint64) - -// SwapUintptr atomically stores new into *addr and returns the previous *addr value. -func SwapUintptr(addr *uintptr, new uintptr) (old uintptr) - -// SwapPointer atomically stores new into *addr and returns the previous *addr value. -func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer) - -// CompareAndSwapInt32 executes the compare-and-swap operation for an int32 value. -func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool) - -// CompareAndSwapInt64 executes the compare-and-swap operation for an int64 value. -func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool) - -// CompareAndSwapUint32 executes the compare-and-swap operation for a uint32 value. -func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool) - -// CompareAndSwapUint64 executes the compare-and-swap operation for a uint64 value. -func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool) - -// CompareAndSwapUintptr executes the compare-and-swap operation for a uintptr value. -func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool) - -// CompareAndSwapPointer executes the compare-and-swap operation for a unsafe.Pointer value. -func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool) - -// AddInt32 atomically adds delta to *addr and returns the new value. -func AddInt32(addr *int32, delta int32) (new int32) - -// AddUint32 atomically adds delta to *addr and returns the new value. -// To subtract a signed positive constant value c from x, do AddUint32(&x, ^uint32(c-1)). -// In particular, to decrement x, do AddUint32(&x, ^uint32(0)). -func AddUint32(addr *uint32, delta uint32) (new uint32) - -// AddInt64 atomically adds delta to *addr and returns the new value. -func AddInt64(addr *int64, delta int64) (new int64) - -// AddUint64 atomically adds delta to *addr and returns the new value. -// To subtract a signed positive constant value c from x, do AddUint64(&x, ^uint64(c-1)). -// In particular, to decrement x, do AddUint64(&x, ^uint64(0)). -func AddUint64(addr *uint64, delta uint64) (new uint64) - -// AddUintptr atomically adds delta to *addr and returns the new value. -func AddUintptr(addr *uintptr, delta uintptr) (new uintptr) - -// LoadInt32 atomically loads *addr. -func LoadInt32(addr *int32) (val int32) - -// LoadInt64 atomically loads *addr. -func LoadInt64(addr *int64) (val int64) - -// LoadUint32 atomically loads *addr. -func LoadUint32(addr *uint32) (val uint32) - -// LoadUint64 atomically loads *addr. -func LoadUint64(addr *uint64) (val uint64) - -// LoadUintptr atomically loads *addr. -func LoadUintptr(addr *uintptr) (val uintptr) - -// LoadPointer atomically loads *addr. -func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer) - -// StoreInt32 atomically stores val into *addr. -func StoreInt32(addr *int32, val int32) - -// StoreInt64 atomically stores val into *addr. -func StoreInt64(addr *int64, val int64) - -// StoreUint32 atomically stores val into *addr. -func StoreUint32(addr *uint32, val uint32) - -// StoreUint64 atomically stores val into *addr. -func StoreUint64(addr *uint64, val uint64) - -// StoreUintptr atomically stores val into *addr. -func StoreUintptr(addr *uintptr, val uintptr) - -// StorePointer atomically stores val into *addr. -func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) - -// Helper for ARM. Linker will discard on other systems -func panic64() { - panic("sync/atomic: broken 64-bit atomic operations (buggy QEMU)") -} diff --git a/src/pkg/sync/atomic/export_linux_arm_test.go b/src/pkg/sync/atomic/export_linux_arm_test.go deleted file mode 100644 index 5cd43353e..000000000 --- a/src/pkg/sync/atomic/export_linux_arm_test.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2013 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 - -func generalCAS64(addr *uint64, old uint64, new uint64) bool - -var GeneralCAS64 = generalCAS64 diff --git a/src/pkg/sync/atomic/race.s b/src/pkg/sync/atomic/race.s deleted file mode 100644 index bdce7668b..000000000 --- a/src/pkg/sync/atomic/race.s +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2014 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. - -// +build race - -// This file is here only to allow external functions. -// The operations are implemented in src/runtime/race_amd64.s |