1
0
mirror of https://github.com/golang/go synced 2024-11-23 08:00:05 -07:00

runtime, sync/atomic: add write barrier for atomic write of pointer

Add write barrier to atomic operations manipulating pointers.

In general an atomic write of a pointer word may indicate racy accesses,
so there is no strictly safe way to attempt to keep the shadow copy
in sync with the real one. Instead, mark the shadow copy as not used.

Redirect sync/atomic pointer routines back to the runtime ones,
so that there is only one copy of the write barrier and shadow logic.
In time we might consider doing this for most of the sync/atomic
functions, but for now only the pointer routines need that treatment.

Found with GODEBUG=wbshadow=1 mode.
Eventually that will run automatically, but right now
it still detects other missing write barriers.

Change-Id: I852936b9a111a6cb9079cfaf6bd78b43016c0242
Reviewed-on: https://go-review.googlesource.com/2066
Reviewed-by: Rick Hudson <rlh@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
Russ Cox 2014-12-22 22:50:42 -05:00
parent eafc482d4f
commit 7b4df8f018
15 changed files with 109 additions and 171 deletions

View File

@ -48,18 +48,7 @@ func xadd(ptr *uint32, delta int32) uint32
//go:noescape //go:noescape
func xchg(ptr *uint32, new uint32) uint32 func xchg(ptr *uint32, new uint32) uint32
// xchgp cannot have a go:noescape annotation, because // NO go:noescape annotation; see atomic_pointer.go.
// while ptr does not escape, new does. If new is marked as
// not escaping, the compiler will make incorrect escape analysis
// decisions about the value being xchg'ed.
// Instead, make xchgp a wrapper around the actual atomic.
// When calling the wrapper we mark ptr as noescape explicitly.
//go:nosplit
func xchgp(ptr unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer {
return xchgp1(noescape(ptr), new)
}
func xchgp1(ptr unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer func xchgp1(ptr unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer
//go:noescape //go:noescape
@ -80,12 +69,5 @@ func atomicstore(ptr *uint32, val uint32)
//go:noescape //go:noescape
func atomicstore64(ptr *uint64, val uint64) func atomicstore64(ptr *uint64, val uint64)
// atomicstorep cannot have a go:noescape annotation. // NO go:noescape annotation; see atomic_pointer.go.
// See comment above for xchgp.
//go:nosplit
func atomicstorep(ptr unsafe.Pointer, new unsafe.Pointer) {
atomicstorep1(noescape(ptr), new)
}
func atomicstorep1(ptr unsafe.Pointer, val unsafe.Pointer) func atomicstorep1(ptr unsafe.Pointer, val unsafe.Pointer)

View File

@ -42,18 +42,7 @@ func xchg(ptr *uint32, new uint32) uint32
//go:noescape //go:noescape
func xchg64(ptr *uint64, new uint64) uint64 func xchg64(ptr *uint64, new uint64) uint64
// xchgp cannot have a go:noescape annotation, because // NO go:noescape annotation; see atomic_pointer.go.
// while ptr does not escape, new does. If new is marked as
// not escaping, the compiler will make incorrect escape analysis
// decisions about the value being xchg'ed.
// Instead, make xchgp a wrapper around the actual atomic.
// When calling the wrapper we mark ptr as noescape explicitly.
//go:nosplit
func xchgp(ptr unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer {
return xchgp1(noescape(ptr), new)
}
func xchgp1(ptr unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer func xchgp1(ptr unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer
//go:noescape //go:noescape
@ -71,12 +60,5 @@ func atomicstore(ptr *uint32, val uint32)
//go:noescape //go:noescape
func atomicstore64(ptr *uint64, val uint64) func atomicstore64(ptr *uint64, val uint64)
// atomicstorep cannot have a go:noescape annotation. // NO go:noescape annotation; see atomic_pointer.go.
// See comment above for xchgp.
//go:nosplit
func atomicstorep(ptr unsafe.Pointer, new unsafe.Pointer) {
atomicstorep1(noescape(ptr), new)
}
func atomicstorep1(ptr unsafe.Pointer, val unsafe.Pointer) func atomicstorep1(ptr unsafe.Pointer, val unsafe.Pointer)

View File

@ -38,10 +38,10 @@ func xchg(addr *uint32, v uint32) uint32 {
} }
//go:nosplit //go:nosplit
func xchgp(addr *unsafe.Pointer, v unsafe.Pointer) unsafe.Pointer { func xchgp1(addr *unsafe.Pointer, v unsafe.Pointer) unsafe.Pointer {
for { for {
old := *addr old := *addr
if casp(addr, old, v) { if casp1(addr, old, v) {
return old return old
} }
} }
@ -63,10 +63,10 @@ func atomicloadp(addr unsafe.Pointer) unsafe.Pointer {
} }
//go:nosplit //go:nosplit
func atomicstorep(addr unsafe.Pointer, v unsafe.Pointer) { func atomicstorep1(addr unsafe.Pointer, v unsafe.Pointer) {
for { for {
old := *(*unsafe.Pointer)(addr) old := *(*unsafe.Pointer)(addr)
if casp((*unsafe.Pointer)(addr), old, v) { if casp1((*unsafe.Pointer)(addr), old, v) {
return return
} }
} }

View File

@ -0,0 +1,96 @@
// Copyright 2009 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 runtime
import "unsafe"
// These functions cannot have go:noescape annotations,
// because while ptr does not escape, new does.
// If new is marked as not escaping, the compiler will make incorrect
// escape analysis decisions about the pointer value being stored.
// Instead, these are wrappers around the actual atomics (xchgp1 and so on)
// that use noescape to convey which arguments do not escape.
//
// Additionally, these functions must update the shadow heap for
// write barrier checking.
//go:nosplit
func atomicstorep(ptr unsafe.Pointer, new unsafe.Pointer) {
atomicstorep1(noescape(ptr), new)
writebarrierptr_nostore((*uintptr)(ptr), uintptr(new))
if mheap_.shadow_enabled {
writebarrierptr_noshadow((*uintptr)(noescape(ptr)))
}
}
//go:nosplit
func xchgp(ptr unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer {
old := xchgp1(noescape(ptr), new)
writebarrierptr_nostore((*uintptr)(ptr), uintptr(new))
if mheap_.shadow_enabled {
writebarrierptr_noshadow((*uintptr)(noescape(ptr)))
}
return old
}
//go:nosplit
func casp(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool {
if !casp1((*unsafe.Pointer)(noescape(unsafe.Pointer(ptr))), noescape(old), new) {
return false
}
writebarrierptr_nostore((*uintptr)(unsafe.Pointer(ptr)), uintptr(new))
if mheap_.shadow_enabled {
writebarrierptr_noshadow((*uintptr)(noescape(unsafe.Pointer(ptr))))
}
return true
}
// Like above, but implement in terms of sync/atomic's uintptr operations.
// We cannot just call the runtime routines, because the race detector expects
// to be able to intercept the sync/atomic forms but not the runtime forms.
//go:linkname sync_atomic_StoreUintptr sync/atomic.StoreUintptr
func sync_atomic_StoreUintptr(ptr *uintptr, new uintptr)
//go:linkname sync_atomic_StorePointer sync/atomic.StorePointer
//go:nosplit
func sync_atomic_StorePointer(ptr *unsafe.Pointer, new unsafe.Pointer) {
sync_atomic_StoreUintptr((*uintptr)(unsafe.Pointer(ptr)), uintptr(new))
atomicstorep1(noescape(unsafe.Pointer(ptr)), new)
writebarrierptr_nostore((*uintptr)(unsafe.Pointer(ptr)), uintptr(new))
if mheap_.shadow_enabled {
writebarrierptr_noshadow((*uintptr)(noescape(unsafe.Pointer(ptr))))
}
}
//go:linkname sync_atomic_SwapUintptr sync/atomic.SwapUintptr
func sync_atomic_SwapUintptr(ptr *uintptr, new uintptr) uintptr
//go:linkname sync_atomic_SwapPointer sync/atomic.SwapPointer
//go:nosplit
func sync_atomic_SwapPointer(ptr unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer {
old := unsafe.Pointer(sync_atomic_SwapUintptr((*uintptr)(noescape(ptr)), uintptr(new)))
writebarrierptr_nostore((*uintptr)(ptr), uintptr(new))
if mheap_.shadow_enabled {
writebarrierptr_noshadow((*uintptr)(noescape(ptr)))
}
return old
}
//go:linkname sync_atomic_CompareAndSwapUintptr sync/atomic.CompareAndSwapUintptr
func sync_atomic_CompareAndSwapUintptr(ptr *uintptr, old, new uintptr) bool
//go:linkname sync_atomic_CompareAndSwapPointer sync/atomic.CompareAndSwapPointer
//go:nosplit
func sync_atomic_CompareAndSwapPointer(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool {
if !sync_atomic_CompareAndSwapUintptr((*uintptr)(noescape(unsafe.Pointer(ptr))), uintptr(old), uintptr(new)) {
return false
}
writebarrierptr_nostore((*uintptr)(unsafe.Pointer(ptr)), uintptr(new))
if mheap_.shadow_enabled {
writebarrierptr_noshadow((*uintptr)(noescape(unsafe.Pointer(ptr))))
}
return true
}

View File

@ -20,18 +20,7 @@ func xchg(ptr *uint32, new uint32) uint32
//go:noescape //go:noescape
func xchg64(ptr *uint64, new uint64) uint64 func xchg64(ptr *uint64, new uint64) uint64
// xchgp cannot have a go:noescape annotation, because // NO go:noescape annotation; see atomic_pointer.go.
// while ptr does not escape, new does. If new is marked as
// not escaping, the compiler will make incorrect escape analysis
// decisions about the value being xchg'ed.
// Instead, make xchgp a wrapper around the actual atomic.
// When calling the wrapper we mark ptr as noescape explicitly.
//go:nosplit
func xchgp(ptr unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer {
return xchgp1(noescape(ptr), new)
}
func xchgp1(ptr unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer func xchgp1(ptr unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer
//go:noescape //go:noescape
@ -58,12 +47,5 @@ func atomicstore(ptr *uint32, val uint32)
//go:noescape //go:noescape
func atomicstore64(ptr *uint64, val uint64) func atomicstore64(ptr *uint64, val uint64)
// atomicstorep cannot have a go:noescape annotation. // NO go:noescape annotation; see atomic_pointer.go.
// See comment above for xchgp.
//go:nosplit
func atomicstorep(ptr unsafe.Pointer, new unsafe.Pointer) {
atomicstorep1(noescape(ptr), new)
}
func atomicstorep1(ptr unsafe.Pointer, val unsafe.Pointer) func atomicstorep1(ptr unsafe.Pointer, val unsafe.Pointer)

View File

@ -202,9 +202,6 @@ TEXT syncatomic·LoadUint64(SB), NOSPLIT, $0-0
TEXT syncatomic·LoadUintptr(SB), NOSPLIT, $0-0 TEXT syncatomic·LoadUintptr(SB), NOSPLIT, $0-0
JMP syncatomic·LoadInt64(SB) JMP syncatomic·LoadInt64(SB)
TEXT syncatomic·LoadPointer(SB), NOSPLIT, $0-0
JMP syncatomic·LoadInt64(SB)
// Store // Store
TEXT syncatomic·StoreInt32(SB), NOSPLIT, $0-0 TEXT syncatomic·StoreInt32(SB), NOSPLIT, $0-0
MOVQ $__tsan_go_atomic32_store(SB), AX MOVQ $__tsan_go_atomic32_store(SB), AX
@ -225,9 +222,6 @@ TEXT syncatomic·StoreUint64(SB), NOSPLIT, $0-0
TEXT syncatomic·StoreUintptr(SB), NOSPLIT, $0-0 TEXT syncatomic·StoreUintptr(SB), NOSPLIT, $0-0
JMP syncatomic·StoreInt64(SB) JMP syncatomic·StoreInt64(SB)
TEXT syncatomic·StorePointer(SB), NOSPLIT, $0-0
JMP syncatomic·StoreInt64(SB)
// Swap // Swap
TEXT syncatomic·SwapInt32(SB), NOSPLIT, $0-0 TEXT syncatomic·SwapInt32(SB), NOSPLIT, $0-0
MOVQ $__tsan_go_atomic32_exchange(SB), AX MOVQ $__tsan_go_atomic32_exchange(SB), AX
@ -248,9 +242,6 @@ TEXT syncatomic·SwapUint64(SB), NOSPLIT, $0-0
TEXT syncatomic·SwapUintptr(SB), NOSPLIT, $0-0 TEXT syncatomic·SwapUintptr(SB), NOSPLIT, $0-0
JMP syncatomic·SwapInt64(SB) JMP syncatomic·SwapInt64(SB)
TEXT syncatomic·SwapPointer(SB), NOSPLIT, $0-0
JMP syncatomic·SwapInt64(SB)
// Add // Add
TEXT syncatomic·AddInt32(SB), NOSPLIT, $0-0 TEXT syncatomic·AddInt32(SB), NOSPLIT, $0-0
MOVQ $__tsan_go_atomic32_fetch_add(SB), AX MOVQ $__tsan_go_atomic32_fetch_add(SB), AX
@ -275,9 +266,6 @@ TEXT syncatomic·AddUint64(SB), NOSPLIT, $0-0
TEXT syncatomic·AddUintptr(SB), NOSPLIT, $0-0 TEXT syncatomic·AddUintptr(SB), NOSPLIT, $0-0
JMP syncatomic·AddInt64(SB) JMP syncatomic·AddInt64(SB)
TEXT syncatomic·AddPointer(SB), NOSPLIT, $0-0
JMP syncatomic·AddInt64(SB)
// CompareAndSwap // CompareAndSwap
TEXT syncatomic·CompareAndSwapInt32(SB), NOSPLIT, $0-0 TEXT syncatomic·CompareAndSwapInt32(SB), NOSPLIT, $0-0
MOVQ $__tsan_go_atomic32_compare_exchange(SB), AX MOVQ $__tsan_go_atomic32_compare_exchange(SB), AX
@ -298,9 +286,6 @@ TEXT syncatomic·CompareAndSwapUint64(SB), NOSPLIT, $0-0
TEXT syncatomic·CompareAndSwapUintptr(SB), NOSPLIT, $0-0 TEXT syncatomic·CompareAndSwapUintptr(SB), NOSPLIT, $0-0
JMP syncatomic·CompareAndSwapInt64(SB) JMP syncatomic·CompareAndSwapInt64(SB)
TEXT syncatomic·CompareAndSwapPointer(SB), NOSPLIT, $0-0
JMP syncatomic·CompareAndSwapInt64(SB)
// Generic atomic operation implementation. // Generic atomic operation implementation.
// AX already contains target function. // AX already contains target function.
TEXT racecallatomic<>(SB), NOSPLIT, $0-0 TEXT racecallatomic<>(SB), NOSPLIT, $0-0

View File

@ -118,18 +118,7 @@ func goexit()
//go:noescape //go:noescape
func cas(ptr *uint32, old, new uint32) bool func cas(ptr *uint32, old, new uint32) bool
// casp cannot have a go:noescape annotation, because // NO go:noescape annotation; see atomic_pointer.go.
// while ptr and old do not escape, new does. If new is marked as
// not escaping, the compiler will make incorrect escape analysis
// decisions about the value being xchg'ed.
// Instead, make casp a wrapper around the actual atomic.
// When calling the wrapper we mark ptr as noescape explicitly.
//go:nosplit
func casp(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool {
return casp1((*unsafe.Pointer)(noescape(unsafe.Pointer(ptr))), noescape(old), new)
}
func casp1(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool func casp1(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool
func nop() // call to prevent inlining of function body func nop() // call to prevent inlining of function body

View File

@ -50,9 +50,6 @@ swaploop:
TEXT ·SwapUintptr(SB),NOSPLIT,$0-12 TEXT ·SwapUintptr(SB),NOSPLIT,$0-12
JMP ·SwapUint32(SB) JMP ·SwapUint32(SB)
TEXT ·SwapPointer(SB),NOSPLIT,$0-12
JMP ·SwapUint32(SB)
TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-13 TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-13
JMP ·CompareAndSwapUint32(SB) JMP ·CompareAndSwapUint32(SB)
@ -69,9 +66,6 @@ TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-13
TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-13 TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-13
JMP ·CompareAndSwapUint32(SB) JMP ·CompareAndSwapUint32(SB)
TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0-13
JMP ·CompareAndSwapUint32(SB)
TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-21 TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-21
JMP ·CompareAndSwapUint64(SB) JMP ·CompareAndSwapUint64(SB)
@ -209,6 +203,3 @@ TEXT ·StoreUint64(SB),NOSPLIT,$0-12
TEXT ·StoreUintptr(SB),NOSPLIT,$0-8 TEXT ·StoreUintptr(SB),NOSPLIT,$0-8
JMP ·StoreUint32(SB) JMP ·StoreUint32(SB)
TEXT ·StorePointer(SB),NOSPLIT,$0-8
JMP ·StoreUint32(SB)

View File

@ -29,9 +29,6 @@ TEXT ·SwapUint64(SB),NOSPLIT,$0-24
TEXT ·SwapUintptr(SB),NOSPLIT,$0-24 TEXT ·SwapUintptr(SB),NOSPLIT,$0-24
JMP ·SwapUint64(SB) JMP ·SwapUint64(SB)
TEXT ·SwapPointer(SB),NOSPLIT,$0-24
JMP ·SwapUint64(SB)
TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-17 TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-17
JMP ·CompareAndSwapUint32(SB) JMP ·CompareAndSwapUint32(SB)
@ -47,9 +44,6 @@ TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-17
TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-25 TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-25
JMP ·CompareAndSwapUint64(SB) JMP ·CompareAndSwapUint64(SB)
TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0-25
JMP ·CompareAndSwapUint64(SB)
TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-25 TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-25
JMP ·CompareAndSwapUint64(SB) JMP ·CompareAndSwapUint64(SB)
@ -137,10 +131,4 @@ TEXT ·StoreUint64(SB),NOSPLIT,$0-16
RET RET
TEXT ·StoreUintptr(SB),NOSPLIT,$0-16 TEXT ·StoreUintptr(SB),NOSPLIT,$0-16
JMP ·StorePointer(SB) JMP ·StoreUint64(SB)
TEXT ·StorePointer(SB),NOSPLIT,$0-16
MOVQ addr+0(FP), BP
MOVQ val+8(FP), AX
XCHGQ AX, 0(BP)
RET

View File

@ -30,9 +30,6 @@ TEXT ·SwapUint64(SB),NOSPLIT,$0-24
TEXT ·SwapUintptr(SB),NOSPLIT,$0-12 TEXT ·SwapUintptr(SB),NOSPLIT,$0-12
JMP ·SwapUint32(SB) JMP ·SwapUint32(SB)
TEXT ·SwapPointer(SB),NOSPLIT,$0-12
JMP ·SwapUint32(SB)
TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-17 TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-17
JMP ·CompareAndSwapUint32(SB) JMP ·CompareAndSwapUint32(SB)
@ -48,9 +45,6 @@ TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-17
TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-17 TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-17
JMP ·CompareAndSwapUint32(SB) JMP ·CompareAndSwapUint32(SB)
TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0-17
JMP ·CompareAndSwapUint32(SB)
TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-25 TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-25
JMP ·CompareAndSwapUint64(SB) JMP ·CompareAndSwapUint64(SB)
@ -150,10 +144,4 @@ TEXT ·StoreUint64(SB),NOSPLIT,$0-16
RET RET
TEXT ·StoreUintptr(SB),NOSPLIT,$0-8 TEXT ·StoreUintptr(SB),NOSPLIT,$0-8
JMP ·StorePointer(SB) JMP ·StoreUint32(SB)
TEXT ·StorePointer(SB),NOSPLIT,$0-8
MOVL addr+0(FP), BX
MOVL val+4(FP), AX
XCHGL AX, 0(BX)
RET

View File

@ -16,9 +16,6 @@ TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0
TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0 TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0
B ·CompareAndSwapUint32(SB) B ·CompareAndSwapUint32(SB)
TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0
B ·CompareAndSwapUint32(SB)
TEXT ·AddInt32(SB),NOSPLIT,$0 TEXT ·AddInt32(SB),NOSPLIT,$0
B ·AddUint32(SB) B ·AddUint32(SB)
@ -37,9 +34,6 @@ TEXT ·SwapUint32(SB),NOSPLIT,$0
TEXT ·SwapUintptr(SB),NOSPLIT,$0 TEXT ·SwapUintptr(SB),NOSPLIT,$0
B ·SwapUint32(SB) B ·SwapUint32(SB)
TEXT ·SwapPointer(SB),NOSPLIT,$0
B ·SwapUint32(SB)
TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0 TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0
B ·CompareAndSwapUint64(SB) B ·CompareAndSwapUint64(SB)
@ -104,6 +98,3 @@ TEXT ·StoreUint64(SB),NOSPLIT,$0
TEXT ·StoreUintptr(SB),NOSPLIT,$0 TEXT ·StoreUintptr(SB),NOSPLIT,$0
B ·StoreUint32(SB) B ·StoreUint32(SB)
TEXT ·StorePointer(SB),NOSPLIT,$0
B ·StoreUint32(SB)

View File

@ -57,9 +57,6 @@ cascheck:
TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0 TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0
B ·CompareAndSwapUint32(SB) B ·CompareAndSwapUint32(SB)
TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0
B ·CompareAndSwapUint32(SB)
TEXT ·AddInt32(SB),NOSPLIT,$0 TEXT ·AddInt32(SB),NOSPLIT,$0
B ·AddUint32(SB) B ·AddUint32(SB)
@ -97,9 +94,6 @@ swaploop1:
TEXT ·SwapUintptr(SB),NOSPLIT,$0 TEXT ·SwapUintptr(SB),NOSPLIT,$0
B ·SwapUint32(SB) B ·SwapUint32(SB)
TEXT ·SwapPointer(SB),NOSPLIT,$0
B ·SwapUint32(SB)
TEXT cas64<>(SB),NOSPLIT,$0 TEXT cas64<>(SB),NOSPLIT,$0
MOVW $0xffff0f60, PC // __kuser_cmpxchg64: Linux-3.1 and above MOVW $0xffff0f60, PC // __kuser_cmpxchg64: Linux-3.1 and above
@ -211,6 +205,3 @@ TEXT ·StoreUint64(SB),NOSPLIT,$0
TEXT ·StoreUintptr(SB),NOSPLIT,$0 TEXT ·StoreUintptr(SB),NOSPLIT,$0
B ·StoreUint32(SB) B ·StoreUint32(SB)
TEXT ·StorePointer(SB),NOSPLIT,$0
B ·StoreUint32(SB)

View File

@ -16,9 +16,6 @@ TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0
TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0 TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0
B ·CompareAndSwapUint32(SB) B ·CompareAndSwapUint32(SB)
TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0
B ·CompareAndSwapUint32(SB)
TEXT ·AddInt32(SB),NOSPLIT,$0 TEXT ·AddInt32(SB),NOSPLIT,$0
B ·AddUint32(SB) B ·AddUint32(SB)
@ -37,9 +34,6 @@ TEXT ·SwapUint32(SB),NOSPLIT,$0
TEXT ·SwapUintptr(SB),NOSPLIT,$0 TEXT ·SwapUintptr(SB),NOSPLIT,$0
B ·SwapUint32(SB) B ·SwapUint32(SB)
TEXT ·SwapPointer(SB),NOSPLIT,$0
B ·SwapUint32(SB)
TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0 TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0
B ·CompareAndSwapUint64(SB) B ·CompareAndSwapUint64(SB)
@ -104,6 +98,3 @@ TEXT ·StoreUint64(SB),NOSPLIT,$0
TEXT ·StoreUintptr(SB),NOSPLIT,$0 TEXT ·StoreUintptr(SB),NOSPLIT,$0
B ·StoreUint32(SB) B ·StoreUint32(SB)
TEXT ·StorePointer(SB),NOSPLIT,$0
B ·StoreUint32(SB)

View File

@ -16,9 +16,6 @@ TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0
TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0 TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0
B ·CompareAndSwapUint32(SB) B ·CompareAndSwapUint32(SB)
TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0
B ·CompareAndSwapUint32(SB)
TEXT ·AddInt32(SB),NOSPLIT,$0 TEXT ·AddInt32(SB),NOSPLIT,$0
B ·AddUint32(SB) B ·AddUint32(SB)
@ -37,9 +34,6 @@ TEXT ·SwapUint32(SB),NOSPLIT,$0
TEXT ·SwapUintptr(SB),NOSPLIT,$0 TEXT ·SwapUintptr(SB),NOSPLIT,$0
B ·SwapUint32(SB) B ·SwapUint32(SB)
TEXT ·SwapPointer(SB),NOSPLIT,$0
B ·SwapUint32(SB)
TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0 TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0
B ·CompareAndSwapUint64(SB) B ·CompareAndSwapUint64(SB)
@ -104,6 +98,3 @@ TEXT ·StoreUint64(SB),NOSPLIT,$0
TEXT ·StoreUintptr(SB),NOSPLIT,$0 TEXT ·StoreUintptr(SB),NOSPLIT,$0
B ·StoreUint32(SB) B ·StoreUint32(SB)
TEXT ·StorePointer(SB),NOSPLIT,$0
B ·StoreUint32(SB)

View File

@ -39,9 +39,6 @@ TEXT ·SwapUint64(SB),NOSPLIT,$0-24
TEXT ·SwapUintptr(SB),NOSPLIT,$0-24 TEXT ·SwapUintptr(SB),NOSPLIT,$0-24
BR ·SwapUint64(SB) BR ·SwapUint64(SB)
TEXT ·SwapPointer(SB),NOSPLIT,$0-24
BR ·SwapUint64(SB)
TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-17 TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-17
BR ·CompareAndSwapUint32(SB) BR ·CompareAndSwapUint32(SB)
@ -66,9 +63,6 @@ TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-17
TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-25 TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-25
BR ·CompareAndSwapUint64(SB) BR ·CompareAndSwapUint64(SB)
TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0-25
BR ·CompareAndSwapUint64(SB)
TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-25 TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-25
BR ·CompareAndSwapUint64(SB) BR ·CompareAndSwapUint64(SB)
@ -178,7 +172,4 @@ TEXT ·StoreUint64(SB),NOSPLIT,$0-16
RETURN RETURN
TEXT ·StoreUintptr(SB),NOSPLIT,$0-16 TEXT ·StoreUintptr(SB),NOSPLIT,$0-16
BR ·StorePointer(SB)
TEXT ·StorePointer(SB),NOSPLIT,$0-16
BR ·StoreUint64(SB) BR ·StoreUint64(SB)