github.com/hslam/atomic@v1.0.0/float64.go (about)

     1  // Copyright (c) 2020 Meng Huang (mhboy@outlook.com)
     2  // This package is licensed under a MIT license that can be found in the LICENSE file.
     3  
     4  package atomic
     5  
     6  import (
     7  	"sync/atomic"
     8  	"unsafe"
     9  )
    10  
    11  // Float64 represents an float64.
    12  type Float64 struct {
    13  	v uint64
    14  }
    15  
    16  // NewFloat64 returns a new Float64.
    17  func NewFloat64(val float64) *Float64 {
    18  	addr := &Float64{}
    19  	addr.Store(val)
    20  	return addr
    21  }
    22  
    23  // Swap atomically stores new into *addr and returns the previous *addr value.
    24  func (addr *Float64) Swap(new float64) (old float64) {
    25  	var v = atomic.SwapUint64(&addr.v, *(*uint64)(unsafe.Pointer(&new)))
    26  	return *(*float64)(unsafe.Pointer(&v))
    27  }
    28  
    29  // CompareAndSwap executes the compare-and-swap operation for an float64 value.
    30  func (addr *Float64) CompareAndSwap(old, new float64) (swapped bool) {
    31  	return atomic.CompareAndSwapUint64(&addr.v, *(*uint64)(unsafe.Pointer(&old)), *(*uint64)(unsafe.Pointer(&new)))
    32  }
    33  
    34  // Add atomically adds delta to *addr and returns the new value.
    35  func (addr *Float64) Add(delta float64) (new float64) {
    36  	for {
    37  		old := addr.Load()
    38  		new = old + delta
    39  		if addr.CompareAndSwap(old, new) {
    40  			return
    41  		}
    42  	}
    43  }
    44  
    45  // Load atomically loads *addr.
    46  func (addr *Float64) Load() (val float64) {
    47  	var v = atomic.LoadUint64(&addr.v)
    48  	return *(*float64)(unsafe.Pointer(&v))
    49  }
    50  
    51  // Store atomically stores val into *addr.
    52  func (addr *Float64) Store(val float64) {
    53  	atomic.StoreUint64(&addr.v, *(*uint64)(unsafe.Pointer(&val)))
    54  }