github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zutil/atomic.go (about) 1 package zutil 2 3 import ( 4 "fmt" 5 "strconv" 6 "sync/atomic" 7 ) 8 9 type ( 10 Bool struct { 11 _ Nocmp 12 b int32 13 } 14 Int32 struct { 15 _ Nocmp 16 v int32 17 } 18 Uint32 struct { 19 _ Nocmp 20 v uint32 21 } 22 Uint64 struct { 23 _ Nocmp 24 v uint64 25 } 26 Int64 struct { 27 _ Nocmp 28 v int64 29 } 30 Uintptr struct { 31 _ Nocmp 32 v uintptr 33 } 34 ) 35 36 func NewBool(b bool) *Bool { 37 ret := &Bool{} 38 if b { 39 ret.b = 1 40 } 41 42 return ret 43 } 44 45 func (b *Bool) Store(val bool) bool { 46 var newV int32 47 if val { 48 newV = 1 49 } 50 return atomic.SwapInt32(&b.b, newV) == 1 51 } 52 53 func (b *Bool) Load() bool { 54 return atomic.LoadInt32(&b.b) == 1 55 } 56 57 func (b *Bool) Toggle() (old bool) { 58 for { 59 old := b.Load() 60 if b.CAS(old, !old) { 61 return old 62 } 63 } 64 } 65 66 func (b *Bool) CAS(old, new bool) bool { 67 var o, n int32 68 69 if old { 70 o = 1 71 } 72 if new { 73 n = 1 74 } 75 76 return atomic.CompareAndSwapInt32(&b.b, o, n) 77 } 78 79 func NewInt32(i int32) *Int32 { 80 return &Int32{ 81 v: i, 82 } 83 } 84 85 func (i32 *Int32) Add(i int32) int32 { 86 return atomic.AddInt32(&i32.v, i) 87 } 88 89 func (i32 *Int32) Sub(i int32) int32 { 90 return atomic.AddInt32(&i32.v, -i) 91 } 92 93 func (i32 *Int32) Swap(i int32) int32 { 94 return atomic.SwapInt32(&i32.v, i) 95 } 96 97 func (i32 *Int32) Load() int32 { 98 return atomic.LoadInt32(&i32.v) 99 } 100 101 func (i32 *Int32) Store(i int32) { 102 atomic.StoreInt32(&i32.v, i) 103 } 104 105 func (i32 *Int32) CAS(old, new int32) bool { 106 return atomic.CompareAndSwapInt32(&i32.v, old, new) 107 } 108 109 func (i32 *Int32) String() string { 110 v := i32.Load() 111 return strconv.FormatInt(int64(v), 10) 112 } 113 114 func NewUint32(i uint32) *Uint32 { 115 return &Uint32{ 116 v: i, 117 } 118 } 119 120 func (u32 *Uint32) Add(i uint32) uint32 { 121 return atomic.AddUint32(&u32.v, i) 122 } 123 124 func (u32 *Uint32) Sub(i uint32) uint32 { 125 return atomic.AddUint32(&u32.v, ^(i - 1)) 126 } 127 128 func (u32 *Uint32) Swap(i uint32) uint32 { 129 return atomic.SwapUint32(&u32.v, i) 130 } 131 132 func (u32 *Uint32) Load() uint32 { 133 return atomic.LoadUint32(&u32.v) 134 } 135 136 func (u32 *Uint32) Store(i uint32) { 137 atomic.StoreUint32(&u32.v, i) 138 } 139 140 func (u32 *Uint32) CAS(old, new uint32) bool { 141 return atomic.CompareAndSwapUint32(&u32.v, old, new) 142 } 143 144 func (u32 *Uint32) String() string { 145 v := u32.Load() 146 return strconv.FormatInt(int64(v), 10) 147 } 148 149 func NewUint64(i uint64) *Uint64 { 150 return &Uint64{ 151 v: i, 152 } 153 } 154 155 func (u64 *Uint64) Add(i uint64) uint64 { 156 return atomic.AddUint64(&u64.v, i) 157 } 158 159 func (u64 *Uint64) Sub(i uint64) uint64 { 160 return atomic.AddUint64(&u64.v, ^(i - 1)) 161 } 162 163 func (u64 *Uint64) Swap(i uint64) uint64 { 164 return atomic.SwapUint64(&u64.v, i) 165 } 166 167 func (u64 *Uint64) Load() uint64 { 168 return atomic.LoadUint64(&u64.v) 169 } 170 171 func (u64 *Uint64) Store(i uint64) { 172 atomic.StoreUint64(&u64.v, i) 173 } 174 175 func (u64 *Uint64) CAS(old, new uint64) bool { 176 return atomic.CompareAndSwapUint64(&u64.v, old, new) 177 } 178 179 func (u64 *Uint64) String() string { 180 v := u64.Load() 181 return strconv.FormatInt(int64(v), 10) 182 } 183 184 func NewInt64(i int64) *Int64 { 185 return &Int64{ 186 v: i, 187 } 188 } 189 190 func (i64 *Int64) Add(i int64) int64 { 191 return atomic.AddInt64(&i64.v, i) 192 } 193 194 func (i64 *Int64) Sub(i int64) int64 { 195 return atomic.AddInt64(&i64.v, -i) 196 } 197 198 func (i64 *Int64) Swap(i int64) int64 { 199 return atomic.SwapInt64(&i64.v, i) 200 } 201 202 func (i64 *Int64) Load() int64 { 203 return atomic.LoadInt64(&i64.v) 204 } 205 206 func (i64 *Int64) Store(i int64) { 207 atomic.StoreInt64(&i64.v, i) 208 } 209 210 func (i64 *Int64) CAS(old, new int64) bool { 211 return atomic.CompareAndSwapInt64(&i64.v, old, new) 212 } 213 214 func (i64 *Int64) String() string { 215 v := i64.Load() 216 return strconv.FormatInt(v, 10) 217 } 218 219 func NewUintptr(i uintptr) *Uintptr { 220 return &Uintptr{ 221 v: i, 222 } 223 } 224 225 func (ptr *Uintptr) Add(i uintptr) uintptr { 226 return atomic.AddUintptr(&ptr.v, i) 227 } 228 229 func (ptr *Uintptr) Sub(i uintptr) uintptr { 230 return atomic.AddUintptr(&ptr.v, -i) 231 } 232 233 func (ptr *Uintptr) Swap(i uintptr) uintptr { 234 return atomic.SwapUintptr(&ptr.v, i) 235 } 236 237 func (ptr *Uintptr) Load() uintptr { 238 return atomic.LoadUintptr(&ptr.v) 239 } 240 241 func (ptr *Uintptr) Store(i uintptr) { 242 atomic.StoreUintptr(&ptr.v, i) 243 } 244 245 func (ptr *Uintptr) CAS(old, new uintptr) bool { 246 return atomic.CompareAndSwapUintptr(&ptr.v, old, new) 247 } 248 249 func (ptr *Uintptr) String() string { 250 v := ptr.Load() 251 return fmt.Sprintf("%+v", v) 252 }