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  }