diff options
Diffstat (limited to 'src/pkg/sync/atomic')
-rw-r--r-- | src/pkg/sync/atomic/asm_386.s | 14 | ||||
-rw-r--r-- | src/pkg/sync/atomic/asm_amd64.s | 4 | ||||
-rw-r--r-- | src/pkg/sync/atomic/asm_amd64p32.s | 159 | ||||
-rw-r--r-- | src/pkg/sync/atomic/asm_linux_arm.s | 12 | ||||
-rw-r--r-- | src/pkg/sync/atomic/atomic_test.go | 7 | ||||
-rw-r--r-- | src/pkg/sync/atomic/export_linux_arm_test.go | 2 |
6 files changed, 180 insertions, 18 deletions
diff --git a/src/pkg/sync/atomic/asm_386.s b/src/pkg/sync/atomic/asm_386.s index eaa72eabb..807c2f873 100644 --- a/src/pkg/sync/atomic/asm_386.s +++ b/src/pkg/sync/atomic/asm_386.s @@ -13,7 +13,7 @@ TEXT ·SwapUint32(SB),NOSPLIT,$0-12 MOVL addr+0(FP), BP MOVL new+4(FP), AX XCHGL AX, 0(BP) - MOVL AX, new+8(FP) + MOVL AX, old+8(FP) RET TEXT ·SwapInt64(SB),NOSPLIT,$0-20 @@ -43,8 +43,8 @@ swaploop: // success // return DX:AX - MOVL AX, new_lo+12(FP) - MOVL DX, new_hi+16(FP) + MOVL AX, old_lo+12(FP) + MOVL DX, old_hi+16(FP) RET TEXT ·SwapUintptr(SB),NOSPLIT,$0-12 @@ -155,10 +155,10 @@ TEXT ·LoadUint32(SB),NOSPLIT,$0-8 MOVL AX, val+4(FP) RET -TEXT ·LoadInt64(SB),NOSPLIT,$0-16 +TEXT ·LoadInt64(SB),NOSPLIT,$0-12 JMP ·LoadUint64(SB) -TEXT ·LoadUint64(SB),NOSPLIT,$0-16 +TEXT ·LoadUint64(SB),NOSPLIT,$0-12 MOVL addr+0(FP), AX TESTL $7, AX JZ 2(PC) @@ -186,10 +186,10 @@ TEXT ·StoreUint32(SB),NOSPLIT,$0-8 XCHGL AX, 0(BP) RET -TEXT ·StoreInt64(SB),NOSPLIT,$0-16 +TEXT ·StoreInt64(SB),NOSPLIT,$0-12 JMP ·StoreUint64(SB) -TEXT ·StoreUint64(SB),NOSPLIT,$0-16 +TEXT ·StoreUint64(SB),NOSPLIT,$0-12 MOVL addr+0(FP), AX TESTL $7, AX JZ 2(PC) diff --git a/src/pkg/sync/atomic/asm_amd64.s b/src/pkg/sync/atomic/asm_amd64.s index 0900492dc..77afa129e 100644 --- a/src/pkg/sync/atomic/asm_amd64.s +++ b/src/pkg/sync/atomic/asm_amd64.s @@ -13,7 +13,7 @@ TEXT ·SwapUint32(SB),NOSPLIT,$0-20 MOVQ addr+0(FP), BP MOVL new+8(FP), AX XCHGL AX, 0(BP) - MOVL AX, new+16(FP) + MOVL AX, old+16(FP) RET TEXT ·SwapInt64(SB),NOSPLIT,$0-24 @@ -23,7 +23,7 @@ TEXT ·SwapUint64(SB),NOSPLIT,$0-24 MOVQ addr+0(FP), BP MOVQ new+8(FP), AX XCHGQ AX, 0(BP) - MOVQ AX, new+16(FP) + MOVQ AX, old+16(FP) RET TEXT ·SwapUintptr(SB),NOSPLIT,$0-24 diff --git a/src/pkg/sync/atomic/asm_amd64p32.s b/src/pkg/sync/atomic/asm_amd64p32.s new file mode 100644 index 000000000..b24ae7a59 --- /dev/null +++ b/src/pkg/sync/atomic/asm_amd64p32.s @@ -0,0 +1,159 @@ +// 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 "../../../cmd/ld/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_linux_arm.s b/src/pkg/sync/atomic/asm_linux_arm.s index b85ca0a13..27be57aa1 100644 --- a/src/pkg/sync/atomic/asm_linux_arm.s +++ b/src/pkg/sync/atomic/asm_linux_arm.s @@ -42,7 +42,7 @@ casagain: BCC cascheck MOVW $1, R0 casret: - MOVW R0, ret+12(FP) + MOVB R0, swapped+12(FP) RET cascheck: // Kernel lies; double-check. @@ -73,7 +73,7 @@ addloop1: ADD R4, R1 BL cas<>(SB) BCC addloop1 - MOVW R1, ret+8(FP) + MOVW R1, new+8(FP) RET TEXT ·AddUintptr(SB),NOSPLIT,$0 @@ -132,13 +132,13 @@ TEXT ·generalCAS64(SB),NOSPLIT,$20-21 BEQ 2(PC) MOVW R1, (R1) MOVW R0, 4(R13) - MOVW oldlo+4(FP), R1 + MOVW old_lo+4(FP), R1 MOVW R1, 8(R13) - MOVW oldhi+8(FP), R1 + MOVW old_hi+8(FP), R1 MOVW R1, 12(R13) - MOVW newlo+12(FP), R2 + MOVW new_lo+12(FP), R2 MOVW R2, 16(R13) - MOVW newhi+16(FP), R3 + MOVW new_hi+16(FP), R3 MOVW R3, 20(R13) BL runtime·cas64(SB) MOVB R0, ret+20(FP) diff --git a/src/pkg/sync/atomic/atomic_test.go b/src/pkg/sync/atomic/atomic_test.go index e10effe7e..a5f44f70d 100644 --- a/src/pkg/sync/atomic/atomic_test.go +++ b/src/pkg/sync/atomic/atomic_test.go @@ -813,7 +813,7 @@ func hammerSwapUintptr32(uaddr *uint32, count int) { 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: %v", old)) + panic(fmt.Sprintf("SwapUintptr is not atomic: %#08x", old)) } } } @@ -827,7 +827,7 @@ func hammerSwapPointer32(uaddr *uint32, count int) { 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: %v", old)) + panic(fmt.Sprintf("SwapPointer is not atomic: %#08x", old)) } } } @@ -1463,6 +1463,9 @@ func TestUnaligned64(t *testing.T) { } 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) }, diff --git a/src/pkg/sync/atomic/export_linux_arm_test.go b/src/pkg/sync/atomic/export_linux_arm_test.go index 8c0b5a75c..5cd43353e 100644 --- a/src/pkg/sync/atomic/export_linux_arm_test.go +++ b/src/pkg/sync/atomic/export_linux_arm_test.go @@ -4,6 +4,6 @@ package atomic -func generalCAS64(*uint64, uint64, uint64) bool +func generalCAS64(addr *uint64, old uint64, new uint64) bool var GeneralCAS64 = generalCAS64 |