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 }