github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/cmn/atomic/a.go (about)

     1  // Package atomic provides simple wrappers around numerics to enforce atomic
     2  // access.
     3  /*
     4   * Copyright (c) 2018-2023, NVIDIA CORPORATION. All rights reserved.
     5   */
     6  package atomic
     7  
     8  import (
     9  	"encoding/json"
    10  	"sync/atomic"
    11  	"time"
    12  )
    13  
    14  //
    15  // int32
    16  //
    17  
    18  type Int32 atomic.Int32
    19  
    20  func NewInt32(i int32) *Int32 {
    21  	v := &atomic.Int32{}
    22  	v.Store(i)
    23  	return (*Int32)(v)
    24  }
    25  
    26  func (v *Int32) Load() int32         { return (*atomic.Int32)(v).Load() }
    27  func (v *Int32) Store(n int32)       { (*atomic.Int32)(v).Store(n) }
    28  func (v *Int32) Add(n int32) int32   { return (*atomic.Int32)(v).Add(n) }
    29  func (v *Int32) Inc() int32          { return (*atomic.Int32)(v).Add(1) }
    30  func (v *Int32) Dec() int32          { return (*atomic.Int32)(v).Add(-1) }
    31  func (v *Int32) CAS(o, n int32) bool { return (*atomic.Int32)(v).CompareAndSwap(o, n) }
    32  func (v *Int32) Swap(n int32) int32  { return (*atomic.Int32)(v).Swap(n) }
    33  
    34  //
    35  // uint32
    36  //
    37  
    38  type Uint32 atomic.Uint32
    39  
    40  func NewUint32(i uint32) *Uint32 {
    41  	v := &atomic.Uint32{}
    42  	v.Store(i)
    43  	return (*Uint32)(v)
    44  }
    45  
    46  func (v *Uint32) Load() uint32         { return (*atomic.Uint32)(v).Load() }
    47  func (v *Uint32) Store(n uint32)       { (*atomic.Uint32)(v).Store(n) }
    48  func (v *Uint32) Add(n uint32) uint32  { return (*atomic.Uint32)(v).Add(n) }
    49  func (v *Uint32) Inc() uint32          { return (*atomic.Uint32)(v).Add(1) }
    50  func (v *Uint32) CAS(o, n uint32) bool { return (*atomic.Uint32)(v).CompareAndSwap(o, n) }
    51  func (v *Uint32) Swap(n uint32) uint32 { return (*atomic.Uint32)(v).Swap(n) }
    52  
    53  //
    54  // int64
    55  //
    56  
    57  type Int64 atomic.Int64
    58  
    59  func NewInt64(i int64) *Int64 {
    60  	v := &atomic.Int64{}
    61  	v.Store(i)
    62  	return (*Int64)(v)
    63  }
    64  
    65  func (v *Int64) Load() int64         { return (*atomic.Int64)(v).Load() }
    66  func (v *Int64) Store(n int64)       { (*atomic.Int64)(v).Store(n) }
    67  func (v *Int64) Add(n int64) int64   { return (*atomic.Int64)(v).Add(n) }
    68  func (v *Int64) Sub(n int64) int64   { return (*atomic.Int64)(v).Add(-n) }
    69  func (v *Int64) Inc() int64          { return (*atomic.Int64)(v).Add(1) }
    70  func (v *Int64) Dec() int64          { return (*atomic.Int64)(v).Add(-1) }
    71  func (v *Int64) CAS(o, n int64) bool { return (*atomic.Int64)(v).CompareAndSwap(o, n) }
    72  func (v *Int64) Swap(n int64) int64  { return (*atomic.Int64)(v).Swap(n) }
    73  
    74  //
    75  // uint64
    76  //
    77  
    78  type Uint64 atomic.Uint64
    79  
    80  func NewUint64(i uint64) *Uint64 {
    81  	v := &atomic.Uint64{}
    82  	v.Store(i)
    83  	return (*Uint64)(v)
    84  }
    85  
    86  func (v *Uint64) Load() uint64         { return (*atomic.Uint64)(v).Load() }
    87  func (v *Uint64) Store(n uint64)       { (*atomic.Uint64)(v).Store(n) }
    88  func (v *Uint64) Add(n uint64) uint64  { return (*atomic.Uint64)(v).Add(n) }
    89  func (v *Uint64) Sub(n uint64) uint64  { return (*atomic.Uint64)(v).Add(^(n - 1)) }
    90  func (v *Uint64) Inc() uint64          { return (*atomic.Uint64)(v).Add(1) }
    91  func (v *Uint64) CAS(o, n uint64) bool { return (*atomic.Uint64)(v).CompareAndSwap(o, n) }
    92  func (v *Uint64) Swap(n uint64) uint64 { return (*atomic.Uint64)(v).Swap(n) }
    93  
    94  //
    95  // bool
    96  //
    97  
    98  type Bool atomic.Bool
    99  
   100  // interface guard
   101  var (
   102  	_ json.Marshaler   = (*Bool)(nil)
   103  	_ json.Unmarshaler = (*Bool)(nil)
   104  )
   105  
   106  func NewBool(i bool) *Bool {
   107  	v := &atomic.Bool{}
   108  	v.Store(i)
   109  	return (*Bool)(v)
   110  }
   111  
   112  func (v *Bool) Load() bool         { return (*atomic.Bool)(v).Load() }
   113  func (v *Bool) Store(n bool)       { (*atomic.Bool)(v).Store(n) }
   114  func (v *Bool) CAS(o, n bool) bool { return (*atomic.Bool)(v).CompareAndSwap(o, n) }
   115  func (v *Bool) Swap(n bool) bool   { return (*atomic.Bool)(v).Swap(n) }
   116  
   117  func (v *Bool) Toggle() bool {
   118  	if v.CAS(true, false) {
   119  		return true
   120  	}
   121  	return !v.CAS(false, true)
   122  }
   123  
   124  func (v *Bool) MarshalJSON() ([]byte, error) {
   125  	return json.Marshal(v.Load())
   126  }
   127  
   128  func (v *Bool) UnmarshalJSON(data []byte) error {
   129  	var y bool
   130  	if err := json.Unmarshal(data, &y); err != nil {
   131  		return err
   132  	}
   133  	v.Store(y)
   134  	return nil
   135  }
   136  
   137  //
   138  // time
   139  //
   140  
   141  type Time atomic.Int64
   142  
   143  // interface guard
   144  var (
   145  	_ json.Marshaler   = (*Time)(nil)
   146  	_ json.Unmarshaler = (*Time)(nil)
   147  )
   148  
   149  func NewTime(t time.Time) *Time {
   150  	v := &atomic.Int64{}
   151  	v.Store(t.UnixNano())
   152  	return (*Time)(v)
   153  }
   154  
   155  func (t *Time) Load() time.Time   { return time.Unix(0, (*atomic.Int64)(t).Load()) }
   156  func (t *Time) Store(n time.Time) { (*atomic.Int64)(t).Store(n.UnixNano()) }
   157  
   158  func (t *Time) MarshalJSON() ([]byte, error) {
   159  	return json.Marshal(t.Load().UnixNano())
   160  }
   161  
   162  func (t *Time) UnmarshalJSON(data []byte) error {
   163  	var y int64
   164  	if err := json.Unmarshal(data, &y); err != nil {
   165  		return err
   166  	}
   167  	t.Store(time.Unix(0, y))
   168  	return nil
   169  }