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  }