github.com/insolar/vanilla@v0.0.0-20201023172447-248fdf805322/atomickit/int.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  	"math/bits"
    10  	"strconv"
    11  	"sync/atomic"
    12  	"unsafe"
    13  )
    14  
    15  func NewInt(v int) Int {
    16  	return Int{v}
    17  }
    18  
    19  type Int struct {
    20  	v int
    21  }
    22  
    23  func (p *Int) ptr32() *int32 {
    24  	return (*int32)(unsafe.Pointer(&p.v))
    25  }
    26  
    27  func (p *Int) ptr64() *int64 {
    28  	return (*int64)(unsafe.Pointer(&p.v))
    29  }
    30  
    31  func (p *Int) Load() int {
    32  	if bits.UintSize == 32 {
    33  		return int(atomic.LoadInt32(p.ptr32()))
    34  	}
    35  	return int(atomic.LoadInt64(p.ptr64()))
    36  }
    37  
    38  func (p *Int) Store(v int) {
    39  	if bits.UintSize == 32 {
    40  		atomic.StoreInt32(p.ptr32(), int32(v))
    41  		return
    42  	}
    43  	atomic.StoreInt64(p.ptr64(), int64(v))
    44  }
    45  
    46  func (p *Int) Swap(v int) int {
    47  	if bits.UintSize == 32 {
    48  		return int(atomic.SwapInt32(p.ptr32(), int32(v)))
    49  	}
    50  	return int(atomic.SwapInt64(p.ptr64(), int64(v)))
    51  }
    52  
    53  func (p *Int) CompareAndSwap(old, new int) bool {
    54  	if bits.UintSize == 32 {
    55  		return atomic.CompareAndSwapInt32(p.ptr32(), int32(old), int32(new))
    56  	}
    57  	return atomic.CompareAndSwapInt64(p.ptr64(), int64(old), int64(new))
    58  }
    59  
    60  func (p *Int) Add(v int) int {
    61  	if bits.UintSize == 32 {
    62  		return int(atomic.AddInt32(p.ptr32(), int32(v)))
    63  	}
    64  	return int(atomic.AddInt64(p.ptr64(), int64(v)))
    65  }
    66  
    67  func (p *Int) Sub(v int) int {
    68  	return p.Add(-v)
    69  }
    70  
    71  func (p *Int) String() string {
    72  	return strconv.FormatInt(int64(p.Load()), 10)
    73  }
    74  
    75  func (p *Int) SetLesser(v int) int {
    76  	for {
    77  		switch x := p.Load(); {
    78  		case x <= v:
    79  			return x
    80  		case p.CompareAndSwap(x, v):
    81  			return v
    82  		}
    83  	}
    84  }
    85  
    86  func (p *Int) SetGreater(v int) int {
    87  	for {
    88  		switch x := p.Load(); {
    89  		case x >= v:
    90  			return x
    91  		case p.CompareAndSwap(x, v):
    92  			return v
    93  		}
    94  	}
    95  }