github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/atomicbitops/atomicbitops_noasm.go (about) 1 // Copyright 2018 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 !amd64 && !arm64 16 // +build !amd64,!arm64 17 18 package atomicbitops 19 20 import "sync/atomic" 21 22 //go:nosplit 23 func AndUint32(addr *Uint32, val uint32) { 24 for { 25 o := addr.Load() 26 n := o & val 27 if atomic.CompareAndSwapUint32(&addr.value, o, n) { 28 break 29 } 30 } 31 } 32 33 //go:nosplit 34 func OrUint32(addr *Uint32, val uint32) { 35 for { 36 o := addr.Load() 37 n := o | val 38 if atomic.CompareAndSwapUint32(&addr.value, o, n) { 39 break 40 } 41 } 42 } 43 44 //go:nosplit 45 func XorUint32(addr *Uint32, val uint32) { 46 for { 47 o := addr.Load() 48 n := o ^ val 49 if atomic.CompareAndSwapUint32(&addr.value, o, n) { 50 break 51 } 52 } 53 } 54 55 //go:nosplit 56 func CompareAndSwapUint32(addr *Uint32, old, new uint32) (prev uint32) { 57 for { 58 prev = addr.Load() 59 if prev != old { 60 return 61 } 62 if atomic.CompareAndSwapUint32(&addr.value, old, new) { 63 return 64 } 65 } 66 } 67 68 //go:nosplit 69 func AndUint64(addr *Uint64, val uint64) { 70 for { 71 o := atomic.LoadUint64(addr.ptr()) 72 n := o & val 73 if atomic.CompareAndSwapUint64(addr.ptr(), o, n) { 74 break 75 } 76 } 77 } 78 79 //go:nosplit 80 func OrUint64(addr *Uint64, val uint64) { 81 for { 82 o := atomic.LoadUint64(addr.ptr()) 83 n := o | val 84 if atomic.CompareAndSwapUint64(addr.ptr(), o, n) { 85 break 86 } 87 } 88 } 89 90 //go:nosplit 91 func XorUint64(addr *Uint64, val uint64) { 92 for { 93 o := atomic.LoadUint64(addr.ptr()) 94 n := o ^ val 95 if atomic.CompareAndSwapUint64(addr.ptr(), o, n) { 96 break 97 } 98 } 99 } 100 101 //go:nosplit 102 func CompareAndSwapUint64(addr *Uint64, old, new uint64) (prev uint64) { 103 for { 104 prev = atomic.LoadUint64(addr.ptr()) 105 if prev != old { 106 return 107 } 108 if atomic.CompareAndSwapUint64(addr.ptr(), old, new) { 109 return 110 } 111 } 112 }