1package azblob 2 3import "sync/atomic" 4 5// AtomicMorpherInt32 identifies a method passed to and invoked by the AtomicMorphInt32 function. 6// The AtomicMorpher callback is passed a startValue and based on this value it returns 7// what the new value should be and the result that AtomicMorph should return to its caller. 8type atomicMorpherInt32 func(startVal int32) (val int32, morphResult interface{}) 9 10const targetAndMorpherMustNotBeNil = "target and morpher must not be nil" 11 12// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function. 13func atomicMorphInt32(target *int32, morpher atomicMorpherInt32) interface{} { 14 for { 15 currentVal := atomic.LoadInt32(target) 16 desiredVal, morphResult := morpher(currentVal) 17 if atomic.CompareAndSwapInt32(target, currentVal, desiredVal) { 18 return morphResult 19 } 20 } 21} 22 23// AtomicMorpherUint32 identifies a method passed to and invoked by the AtomicMorph function. 24// The AtomicMorpher callback is passed a startValue and based on this value it returns 25// what the new value should be and the result that AtomicMorph should return to its caller. 26type atomicMorpherUint32 func(startVal uint32) (val uint32, morphResult interface{}) 27 28// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function. 29func atomicMorphUint32(target *uint32, morpher atomicMorpherUint32) interface{} { 30 for { 31 currentVal := atomic.LoadUint32(target) 32 desiredVal, morphResult := morpher(currentVal) 33 if atomic.CompareAndSwapUint32(target, currentVal, desiredVal) { 34 return morphResult 35 } 36 } 37} 38 39// AtomicMorpherUint64 identifies a method passed to and invoked by the AtomicMorphUint64 function. 40// The AtomicMorpher callback is passed a startValue and based on this value it returns 41// what the new value should be and the result that AtomicMorph should return to its caller. 42type atomicMorpherInt64 func(startVal int64) (val int64, morphResult interface{}) 43 44// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function. 45func atomicMorphInt64(target *int64, morpher atomicMorpherInt64) interface{} { 46 for { 47 currentVal := atomic.LoadInt64(target) 48 desiredVal, morphResult := morpher(currentVal) 49 if atomic.CompareAndSwapInt64(target, currentVal, desiredVal) { 50 return morphResult 51 } 52 } 53} 54 55// AtomicMorpherUint64 identifies a method passed to and invoked by the AtomicMorphUint64 function. 56// The AtomicMorpher callback is passed a startValue and based on this value it returns 57// what the new value should be and the result that AtomicMorph should return to its caller. 58type atomicMorpherUint64 func(startVal uint64) (val uint64, morphResult interface{}) 59 60// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function. 61func atomicMorphUint64(target *uint64, morpher atomicMorpherUint64) interface{} { 62 for { 63 currentVal := atomic.LoadUint64(target) 64 desiredVal, morphResult := morpher(currentVal) 65 if atomic.CompareAndSwapUint64(target, currentVal, desiredVal) { 66 return morphResult 67 } 68 } 69} 70