diff options
Diffstat (limited to 'src/runtime/atomic_pointer.go')
| -rw-r--r-- | src/runtime/atomic_pointer.go | 23 |
1 files changed, 10 insertions, 13 deletions
diff --git a/src/runtime/atomic_pointer.go b/src/runtime/atomic_pointer.go index 4fe334014d..292b3517ad 100644 --- a/src/runtime/atomic_pointer.go +++ b/src/runtime/atomic_pointer.go @@ -20,17 +20,17 @@ import ( // //go:nosplit func atomicstorep(ptr unsafe.Pointer, new unsafe.Pointer) { + writebarrierptr_prewrite((*uintptr)(ptr), uintptr(new)) atomic.StorepNoWB(noescape(ptr), new) - writebarrierptr_nostore((*uintptr)(ptr), uintptr(new)) } //go:nosplit func casp(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool { - if !atomic.Casp1((*unsafe.Pointer)(noescape(unsafe.Pointer(ptr))), noescape(old), new) { - return false - } - writebarrierptr_nostore((*uintptr)(unsafe.Pointer(ptr)), uintptr(new)) - return true + // The write barrier is only necessary if the CAS succeeds, + // but since it needs to happen before the write becomes + // public, we have to do it conservatively all the time. + writebarrierptr_prewrite((*uintptr)(unsafe.Pointer(ptr)), uintptr(new)) + return atomic.Casp1((*unsafe.Pointer)(noescape(unsafe.Pointer(ptr))), noescape(old), new) } // Like above, but implement in terms of sync/atomic's uintptr operations. @@ -43,8 +43,8 @@ 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) { + writebarrierptr_prewrite((*uintptr)(unsafe.Pointer(ptr)), uintptr(new)) sync_atomic_StoreUintptr((*uintptr)(unsafe.Pointer(ptr)), uintptr(new)) - writebarrierptr_nostore((*uintptr)(unsafe.Pointer(ptr)), uintptr(new)) } //go:linkname sync_atomic_SwapUintptr sync/atomic.SwapUintptr @@ -53,8 +53,8 @@ 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 { + writebarrierptr_prewrite((*uintptr)(unsafe.Pointer(ptr)), uintptr(new)) old := unsafe.Pointer(sync_atomic_SwapUintptr((*uintptr)(noescape(unsafe.Pointer(ptr))), uintptr(new))) - writebarrierptr_nostore((*uintptr)(unsafe.Pointer(ptr)), uintptr(new)) return old } @@ -64,9 +64,6 @@ 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)) - return true + writebarrierptr_prewrite((*uintptr)(unsafe.Pointer(ptr)), uintptr(new)) + return sync_atomic_CompareAndSwapUintptr((*uintptr)(noescape(unsafe.Pointer(ptr))), uintptr(old), uintptr(new)) } |
