Commit e39072d6 authored by Nigel Tao's avatar Nigel Tao

sync/atomic: add package doc for AddT, LoadT and StoreT.

Rename the first argument of CompareAndSwapT and AddT s/val/addr/
for consistency with LoadT and StoreT.

R=rsc, r, dvyukov
CC=golang-dev
https://golang.org/cl/6494112
parent 8fd65b0e
...@@ -6,7 +6,7 @@ TEXT ·CompareAndSwapInt32(SB),7,$0 ...@@ -6,7 +6,7 @@ TEXT ·CompareAndSwapInt32(SB),7,$0
JMP ·CompareAndSwapUint32(SB) JMP ·CompareAndSwapUint32(SB)
TEXT ·CompareAndSwapUint32(SB),7,$0 TEXT ·CompareAndSwapUint32(SB),7,$0
MOVL valptr+0(FP), BP MOVL addr+0(FP), BP
MOVL old+4(FP), AX MOVL old+4(FP), AX
MOVL new+8(FP), CX MOVL new+8(FP), CX
// CMPXCHGL was introduced on the 486. // CMPXCHGL was introduced on the 486.
...@@ -25,7 +25,7 @@ TEXT ·CompareAndSwapInt64(SB),7,$0 ...@@ -25,7 +25,7 @@ TEXT ·CompareAndSwapInt64(SB),7,$0
JMP ·CompareAndSwapUint64(SB) JMP ·CompareAndSwapUint64(SB)
TEXT ·CompareAndSwapUint64(SB),7,$0 TEXT ·CompareAndSwapUint64(SB),7,$0
MOVL valptr+0(FP), BP MOVL addr+0(FP), BP
MOVL oldlo+4(FP), AX MOVL oldlo+4(FP), AX
MOVL oldhi+8(FP), DX MOVL oldhi+8(FP), DX
MOVL newlo+12(FP), BX MOVL newlo+12(FP), BX
...@@ -40,7 +40,7 @@ TEXT ·AddInt32(SB),7,$0 ...@@ -40,7 +40,7 @@ TEXT ·AddInt32(SB),7,$0
JMP ·AddUint32(SB) JMP ·AddUint32(SB)
TEXT ·AddUint32(SB),7,$0 TEXT ·AddUint32(SB),7,$0
MOVL valptr+0(FP), BP MOVL addr+0(FP), BP
MOVL delta+4(FP), AX MOVL delta+4(FP), AX
MOVL AX, CX MOVL AX, CX
// XADD was introduced on the 486. // XADD was introduced on the 486.
...@@ -58,24 +58,24 @@ TEXT ·AddInt64(SB),7,$0 ...@@ -58,24 +58,24 @@ TEXT ·AddInt64(SB),7,$0
TEXT ·AddUint64(SB),7,$0 TEXT ·AddUint64(SB),7,$0
// no XADDQ so use CMPXCHG8B loop // no XADDQ so use CMPXCHG8B loop
MOVL valptr+0(FP), BP MOVL addr+0(FP), BP
// DI:SI = delta // DI:SI = delta
MOVL deltalo+4(FP), SI MOVL deltalo+4(FP), SI
MOVL deltahi+8(FP), DI MOVL deltahi+8(FP), DI
// DX:AX = *valptr // DX:AX = *addr
MOVL 0(BP), AX MOVL 0(BP), AX
MOVL 4(BP), DX MOVL 4(BP), DX
addloop: addloop:
// CX:BX = DX:AX (*valptr) + DI:SI (delta) // CX:BX = DX:AX (*addr) + DI:SI (delta)
MOVL AX, BX MOVL AX, BX
MOVL DX, CX MOVL DX, CX
ADDL SI, BX ADDL SI, BX
ADCL DI, CX ADCL DI, CX
// if *valptr == DX:AX { // if *addr == DX:AX {
// *valptr = CX:BX // *addr = CX:BX
// } else { // } else {
// DX:AX = *valptr // DX:AX = *addr
// } // }
// all in one instruction // all in one instruction
LOCK LOCK
...@@ -93,7 +93,7 @@ TEXT ·LoadInt32(SB),7,$0 ...@@ -93,7 +93,7 @@ TEXT ·LoadInt32(SB),7,$0
JMP ·LoadUint32(SB) JMP ·LoadUint32(SB)
TEXT ·LoadUint32(SB),7,$0 TEXT ·LoadUint32(SB),7,$0
MOVL addrptr+0(FP), AX MOVL addr+0(FP), AX
MOVL 0(AX), AX MOVL 0(AX), AX
MOVL AX, ret+4(FP) MOVL AX, ret+4(FP)
RET RET
...@@ -102,7 +102,7 @@ TEXT ·LoadInt64(SB),7,$0 ...@@ -102,7 +102,7 @@ TEXT ·LoadInt64(SB),7,$0
JMP ·LoadUint64(SB) JMP ·LoadUint64(SB)
TEXT ·LoadUint64(SB),7,$0 TEXT ·LoadUint64(SB),7,$0
MOVL addrptr+0(FP), AX MOVL addr+0(FP), AX
// MOVQ and EMMS were introduced on the Pentium MMX. // MOVQ and EMMS were introduced on the Pentium MMX.
// MOVQ (%EAX), %MM0 // MOVQ (%EAX), %MM0
BYTE $0x0f; BYTE $0x6f; BYTE $0x00 BYTE $0x0f; BYTE $0x6f; BYTE $0x00
...@@ -121,7 +121,7 @@ TEXT ·StoreInt32(SB),7,$0 ...@@ -121,7 +121,7 @@ TEXT ·StoreInt32(SB),7,$0
JMP ·StoreUint32(SB) JMP ·StoreUint32(SB)
TEXT ·StoreUint32(SB),7,$0 TEXT ·StoreUint32(SB),7,$0
MOVL addrptr+0(FP), BP MOVL addr+0(FP), BP
MOVL val+4(FP), AX MOVL val+4(FP), AX
XCHGL AX, 0(BP) XCHGL AX, 0(BP)
RET RET
...@@ -130,7 +130,7 @@ TEXT ·StoreInt64(SB),7,$0 ...@@ -130,7 +130,7 @@ TEXT ·StoreInt64(SB),7,$0
JMP ·StoreUint64(SB) JMP ·StoreUint64(SB)
TEXT ·StoreUint64(SB),7,$0 TEXT ·StoreUint64(SB),7,$0
MOVL addrptr+0(FP), AX MOVL addr+0(FP), AX
// MOVQ and EMMS were introduced on the Pentium MMX. // MOVQ and EMMS were introduced on the Pentium MMX.
// MOVQ 0x8(%ESP), %MM0 // MOVQ 0x8(%ESP), %MM0
BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08 BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08
......
...@@ -6,7 +6,7 @@ TEXT ·CompareAndSwapInt32(SB),7,$0 ...@@ -6,7 +6,7 @@ TEXT ·CompareAndSwapInt32(SB),7,$0
JMP ·CompareAndSwapUint32(SB) JMP ·CompareAndSwapUint32(SB)
TEXT ·CompareAndSwapUint32(SB),7,$0 TEXT ·CompareAndSwapUint32(SB),7,$0
MOVQ valptr+0(FP), BP MOVQ addr+0(FP), BP
MOVL old+8(FP), AX MOVL old+8(FP), AX
MOVL new+12(FP), CX MOVL new+12(FP), CX
LOCK LOCK
...@@ -24,7 +24,7 @@ TEXT ·CompareAndSwapInt64(SB),7,$0 ...@@ -24,7 +24,7 @@ TEXT ·CompareAndSwapInt64(SB),7,$0
JMP ·CompareAndSwapUint64(SB) JMP ·CompareAndSwapUint64(SB)
TEXT ·CompareAndSwapUint64(SB),7,$0 TEXT ·CompareAndSwapUint64(SB),7,$0
MOVQ valptr+0(FP), BP MOVQ addr+0(FP), BP
MOVQ old+8(FP), AX MOVQ old+8(FP), AX
MOVQ new+16(FP), CX MOVQ new+16(FP), CX
LOCK LOCK
...@@ -36,7 +36,7 @@ TEXT ·AddInt32(SB),7,$0 ...@@ -36,7 +36,7 @@ TEXT ·AddInt32(SB),7,$0
JMP ·AddUint32(SB) JMP ·AddUint32(SB)
TEXT ·AddUint32(SB),7,$0 TEXT ·AddUint32(SB),7,$0
MOVQ valptr+0(FP), BP MOVQ addr+0(FP), BP
MOVL delta+8(FP), AX MOVL delta+8(FP), AX
MOVL AX, CX MOVL AX, CX
LOCK LOCK
...@@ -52,7 +52,7 @@ TEXT ·AddInt64(SB),7,$0 ...@@ -52,7 +52,7 @@ TEXT ·AddInt64(SB),7,$0
JMP ·AddUint64(SB) JMP ·AddUint64(SB)
TEXT ·AddUint64(SB),7,$0 TEXT ·AddUint64(SB),7,$0
MOVQ valptr+0(FP), BP MOVQ addr+0(FP), BP
MOVQ delta+8(FP), AX MOVQ delta+8(FP), AX
MOVQ AX, CX MOVQ AX, CX
LOCK LOCK
...@@ -65,7 +65,7 @@ TEXT ·LoadInt32(SB),7,$0 ...@@ -65,7 +65,7 @@ TEXT ·LoadInt32(SB),7,$0
JMP ·LoadUint32(SB) JMP ·LoadUint32(SB)
TEXT ·LoadUint32(SB),7,$0 TEXT ·LoadUint32(SB),7,$0
MOVQ addrptr+0(FP), AX MOVQ addr+0(FP), AX
MOVL 0(AX), AX MOVL 0(AX), AX
MOVL AX, ret+8(FP) MOVL AX, ret+8(FP)
RET RET
...@@ -74,7 +74,7 @@ TEXT ·LoadInt64(SB),7,$0 ...@@ -74,7 +74,7 @@ TEXT ·LoadInt64(SB),7,$0
JMP ·LoadUint64(SB) JMP ·LoadUint64(SB)
TEXT ·LoadUint64(SB),7,$0 TEXT ·LoadUint64(SB),7,$0
MOVQ addrptr+0(FP), AX MOVQ addr+0(FP), AX
MOVQ 0(AX), AX MOVQ 0(AX), AX
MOVQ AX, ret+8(FP) MOVQ AX, ret+8(FP)
RET RET
...@@ -83,7 +83,7 @@ TEXT ·LoadUintptr(SB),7,$0 ...@@ -83,7 +83,7 @@ TEXT ·LoadUintptr(SB),7,$0
JMP ·LoadPointer(SB) JMP ·LoadPointer(SB)
TEXT ·LoadPointer(SB),7,$0 TEXT ·LoadPointer(SB),7,$0
MOVQ addrptr+0(FP), AX MOVQ addr+0(FP), AX
MOVQ 0(AX), AX MOVQ 0(AX), AX
MOVQ AX, ret+8(FP) MOVQ AX, ret+8(FP)
RET RET
...@@ -92,7 +92,7 @@ TEXT ·StoreInt32(SB),7,$0 ...@@ -92,7 +92,7 @@ TEXT ·StoreInt32(SB),7,$0
JMP ·StoreUint32(SB) JMP ·StoreUint32(SB)
TEXT ·StoreUint32(SB),7,$0 TEXT ·StoreUint32(SB),7,$0
MOVQ addrptr+0(FP), BP MOVQ addr+0(FP), BP
MOVL val+8(FP), AX MOVL val+8(FP), AX
XCHGL AX, 0(BP) XCHGL AX, 0(BP)
RET RET
...@@ -101,7 +101,7 @@ TEXT ·StoreInt64(SB),7,$0 ...@@ -101,7 +101,7 @@ TEXT ·StoreInt64(SB),7,$0
JMP ·StoreUint64(SB) JMP ·StoreUint64(SB)
TEXT ·StoreUint64(SB),7,$0 TEXT ·StoreUint64(SB),7,$0
MOVQ addrptr+0(FP), BP MOVQ addr+0(FP), BP
MOVQ val+8(FP), AX MOVQ val+8(FP), AX
XCHGQ AX, 0(BP) XCHGQ AX, 0(BP)
RET RET
...@@ -110,7 +110,7 @@ TEXT ·StoreUintptr(SB),7,$0 ...@@ -110,7 +110,7 @@ TEXT ·StoreUintptr(SB),7,$0
JMP ·StorePointer(SB) JMP ·StorePointer(SB)
TEXT ·StorePointer(SB),7,$0 TEXT ·StorePointer(SB),7,$0
MOVQ addrptr+0(FP), BP MOVQ addr+0(FP), BP
MOVQ val+8(FP), AX MOVQ val+8(FP), AX
XCHGQ AX, 0(BP) XCHGQ AX, 0(BP)
RET RET
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
// ARM atomic operations, for use by asm_$(GOOS)_arm.s. // ARM atomic operations, for use by asm_$(GOOS)_arm.s.
TEXT ·armCompareAndSwapUint32(SB),7,$0 TEXT ·armCompareAndSwapUint32(SB),7,$0
MOVW valptr+0(FP), R1 MOVW addr+0(FP), R1
MOVW old+4(FP), R2 MOVW old+4(FP), R2
MOVW new+8(FP), R3 MOVW new+8(FP), R3
casloop: casloop:
...@@ -26,7 +26,7 @@ casfail: ...@@ -26,7 +26,7 @@ casfail:
TEXT ·armCompareAndSwapUint64(SB),7,$0 TEXT ·armCompareAndSwapUint64(SB),7,$0
BL fastCheck64<>(SB) BL fastCheck64<>(SB)
MOVW valptr+0(FP), R1 MOVW addr+0(FP), R1
MOVW oldlo+4(FP), R2 MOVW oldlo+4(FP), R2
MOVW oldhi+8(FP), R3 MOVW oldhi+8(FP), R3
MOVW newlo+12(FP), R4 MOVW newlo+12(FP), R4
...@@ -50,7 +50,7 @@ cas64fail: ...@@ -50,7 +50,7 @@ cas64fail:
RET RET
TEXT ·armAddUint32(SB),7,$0 TEXT ·armAddUint32(SB),7,$0
MOVW valptr+0(FP), R1 MOVW addr+0(FP), R1
MOVW delta+4(FP), R2 MOVW delta+4(FP), R2
addloop: addloop:
// LDREX and STREX were introduced in ARM 6. // LDREX and STREX were introduced in ARM 6.
...@@ -64,7 +64,7 @@ addloop: ...@@ -64,7 +64,7 @@ addloop:
TEXT ·armAddUint64(SB),7,$0 TEXT ·armAddUint64(SB),7,$0
BL fastCheck64<>(SB) BL fastCheck64<>(SB)
MOVW valptr+0(FP), R1 MOVW addr+0(FP), R1
MOVW deltalo+4(FP), R2 MOVW deltalo+4(FP), R2
MOVW deltahi+8(FP), R3 MOVW deltahi+8(FP), R3
add64loop: add64loop:
...@@ -81,7 +81,7 @@ add64loop: ...@@ -81,7 +81,7 @@ add64loop:
TEXT ·armLoadUint64(SB),7,$0 TEXT ·armLoadUint64(SB),7,$0
BL fastCheck64<>(SB) BL fastCheck64<>(SB)
MOVW addrptr+0(FP), R1 MOVW addr+0(FP), R1
load64loop: load64loop:
LDREXD (R1), R2 // loads R2 and R3 LDREXD (R1), R2 // loads R2 and R3
STREXD R2, (R1), R0 // stores R2 and R3 STREXD R2, (R1), R0 // stores R2 and R3
...@@ -93,7 +93,7 @@ load64loop: ...@@ -93,7 +93,7 @@ load64loop:
TEXT ·armStoreUint64(SB),7,$0 TEXT ·armStoreUint64(SB),7,$0
BL fastCheck64<>(SB) BL fastCheck64<>(SB)
MOVW addrptr+0(FP), R1 MOVW addr+0(FP), R1
MOVW vallo+4(FP), R2 MOVW vallo+4(FP), R2
MOVW valhi+8(FP), R3 MOVW valhi+8(FP), R3
store64loop: store64loop:
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
// implementation at address 0xffff0fc0. Caller sets: // implementation at address 0xffff0fc0. Caller sets:
// R0 = old value // R0 = old value
// R1 = new value // R1 = new value
// R2 = valptr // R2 = addr
// LR = return address // LR = return address
// The function returns with CS true if the swap happened. // 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 // http://lxr.linux.no/linux+v2.6.37.2/arch/arm/kernel/entry-armv.S#L850
...@@ -27,7 +27,7 @@ TEXT ·CompareAndSwapInt32(SB),7,$0 ...@@ -27,7 +27,7 @@ TEXT ·CompareAndSwapInt32(SB),7,$0
// Implement using kernel cas for portability. // Implement using kernel cas for portability.
TEXT ·CompareAndSwapUint32(SB),7,$0 TEXT ·CompareAndSwapUint32(SB),7,$0
MOVW valptr+0(FP), R2 MOVW addr+0(FP), R2
MOVW old+4(FP), R0 MOVW old+4(FP), R0
casagain: casagain:
MOVW new+8(FP), R1 MOVW new+8(FP), R1
...@@ -39,7 +39,7 @@ casret: ...@@ -39,7 +39,7 @@ casret:
RET RET
cascheck: cascheck:
// Kernel lies; double-check. // Kernel lies; double-check.
MOVW valptr+0(FP), R2 MOVW addr+0(FP), R2
MOVW old+4(FP), R0 MOVW old+4(FP), R0
MOVW 0(R2), R3 MOVW 0(R2), R3
CMP R0, R3 CMP R0, R3
...@@ -58,7 +58,7 @@ TEXT ·AddInt32(SB),7,$0 ...@@ -58,7 +58,7 @@ TEXT ·AddInt32(SB),7,$0
// Implement using kernel cas for portability. // Implement using kernel cas for portability.
TEXT ·AddUint32(SB),7,$0 TEXT ·AddUint32(SB),7,$0
MOVW valptr+0(FP), R2 MOVW addr+0(FP), R2
MOVW delta+4(FP), R4 MOVW delta+4(FP), R4
addloop1: addloop1:
MOVW 0(R2), R0 MOVW 0(R2), R0
...@@ -77,7 +77,7 @@ TEXT cas64<>(SB),7,$0 ...@@ -77,7 +77,7 @@ TEXT cas64<>(SB),7,$0
TEXT kernelCAS64<>(SB),7,$0 TEXT kernelCAS64<>(SB),7,$0
// int (*__kuser_cmpxchg64_t)(const int64_t *oldval, const int64_t *newval, volatile int64_t *ptr); // int (*__kuser_cmpxchg64_t)(const int64_t *oldval, const int64_t *newval, volatile int64_t *ptr);
MOVW valptr+0(FP), R2 // ptr MOVW addr+0(FP), R2 // ptr
MOVW $4(FP), R0 // oldval MOVW $4(FP), R0 // oldval
MOVW $12(FP), R1 // newval MOVW $12(FP), R1 // newval
BL cas64<>(SB) BL cas64<>(SB)
...@@ -88,7 +88,7 @@ TEXT kernelCAS64<>(SB),7,$0 ...@@ -88,7 +88,7 @@ TEXT kernelCAS64<>(SB),7,$0
TEXT generalCAS64<>(SB),7,$20 TEXT generalCAS64<>(SB),7,$20
// bool runtime·cas64(uint64 volatile *addr, uint64 *old, uint64 new) // bool runtime·cas64(uint64 volatile *addr, uint64 *old, uint64 new)
MOVW valptr+0(FP), R0 MOVW addr+0(FP), R0
MOVW R0, 4(R13) MOVW R0, 4(R13)
MOVW $4(FP), R1 // oldval MOVW $4(FP), R1 // oldval
MOVW R1, 8(R13) MOVW R1, 8(R13)
...@@ -140,7 +140,7 @@ TEXT ·LoadInt32(SB),7,$0 ...@@ -140,7 +140,7 @@ TEXT ·LoadInt32(SB),7,$0
B ·LoadUint32(SB) B ·LoadUint32(SB)
TEXT ·LoadUint32(SB),7,$0 TEXT ·LoadUint32(SB),7,$0
MOVW addrptr+0(FP), R2 MOVW addr+0(FP), R2
loadloop1: loadloop1:
MOVW 0(R2), R0 MOVW 0(R2), R0
MOVW R0, R1 MOVW R0, R1
...@@ -165,7 +165,7 @@ TEXT ·StoreInt32(SB),7,$0 ...@@ -165,7 +165,7 @@ TEXT ·StoreInt32(SB),7,$0
B ·StoreUint32(SB) B ·StoreUint32(SB)
TEXT ·StoreUint32(SB),7,$0 TEXT ·StoreUint32(SB),7,$0
MOVW addrptr+0(FP), R2 MOVW addr+0(FP), R2
MOVW val+4(FP), R1 MOVW val+4(FP), R1
storeloop1: storeloop1:
MOVW 0(R2), R0 MOVW 0(R2), R0
......
...@@ -640,73 +640,73 @@ func init() { ...@@ -640,73 +640,73 @@ func init() {
} }
} }
func hammerAddInt32(uval *uint32, count int) { func hammerAddInt32(uaddr *uint32, count int) {
val := (*int32)(unsafe.Pointer(uval)) addr := (*int32)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
AddInt32(val, 1) AddInt32(addr, 1)
} }
} }
func hammerAddUint32(val *uint32, count int) { func hammerAddUint32(addr *uint32, count int) {
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
AddUint32(val, 1) AddUint32(addr, 1)
} }
} }
func hammerAddUintptr32(uval *uint32, count int) { func hammerAddUintptr32(uaddr *uint32, count int) {
// only safe when uintptr is 32-bit. // only safe when uintptr is 32-bit.
// not called on 64-bit systems. // not called on 64-bit systems.
val := (*uintptr)(unsafe.Pointer(uval)) addr := (*uintptr)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
AddUintptr(val, 1) AddUintptr(addr, 1)
} }
} }
func hammerCompareAndSwapInt32(uval *uint32, count int) { func hammerCompareAndSwapInt32(uaddr *uint32, count int) {
val := (*int32)(unsafe.Pointer(uval)) addr := (*int32)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
for { for {
v := *val v := *addr
if CompareAndSwapInt32(val, v, v+1) { if CompareAndSwapInt32(addr, v, v+1) {
break break
} }
} }
} }
} }
func hammerCompareAndSwapUint32(val *uint32, count int) { func hammerCompareAndSwapUint32(addr *uint32, count int) {
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
for { for {
v := *val v := *addr
if CompareAndSwapUint32(val, v, v+1) { if CompareAndSwapUint32(addr, v, v+1) {
break break
} }
} }
} }
} }
func hammerCompareAndSwapUintptr32(uval *uint32, count int) { func hammerCompareAndSwapUintptr32(uaddr *uint32, count int) {
// only safe when uintptr is 32-bit. // only safe when uintptr is 32-bit.
// not called on 64-bit systems. // not called on 64-bit systems.
val := (*uintptr)(unsafe.Pointer(uval)) addr := (*uintptr)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
for { for {
v := *val v := *addr
if CompareAndSwapUintptr(val, v, v+1) { if CompareAndSwapUintptr(addr, v, v+1) {
break break
} }
} }
} }
} }
func hammerCompareAndSwapPointer32(uval *uint32, count int) { func hammerCompareAndSwapPointer32(uaddr *uint32, count int) {
// only safe when uintptr is 32-bit. // only safe when uintptr is 32-bit.
// not called on 64-bit systems. // not called on 64-bit systems.
val := (*unsafe.Pointer)(unsafe.Pointer(uval)) addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
for { for {
v := *val v := *addr
if CompareAndSwapPointer(val, v, unsafe.Pointer(uintptr(v)+1)) { if CompareAndSwapPointer(addr, v, unsafe.Pointer(uintptr(v)+1)) {
break break
} }
} }
...@@ -765,73 +765,73 @@ func init() { ...@@ -765,73 +765,73 @@ func init() {
} }
} }
func hammerAddInt64(uval *uint64, count int) { func hammerAddInt64(uaddr *uint64, count int) {
val := (*int64)(unsafe.Pointer(uval)) addr := (*int64)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
AddInt64(val, 1) AddInt64(addr, 1)
} }
} }
func hammerAddUint64(val *uint64, count int) { func hammerAddUint64(addr *uint64, count int) {
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
AddUint64(val, 1) AddUint64(addr, 1)
} }
} }
func hammerAddUintptr64(uval *uint64, count int) { func hammerAddUintptr64(uaddr *uint64, count int) {
// only safe when uintptr is 64-bit. // only safe when uintptr is 64-bit.
// not called on 32-bit systems. // not called on 32-bit systems.
val := (*uintptr)(unsafe.Pointer(uval)) addr := (*uintptr)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
AddUintptr(val, 1) AddUintptr(addr, 1)
} }
} }
func hammerCompareAndSwapInt64(uval *uint64, count int) { func hammerCompareAndSwapInt64(uaddr *uint64, count int) {
val := (*int64)(unsafe.Pointer(uval)) addr := (*int64)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
for { for {
v := *val v := *addr
if CompareAndSwapInt64(val, v, v+1) { if CompareAndSwapInt64(addr, v, v+1) {
break break
} }
} }
} }
} }
func hammerCompareAndSwapUint64(val *uint64, count int) { func hammerCompareAndSwapUint64(addr *uint64, count int) {
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
for { for {
v := *val v := *addr
if CompareAndSwapUint64(val, v, v+1) { if CompareAndSwapUint64(addr, v, v+1) {
break break
} }
} }
} }
} }
func hammerCompareAndSwapUintptr64(uval *uint64, count int) { func hammerCompareAndSwapUintptr64(uaddr *uint64, count int) {
// only safe when uintptr is 64-bit. // only safe when uintptr is 64-bit.
// not called on 32-bit systems. // not called on 32-bit systems.
val := (*uintptr)(unsafe.Pointer(uval)) addr := (*uintptr)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
for { for {
v := *val v := *addr
if CompareAndSwapUintptr(val, v, v+1) { if CompareAndSwapUintptr(addr, v, v+1) {
break break
} }
} }
} }
} }
func hammerCompareAndSwapPointer64(uval *uint64, count int) { func hammerCompareAndSwapPointer64(uaddr *uint64, count int) {
// only safe when uintptr is 64-bit. // only safe when uintptr is 64-bit.
// not called on 32-bit systems. // not called on 32-bit systems.
val := (*unsafe.Pointer)(unsafe.Pointer(uval)) addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
for { for {
v := *val v := *addr
if CompareAndSwapPointer(val, v, unsafe.Pointer(uintptr(v)+1)) { if CompareAndSwapPointer(addr, v, unsafe.Pointer(uintptr(v)+1)) {
break break
} }
} }
...@@ -871,9 +871,9 @@ func TestHammer64(t *testing.T) { ...@@ -871,9 +871,9 @@ func TestHammer64(t *testing.T) {
} }
} }
func hammerStoreLoadInt32(t *testing.T, valp unsafe.Pointer) { func hammerStoreLoadInt32(t *testing.T, paddr unsafe.Pointer) {
val := (*int32)(valp) addr := (*int32)(paddr)
v := LoadInt32(val) v := LoadInt32(addr)
vlo := v & ((1 << 16) - 1) vlo := v & ((1 << 16) - 1)
vhi := v >> 16 vhi := v >> 16
if vlo != vhi { if vlo != vhi {
...@@ -883,12 +883,12 @@ func hammerStoreLoadInt32(t *testing.T, valp unsafe.Pointer) { ...@@ -883,12 +883,12 @@ func hammerStoreLoadInt32(t *testing.T, valp unsafe.Pointer) {
if vlo == 1e4 { if vlo == 1e4 {
new = 0 new = 0
} }
StoreInt32(val, new) StoreInt32(addr, new)
} }
func hammerStoreLoadUint32(t *testing.T, valp unsafe.Pointer) { func hammerStoreLoadUint32(t *testing.T, paddr unsafe.Pointer) {
val := (*uint32)(valp) addr := (*uint32)(paddr)
v := LoadUint32(val) v := LoadUint32(addr)
vlo := v & ((1 << 16) - 1) vlo := v & ((1 << 16) - 1)
vhi := v >> 16 vhi := v >> 16
if vlo != vhi { if vlo != vhi {
...@@ -898,38 +898,38 @@ func hammerStoreLoadUint32(t *testing.T, valp unsafe.Pointer) { ...@@ -898,38 +898,38 @@ func hammerStoreLoadUint32(t *testing.T, valp unsafe.Pointer) {
if vlo == 1e4 { if vlo == 1e4 {
new = 0 new = 0
} }
StoreUint32(val, new) StoreUint32(addr, new)
} }
func hammerStoreLoadInt64(t *testing.T, valp unsafe.Pointer) { func hammerStoreLoadInt64(t *testing.T, paddr unsafe.Pointer) {
val := (*int64)(valp) addr := (*int64)(paddr)
v := LoadInt64(val) v := LoadInt64(addr)
vlo := v & ((1 << 32) - 1) vlo := v & ((1 << 32) - 1)
vhi := v >> 32 vhi := v >> 32
if vlo != vhi { if vlo != vhi {
t.Fatalf("Int64: %#x != %#x", vlo, vhi) t.Fatalf("Int64: %#x != %#x", vlo, vhi)
} }
new := v + 1 + 1<<32 new := v + 1 + 1<<32
StoreInt64(val, new) StoreInt64(addr, new)
} }
func hammerStoreLoadUint64(t *testing.T, valp unsafe.Pointer) { func hammerStoreLoadUint64(t *testing.T, paddr unsafe.Pointer) {
val := (*uint64)(valp) addr := (*uint64)(paddr)
v := LoadUint64(val) v := LoadUint64(addr)
vlo := v & ((1 << 32) - 1) vlo := v & ((1 << 32) - 1)
vhi := v >> 32 vhi := v >> 32
if vlo != vhi { if vlo != vhi {
t.Fatalf("Uint64: %#x != %#x", vlo, vhi) t.Fatalf("Uint64: %#x != %#x", vlo, vhi)
} }
new := v + 1 + 1<<32 new := v + 1 + 1<<32
StoreUint64(val, new) StoreUint64(addr, new)
} }
func hammerStoreLoadUintptr(t *testing.T, valp unsafe.Pointer) { func hammerStoreLoadUintptr(t *testing.T, paddr unsafe.Pointer) {
val := (*uintptr)(valp) addr := (*uintptr)(paddr)
var test64 uint64 = 1 << 50 var test64 uint64 = 1 << 50
arch32 := uintptr(test64) == 0 arch32 := uintptr(test64) == 0
v := LoadUintptr(val) v := LoadUintptr(addr)
new := v new := v
if arch32 { if arch32 {
vlo := v & ((1 << 16) - 1) vlo := v & ((1 << 16) - 1)
...@@ -950,14 +950,14 @@ func hammerStoreLoadUintptr(t *testing.T, valp unsafe.Pointer) { ...@@ -950,14 +950,14 @@ func hammerStoreLoadUintptr(t *testing.T, valp unsafe.Pointer) {
inc := uint64(1 + 1<<32) inc := uint64(1 + 1<<32)
new = v + uintptr(inc) new = v + uintptr(inc)
} }
StoreUintptr(val, new) StoreUintptr(addr, new)
} }
func hammerStoreLoadPointer(t *testing.T, valp unsafe.Pointer) { func hammerStoreLoadPointer(t *testing.T, paddr unsafe.Pointer) {
val := (*unsafe.Pointer)(valp) addr := (*unsafe.Pointer)(paddr)
var test64 uint64 = 1 << 50 var test64 uint64 = 1 << 50
arch32 := uintptr(test64) == 0 arch32 := uintptr(test64) == 0
v := uintptr(LoadPointer(val)) v := uintptr(LoadPointer(addr))
new := v new := v
if arch32 { if arch32 {
vlo := v & ((1 << 16) - 1) vlo := v & ((1 << 16) - 1)
...@@ -978,7 +978,7 @@ func hammerStoreLoadPointer(t *testing.T, valp unsafe.Pointer) { ...@@ -978,7 +978,7 @@ func hammerStoreLoadPointer(t *testing.T, valp unsafe.Pointer) {
inc := uint64(1 + 1<<32) inc := uint64(1 + 1<<32)
new = v + uintptr(inc) new = v + uintptr(inc)
} }
StorePointer(val, unsafe.Pointer(new)) StorePointer(addr, unsafe.Pointer(new))
} }
func TestHammerStoreLoad(t *testing.T) { func TestHammerStoreLoad(t *testing.T) {
......
...@@ -14,12 +14,22 @@ ...@@ -14,12 +14,22 @@
// The compare-and-swap operation, implemented by the CompareAndSwapT // The compare-and-swap operation, implemented by the CompareAndSwapT
// functions, is the atomic equivalent of: // functions, is the atomic equivalent of:
// //
// if *val == old { // if *addr == old {
// *val = new // *addr = new
// return true // return true
// } // }
// return false // 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 package atomic
import ( import (
...@@ -31,37 +41,37 @@ import ( ...@@ -31,37 +41,37 @@ import (
// On x86-32, the 64-bit functions use instructions unavailable before the Pentium MMX. // On x86-32, the 64-bit functions use instructions unavailable before the Pentium MMX.
// CompareAndSwapInt32 executes the compare-and-swap operation for an int32 value. // CompareAndSwapInt32 executes the compare-and-swap operation for an int32 value.
func CompareAndSwapInt32(val *int32, old, new int32) (swapped bool) func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
// CompareAndSwapInt64 executes the compare-and-swap operation for an int64 value. // CompareAndSwapInt64 executes the compare-and-swap operation for an int64 value.
func CompareAndSwapInt64(val *int64, old, new int64) (swapped bool) func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)
// CompareAndSwapUint32 executes the compare-and-swap operation for a uint32 value. // CompareAndSwapUint32 executes the compare-and-swap operation for a uint32 value.
func CompareAndSwapUint32(val *uint32, old, new uint32) (swapped bool) func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
// CompareAndSwapUint64 executes the compare-and-swap operation for a uint64 value. // CompareAndSwapUint64 executes the compare-and-swap operation for a uint64 value.
func CompareAndSwapUint64(val *uint64, old, new uint64) (swapped bool) func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)
// CompareAndSwapUintptr executes the compare-and-swap operation for a uintptr value. // CompareAndSwapUintptr executes the compare-and-swap operation for a uintptr value.
func CompareAndSwapUintptr(val *uintptr, old, new uintptr) (swapped bool) func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool)
// CompareAndSwapPointer executes the compare-and-swap operation for a unsafe.Pointer value. // CompareAndSwapPointer executes the compare-and-swap operation for a unsafe.Pointer value.
func CompareAndSwapPointer(val *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool) func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool)
// AddInt32 atomically adds delta to *val and returns the new value. // AddInt32 atomically adds delta to *addr and returns the new value.
func AddInt32(val *int32, delta int32) (new int32) func AddInt32(addr *int32, delta int32) (new int32)
// AddUint32 atomically adds delta to *val and returns the new value. // AddUint32 atomically adds delta to *addr and returns the new value.
func AddUint32(val *uint32, delta uint32) (new uint32) func AddUint32(addr *uint32, delta uint32) (new uint32)
// AddInt64 atomically adds delta to *val and returns the new value. // AddInt64 atomically adds delta to *addr and returns the new value.
func AddInt64(val *int64, delta int64) (new int64) func AddInt64(addr *int64, delta int64) (new int64)
// AddUint64 atomically adds delta to *val and returns the new value. // AddUint64 atomically adds delta to *addr and returns the new value.
func AddUint64(val *uint64, delta uint64) (new uint64) func AddUint64(addr *uint64, delta uint64) (new uint64)
// AddUintptr atomically adds delta to *val and returns the new value. // AddUintptr atomically adds delta to *addr and returns the new value.
func AddUintptr(val *uintptr, delta uintptr) (new uintptr) func AddUintptr(addr *uintptr, delta uintptr) (new uintptr)
// LoadInt32 atomically loads *addr. // LoadInt32 atomically loads *addr.
func LoadInt32(addr *int32) (val int32) func LoadInt32(addr *int32) (val int32)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment