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 }
113