github.com/ttpreport/gvisor-ligolo@v0.0.0-20240123134145-a858404967ba/pkg/atomicbitops/32b_32bit.go (about) 1 // Copyright 2022 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //go:build arm || mips || mipsle || 386 16 // +build arm mips mipsle 386 17 18 package atomicbitops 19 20 import ( 21 "sync/atomic" 22 23 "github.com/ttpreport/gvisor-ligolo/pkg/sync" 24 ) 25 26 // Note that this file is *identical* to 32b_64bit.go, as go_stateify gets 27 // confused about build tags if these are not separated. 28 29 // LINT.IfChange 30 31 // Int32 is an atomic int32. 32 // 33 // The default value is zero. 34 // 35 // Don't add fields to this struct. It is important that it remain the same 36 // size as its builtin analogue. 37 // 38 // +stateify savable 39 type Int32 struct { 40 _ sync.NoCopy 41 value int32 42 } 43 44 // FromInt32 returns an Int32 initialized to value v. 45 // 46 //go:nosplit 47 func FromInt32(v int32) Int32 { 48 return Int32{value: v} 49 } 50 51 // Load is analogous to atomic.LoadInt32. 52 // 53 //go:nosplit 54 func (i *Int32) Load() int32 { 55 return atomic.LoadInt32(&i.value) 56 } 57 58 // RacyLoad is analogous to reading an atomic value without using 59 // synchronization. 60 // 61 // It may be helpful to document why a racy operation is permitted. 62 // 63 //go:nosplit 64 func (i *Int32) RacyLoad() int32 { 65 return i.value 66 } 67 68 // Store is analogous to atomic.StoreInt32. 69 // 70 //go:nosplit 71 func (i *Int32) Store(v int32) { 72 atomic.StoreInt32(&i.value, v) 73 } 74 75 // RacyStore is analogous to setting an atomic value without using 76 // synchronization. 77 // 78 // It may be helpful to document why a racy operation is permitted. 79 // 80 // Don't add fields to this struct. It is important that it remain the same 81 // size as its builtin analogue. 82 // 83 //go:nosplit 84 func (i *Int32) RacyStore(v int32) { 85 i.value = v 86 } 87 88 // Add is analogous to atomic.AddInt32. 89 // 90 //go:nosplit 91 func (i *Int32) Add(v int32) int32 { 92 return atomic.AddInt32(&i.value, v) 93 } 94 95 // RacyAdd is analogous to adding to an atomic value without using 96 // synchronization. 97 // 98 // It may be helpful to document why a racy operation is permitted. 99 // 100 //go:nosplit 101 func (i *Int32) RacyAdd(v int32) int32 { 102 i.value += v 103 return i.value 104 } 105 106 // Swap is analogous to atomic.SwapInt32. 107 // 108 //go:nosplit 109 func (i *Int32) Swap(v int32) int32 { 110 return atomic.SwapInt32(&i.value, v) 111 } 112 113 // CompareAndSwap is analogous to atomic.CompareAndSwapInt32. 114 // 115 //go:nosplit 116 func (i *Int32) CompareAndSwap(oldVal, newVal int32) bool { 117 return atomic.CompareAndSwapInt32(&i.value, oldVal, newVal) 118 } 119 120 //go:nosplit 121 func (i *Int32) ptr() *int32 { 122 return &i.value 123 } 124 125 // Uint32 is an atomic uint32. 126 // 127 // See aligned_unsafe.go in this directory for justification. 128 // 129 // +stateify savable 130 type Uint32 struct { 131 _ sync.NoCopy 132 value uint32 133 } 134 135 // FromUint32 returns an Uint32 initialized to value v. 136 // 137 //go:nosplit 138 func FromUint32(v uint32) Uint32 { 139 return Uint32{value: v} 140 } 141 142 // Load is analogous to atomic.LoadUint32. 143 // 144 //go:nosplit 145 func (u *Uint32) Load() uint32 { 146 return atomic.LoadUint32(&u.value) 147 } 148 149 // RacyLoad is analogous to reading an atomic value without using 150 // synchronization. 151 // 152 // It may be helpful to document why a racy operation is permitted. 153 // 154 //go:nosplit 155 func (u *Uint32) RacyLoad() uint32 { 156 return u.value 157 } 158 159 // Store is analogous to atomic.StoreUint32. 160 // 161 //go:nosplit 162 func (u *Uint32) Store(v uint32) { 163 atomic.StoreUint32(&u.value, v) 164 } 165 166 // RacyStore is analogous to setting an atomic value without using 167 // synchronization. 168 // 169 // It may be helpful to document why a racy operation is permitted. 170 // 171 //go:nosplit 172 func (u *Uint32) RacyStore(v uint32) { 173 u.value = v 174 } 175 176 // Add is analogous to atomic.AddUint32. 177 // 178 //go:nosplit 179 func (u *Uint32) Add(v uint32) uint32 { 180 return atomic.AddUint32(&u.value, v) 181 } 182 183 // RacyAdd is analogous to adding to an atomic value without using 184 // synchronization. 185 // 186 // It may be helpful to document why a racy operation is permitted. 187 // 188 //go:nosplit 189 func (u *Uint32) RacyAdd(v uint32) uint32 { 190 u.value += v 191 return u.value 192 } 193 194 // Swap is analogous to atomic.SwapUint32. 195 // 196 //go:nosplit 197 func (u *Uint32) Swap(v uint32) uint32 { 198 return atomic.SwapUint32(&u.value, v) 199 } 200 201 // CompareAndSwap is analogous to atomic.CompareAndSwapUint32. 202 // 203 //go:nosplit 204 func (u *Uint32) CompareAndSwap(oldVal, newVal uint32) bool { 205 return atomic.CompareAndSwapUint32(&u.value, oldVal, newVal) 206 } 207 208 //go:nosplit 209 func (u *Uint32) ptr() *uint32 { 210 return &u.value 211 } 212 213 // LINT.ThenChange(32b_64bit.go)