atomic.tpl (1669B)
1 package atomics 2 3 import ( 4 "sync/atomic" 5 "unsafe" 6 ) 7 8 // {{ .Name }} provides user-friendly means of performing atomic operations on {{ .Type }} types. 9 type {{ .Name }} struct{ ptr unsafe.Pointer } 10 11 // New{{ .Name }} will return a new {{ .Name }} instance initialized with zero value. 12 func New{{ .Name }}() *{{ .Name }} { 13 var v {{ .Type }} 14 return &{{ .Name }}{ 15 ptr: unsafe.Pointer(&v), 16 } 17 } 18 19 // Store will atomically store {{ .Type }} value in address contained within v. 20 func (v *{{ .Name }}) Store(val {{ .Type }}) { 21 atomic.StorePointer(&v.ptr, unsafe.Pointer(&val)) 22 } 23 24 // Load will atomically load {{ .Type }} value at address contained within v. 25 func (v *{{ .Name }}) Load() {{ .Type }} { 26 return *(*{{ .Type }})(atomic.LoadPointer(&v.ptr)) 27 } 28 29 // CAS performs a compare-and-swap for a(n) {{ .Type }} value at address contained within v. 30 func (v *{{ .Name }}) CAS(cmp, swp {{ .Type }}) bool { 31 for { 32 // Load current value at address 33 ptr := atomic.LoadPointer(&v.ptr) 34 cur := *(*{{ .Type }})(ptr) 35 36 // Perform comparison against current 37 if !({{ call .Compare "cur" "cmp" }}) { 38 return false 39 } 40 41 // Attempt to replace pointer 42 if atomic.CompareAndSwapPointer( 43 &v.ptr, 44 ptr, 45 unsafe.Pointer(&swp), 46 ) { 47 return true 48 } 49 } 50 } 51 52 // Swap atomically stores new {{ .Type }} value into address contained within v, and returns previous value. 53 func (v *{{ .Name }}) Swap(swp {{ .Type }}) {{ .Type }} { 54 ptr := unsafe.Pointer(&swp) 55 ptr = atomic.SwapPointer(&v.ptr, ptr) 56 return *(*{{ .Type }})(ptr) 57 }