github.com/XiaoMi/Gaea@v1.2.5/util/sync2/atomic.go (about) 1 /* 2 Copyright 2017 Google Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package sync2 18 19 import ( 20 "sync" 21 "sync/atomic" 22 "time" 23 ) 24 25 // AtomicInt32 is a wrapper with a simpler interface around atomic.(Add|Store|Load|CompareAndSwap)Int32 functions. 26 type AtomicInt32 struct { 27 int32 28 } 29 30 // NewAtomicInt32 initializes a new AtomicInt32 with a given value. 31 func NewAtomicInt32(n int32) AtomicInt32 { 32 return AtomicInt32{n} 33 } 34 35 // Add atomically adds n to the value. 36 func (i *AtomicInt32) Add(n int32) int32 { 37 return atomic.AddInt32(&i.int32, n) 38 } 39 40 // Set atomically sets n as new value. 41 func (i *AtomicInt32) Set(n int32) { 42 atomic.StoreInt32(&i.int32, n) 43 } 44 45 // Get atomically returns the current value. 46 func (i *AtomicInt32) Get() int32 { 47 return atomic.LoadInt32(&i.int32) 48 } 49 50 // CompareAndSwap atomatically swaps the old with the new value. 51 func (i *AtomicInt32) CompareAndSwap(oldval, newval int32) (swapped bool) { 52 return atomic.CompareAndSwapInt32(&i.int32, oldval, newval) 53 } 54 55 // AtomicInt64 is a wrapper with a simpler interface around atomic.(Add|Store|Load|CompareAndSwap)Int64 functions. 56 type AtomicInt64 struct { 57 int64 58 } 59 60 // NewAtomicInt64 initializes a new AtomicInt64 with a given value. 61 func NewAtomicInt64(n int64) AtomicInt64 { 62 return AtomicInt64{n} 63 } 64 65 // Add atomically adds n to the value. 66 func (i *AtomicInt64) Add(n int64) int64 { 67 return atomic.AddInt64(&i.int64, n) 68 } 69 70 // Set atomically sets n as new value. 71 func (i *AtomicInt64) Set(n int64) { 72 atomic.StoreInt64(&i.int64, n) 73 } 74 75 // Get atomically returns the current value. 76 func (i *AtomicInt64) Get() int64 { 77 return atomic.LoadInt64(&i.int64) 78 } 79 80 // CompareAndSwap atomatically swaps the old with the new value. 81 func (i *AtomicInt64) CompareAndSwap(oldval, newval int64) (swapped bool) { 82 return atomic.CompareAndSwapInt64(&i.int64, oldval, newval) 83 } 84 85 // AtomicDuration is a wrapper with a simpler interface around atomic.(Add|Store|Load|CompareAndSwap)Int64 functions. 86 type AtomicDuration struct { 87 int64 88 } 89 90 // NewAtomicDuration initializes a new AtomicDuration with a given value. 91 func NewAtomicDuration(duration time.Duration) AtomicDuration { 92 return AtomicDuration{int64(duration)} 93 } 94 95 // Add atomically adds duration to the value. 96 func (d *AtomicDuration) Add(duration time.Duration) time.Duration { 97 return time.Duration(atomic.AddInt64(&d.int64, int64(duration))) 98 } 99 100 // Set atomically sets duration as new value. 101 func (d *AtomicDuration) Set(duration time.Duration) { 102 atomic.StoreInt64(&d.int64, int64(duration)) 103 } 104 105 // Get atomically returns the current value. 106 func (d *AtomicDuration) Get() time.Duration { 107 return time.Duration(atomic.LoadInt64(&d.int64)) 108 } 109 110 // CompareAndSwap atomatically swaps the old with the new value. 111 func (d *AtomicDuration) CompareAndSwap(oldval, newval time.Duration) (swapped bool) { 112 return atomic.CompareAndSwapInt64(&d.int64, int64(oldval), int64(newval)) 113 } 114 115 // AtomicBool gives an atomic boolean variable. 116 type AtomicBool struct { 117 int32 118 } 119 120 // NewAtomicBool initializes a new AtomicBool with a given value. 121 func NewAtomicBool(n bool) AtomicBool { 122 if n { 123 return AtomicBool{1} 124 } 125 return AtomicBool{0} 126 } 127 128 // Set atomically sets n as new value. 129 func (i *AtomicBool) Set(n bool) { 130 if n { 131 atomic.StoreInt32(&i.int32, 1) 132 } else { 133 atomic.StoreInt32(&i.int32, 0) 134 } 135 } 136 137 // Get atomically returns the current value. 138 func (i *AtomicBool) Get() bool { 139 return atomic.LoadInt32(&i.int32) != 0 140 } 141 142 // CompareAndSwap atomatically swaps the old with the new value. 143 func (i *AtomicBool) CompareAndSwap(o, n bool) bool { 144 var old, new int32 145 if o { 146 old = 1 147 } 148 if n { 149 new = 1 150 } 151 return atomic.CompareAndSwapInt32(&i.int32, old, new) 152 } 153 154 // AtomicString gives you atomic-style APIs for string, but 155 // it's only a convenience wrapper that uses a mutex. So, it's 156 // not as efficient as the rest of the atomic types. 157 type AtomicString struct { 158 mu sync.Mutex 159 str string 160 } 161 162 // Set atomically sets str as new value. 163 func (s *AtomicString) Set(str string) { 164 s.mu.Lock() 165 s.str = str 166 s.mu.Unlock() 167 } 168 169 // Get atomically returns the current value. 170 func (s *AtomicString) Get() string { 171 s.mu.Lock() 172 str := s.str 173 s.mu.Unlock() 174 return str 175 } 176 177 // CompareAndSwap atomatically swaps the old with the new value. 178 func (s *AtomicString) CompareAndSwap(oldval, newval string) (swqpped bool) { 179 s.mu.Lock() 180 defer s.mu.Unlock() 181 if s.str == oldval { 182 s.str = newval 183 return true 184 } 185 return false 186 }