rsc.io/go@v0.0.0-20150416155037-e040fd465409/src/runtime/atomic_pointer.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package runtime 6 7 import "unsafe" 8 9 // These functions cannot have go:noescape annotations, 10 // because while ptr does not escape, new does. 11 // If new is marked as not escaping, the compiler will make incorrect 12 // escape analysis decisions about the pointer value being stored. 13 // Instead, these are wrappers around the actual atomics (xchgp1 and so on) 14 // that use noescape to convey which arguments do not escape. 15 // 16 // Additionally, these functions must update the shadow heap for 17 // write barrier checking. 18 19 //go:nosplit 20 func atomicstorep(ptr unsafe.Pointer, new unsafe.Pointer) { 21 atomicstorep1(noescape(ptr), new) 22 writebarrierptr_nostore((*uintptr)(ptr), uintptr(new)) 23 if mheap_.shadow_enabled { 24 writebarrierptr_noshadow((*uintptr)(noescape(ptr))) 25 } 26 } 27 28 //go:nosplit 29 func xchgp(ptr unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer { 30 old := xchgp1(noescape(ptr), new) 31 writebarrierptr_nostore((*uintptr)(ptr), uintptr(new)) 32 if mheap_.shadow_enabled { 33 writebarrierptr_noshadow((*uintptr)(noescape(ptr))) 34 } 35 return old 36 } 37 38 //go:nosplit 39 func casp(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool { 40 if !casp1((*unsafe.Pointer)(noescape(unsafe.Pointer(ptr))), noescape(old), new) { 41 return false 42 } 43 writebarrierptr_nostore((*uintptr)(unsafe.Pointer(ptr)), uintptr(new)) 44 if mheap_.shadow_enabled { 45 writebarrierptr_noshadow((*uintptr)(noescape(unsafe.Pointer(ptr)))) 46 } 47 return true 48 } 49 50 // Like above, but implement in terms of sync/atomic's uintptr operations. 51 // We cannot just call the runtime routines, because the race detector expects 52 // to be able to intercept the sync/atomic forms but not the runtime forms. 53 54 //go:linkname sync_atomic_StoreUintptr sync/atomic.StoreUintptr 55 func sync_atomic_StoreUintptr(ptr *uintptr, new uintptr) 56 57 //go:linkname sync_atomic_StorePointer sync/atomic.StorePointer 58 //go:nosplit 59 func sync_atomic_StorePointer(ptr *unsafe.Pointer, new unsafe.Pointer) { 60 sync_atomic_StoreUintptr((*uintptr)(unsafe.Pointer(ptr)), uintptr(new)) 61 atomicstorep1(noescape(unsafe.Pointer(ptr)), new) 62 writebarrierptr_nostore((*uintptr)(unsafe.Pointer(ptr)), uintptr(new)) 63 if mheap_.shadow_enabled { 64 writebarrierptr_noshadow((*uintptr)(noescape(unsafe.Pointer(ptr)))) 65 } 66 } 67 68 //go:linkname sync_atomic_SwapUintptr sync/atomic.SwapUintptr 69 func sync_atomic_SwapUintptr(ptr *uintptr, new uintptr) uintptr 70 71 //go:linkname sync_atomic_SwapPointer sync/atomic.SwapPointer 72 //go:nosplit 73 func sync_atomic_SwapPointer(ptr unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer { 74 old := unsafe.Pointer(sync_atomic_SwapUintptr((*uintptr)(noescape(ptr)), uintptr(new))) 75 writebarrierptr_nostore((*uintptr)(ptr), uintptr(new)) 76 if mheap_.shadow_enabled { 77 writebarrierptr_noshadow((*uintptr)(noescape(ptr))) 78 } 79 return old 80 } 81 82 //go:linkname sync_atomic_CompareAndSwapUintptr sync/atomic.CompareAndSwapUintptr 83 func sync_atomic_CompareAndSwapUintptr(ptr *uintptr, old, new uintptr) bool 84 85 //go:linkname sync_atomic_CompareAndSwapPointer sync/atomic.CompareAndSwapPointer 86 //go:nosplit 87 func sync_atomic_CompareAndSwapPointer(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool { 88 if !sync_atomic_CompareAndSwapUintptr((*uintptr)(noescape(unsafe.Pointer(ptr))), uintptr(old), uintptr(new)) { 89 return false 90 } 91 writebarrierptr_nostore((*uintptr)(unsafe.Pointer(ptr)), uintptr(new)) 92 if mheap_.shadow_enabled { 93 writebarrierptr_noshadow((*uintptr)(noescape(unsafe.Pointer(ptr)))) 94 } 95 return true 96 }