github.com/insolar/vanilla@v0.0.0-20201023172447-248fdf805322/atomickit/uint32.go (about) 1 // Copyright 2020 Insolar Network Ltd. 2 // All rights reserved. 3 // This material is licensed under the Insolar License version 1.0, 4 // available at https://github.com/insolar/assured-ledger/blob/master/LICENSE.md. 5 6 package atomickit 7 8 import ( 9 "strconv" 10 "sync/atomic" 11 ) 12 13 func NewUint32(v uint32) Uint32 { 14 return Uint32{v} 15 } 16 17 type Uint32 struct { 18 v uint32 19 } 20 21 func (p *Uint32) Load() uint32 { 22 return atomic.LoadUint32(&p.v) 23 } 24 25 func (p *Uint32) Store(v uint32) { 26 atomic.StoreUint32(&p.v, v) 27 } 28 29 func (p *Uint32) Swap(v uint32) uint32 { 30 return atomic.SwapUint32(&p.v, v) 31 } 32 33 func (p *Uint32) CompareAndSwap(old, new uint32) bool { 34 return atomic.CompareAndSwapUint32(&p.v, old, new) 35 } 36 37 func (p *Uint32) Add(v uint32) uint32 { 38 return atomic.AddUint32(&p.v, v) 39 } 40 41 func (p *Uint32) Sub(v uint32) uint32 { 42 return p.Add(^(v - 1)) 43 } 44 45 func (p *Uint32) String() string { 46 return strconv.FormatUint(uint64(p.Load()), 10) 47 } 48 49 func (p *Uint32) SetBits(v uint32) uint32 { 50 for { 51 switch x := p.Load(); { 52 case x & v == v: 53 return x 54 case p.CompareAndSwap(x, x|v): 55 return x|v 56 } 57 } 58 } 59 60 func (p *Uint32) TrySetBits(v uint32, all bool) bool { 61 for { 62 x := p.Load() 63 switch { 64 case x & v == 0: 65 case all: 66 return false 67 case x & v == v: 68 return false 69 } 70 if p.CompareAndSwap(x, x|v) { 71 return true 72 } 73 } 74 } 75 76 func (p *Uint32) UnsetBits(v uint32) uint32 { 77 for { 78 switch x := p.Load(); { 79 case x & v == 0: 80 return x 81 case p.CompareAndSwap(x, x&^v): 82 return x&^v 83 } 84 } 85 } 86 87 func (p *Uint32) TryUnsetBits(v uint32, all bool) bool { 88 for { 89 x := p.Load() 90 switch { 91 case x & v == 0: 92 return false 93 case x & v == v: 94 case all: 95 return false 96 } 97 if p.CompareAndSwap(x, x&^v) { 98 return true 99 } 100 } 101 } 102 103 func (p *Uint32) CompareAndSub(v uint32) bool { 104 for { 105 switch x := p.Load(); { 106 case x < v: 107 return false 108 case p.CompareAndSwap(x, x-v): 109 return true 110 } 111 } 112 } 113 114 func (p *Uint32) SetLesser(v uint32) uint32 { 115 for { 116 switch x := p.Load(); { 117 case x <= v: 118 return x 119 case p.CompareAndSwap(x, v): 120 return v 121 } 122 } 123 } 124 125 func (p *Uint32) SetGreater(v uint32) uint32 { 126 for { 127 switch x := p.Load(); { 128 case x >= v: 129 return x 130 case p.CompareAndSwap(x, v): 131 return v 132 } 133 } 134 } 135 136 func (p *Uint32) CompareAndSetBits(maskOut, deny, v uint32) bool { 137 for { 138 x := p.Load() 139 x2 := x &^ maskOut 140 switch { 141 case x2 & deny != 0: 142 return false 143 case x2 & v != 0: 144 return false 145 } 146 if p.CompareAndSwap(x, x|v) { 147 return true 148 } 149 } 150 }