LEFT | RIGHT |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // +build race | 5 // +build race |
6 | 6 |
7 package atomic | 7 package atomic |
8 | 8 |
9 import ( | 9 import ( |
10 "runtime" | 10 "runtime" |
11 "unsafe" | 11 "unsafe" |
12 ) | 12 ) |
13 | 13 |
14 var mtx uint32 = 1 // same for all | 14 var mtx uint32 = 1 // same for all |
15 | 15 |
16 func CompareAndSwapInt32(val *int32, old, new int32) bool { | 16 func CompareAndSwapInt32(val *int32, old, new int32) bool { |
17 return CompareAndSwapUint32((*uint32)(unsafe.Pointer(val)), uint32(old),
uint32(new)) | 17 return CompareAndSwapUint32((*uint32)(unsafe.Pointer(val)), uint32(old),
uint32(new)) |
18 } | 18 } |
19 | 19 |
20 func CompareAndSwapUint32(val *uint32, old, new uint32) (swapped bool) { | 20 func CompareAndSwapUint32(val *uint32, old, new uint32) (swapped bool) { |
21 pc := make([]uintptr, 1) | |
22 runtime.Callers(2, pc) | |
23 | |
24 swapped = false | 21 swapped = false |
25 runtime.RaceSemacquire(&mtx) | 22 runtime.RaceSemacquire(&mtx) |
26 runtime.RaceAcquire(unsafe.Pointer(val)) | 23 runtime.RaceAcquire(unsafe.Pointer(val)) |
27 if *val == old { | 24 if *val == old { |
28 *val = new | 25 *val = new |
29 swapped = true | 26 swapped = true |
30 runtime.RaceReleaseMerge(unsafe.Pointer(val)) | 27 runtime.RaceReleaseMerge(unsafe.Pointer(val)) |
31 } | 28 } |
32 runtime.RaceSemrelease(&mtx) | 29 runtime.RaceSemrelease(&mtx) |
33 return | 30 return |
34 } | 31 } |
35 | 32 |
36 func CompareAndSwapInt64(val *int64, old, new int64) bool { | 33 func CompareAndSwapInt64(val *int64, old, new int64) bool { |
37 return CompareAndSwapUint64((*uint64)(unsafe.Pointer(val)), uint64(old),
uint64(new)) | 34 return CompareAndSwapUint64((*uint64)(unsafe.Pointer(val)), uint64(old),
uint64(new)) |
38 } | 35 } |
39 | 36 |
40 func CompareAndSwapUint64(val *uint64, old, new uint64) (swapped bool) { | 37 func CompareAndSwapUint64(val *uint64, old, new uint64) (swapped bool) { |
41 pc := make([]uintptr, 1) | |
42 runtime.Callers(2, pc) | |
43 | |
44 swapped = false | 38 swapped = false |
45 runtime.RaceSemacquire(&mtx) | 39 runtime.RaceSemacquire(&mtx) |
46 runtime.RaceAcquire(unsafe.Pointer(val)) | 40 runtime.RaceAcquire(unsafe.Pointer(val)) |
47 if *val == old { | 41 if *val == old { |
48 *val = new | 42 *val = new |
49 swapped = true | 43 swapped = true |
50 runtime.RaceReleaseMerge(unsafe.Pointer(val)) | 44 runtime.RaceReleaseMerge(unsafe.Pointer(val)) |
51 } | 45 } |
52 runtime.RaceSemrelease(&mtx) | 46 runtime.RaceSemrelease(&mtx) |
53 return | 47 return |
54 } | 48 } |
55 | 49 |
56 func CompareAndSwapPointer(val *unsafe.Pointer, old, new unsafe.Pointer) (swappe
d bool) { | 50 func CompareAndSwapPointer(val *unsafe.Pointer, old, new unsafe.Pointer) (swappe
d bool) { |
57 pc := make([]uintptr, 1) | |
58 runtime.Callers(2, pc) | |
59 | |
60 swapped = false | 51 swapped = false |
61 runtime.RaceSemacquire(&mtx) | 52 runtime.RaceSemacquire(&mtx) |
62 runtime.RaceAcquire(unsafe.Pointer(val)) | 53 runtime.RaceAcquire(unsafe.Pointer(val)) |
63 if *val == old { | 54 if *val == old { |
64 *val = new | 55 *val = new |
65 swapped = true | 56 swapped = true |
66 runtime.RaceReleaseMerge(unsafe.Pointer(val)) | 57 runtime.RaceReleaseMerge(unsafe.Pointer(val)) |
67 } | 58 } |
68 runtime.RaceSemrelease(&mtx) | 59 runtime.RaceSemrelease(&mtx) |
69 return | 60 return |
70 } | 61 } |
71 | 62 |
72 func CompareAndSwapUintptr(val *uintptr, old, new uintptr) (swapped bool) { | 63 func CompareAndSwapUintptr(val *uintptr, old, new uintptr) (swapped bool) { |
73 pc := make([]uintptr, 1) | |
74 runtime.Callers(2, pc) | |
75 | |
76 swapped = false | 64 swapped = false |
77 runtime.RaceSemacquire(&mtx) | 65 runtime.RaceSemacquire(&mtx) |
78 runtime.RaceAcquire(unsafe.Pointer(val)) | 66 runtime.RaceAcquire(unsafe.Pointer(val)) |
79 if *val == old { | 67 if *val == old { |
80 *val = new | 68 *val = new |
81 swapped = true | 69 swapped = true |
82 runtime.RaceReleaseMerge(unsafe.Pointer(val)) | 70 runtime.RaceReleaseMerge(unsafe.Pointer(val)) |
83 } | 71 } |
84 runtime.RaceSemrelease(&mtx) | 72 runtime.RaceSemrelease(&mtx) |
85 return | 73 return |
86 } | 74 } |
87 | 75 |
88 func AddInt32(val *int32, delta int32) int32 { | 76 func AddInt32(val *int32, delta int32) int32 { |
89 return int32(AddUint32((*uint32)(unsafe.Pointer(val)), uint32(delta))) | 77 return int32(AddUint32((*uint32)(unsafe.Pointer(val)), uint32(delta))) |
90 } | 78 } |
91 | 79 |
92 func AddUint32(val *uint32, delta uint32) (new uint32) { | 80 func AddUint32(val *uint32, delta uint32) (new uint32) { |
93 pc := make([]uintptr, 1) | |
94 runtime.Callers(2, pc) | |
95 | |
96 runtime.RaceSemacquire(&mtx) | 81 runtime.RaceSemacquire(&mtx) |
97 runtime.RaceAcquire(unsafe.Pointer(val)) | 82 runtime.RaceAcquire(unsafe.Pointer(val)) |
98 *val = *val + delta | 83 *val = *val + delta |
99 new = *val | 84 new = *val |
100 runtime.RaceReleaseMerge(unsafe.Pointer(val)) | 85 runtime.RaceReleaseMerge(unsafe.Pointer(val)) |
101 runtime.RaceSemrelease(&mtx) | 86 runtime.RaceSemrelease(&mtx) |
102 | 87 |
103 return | 88 return |
104 } | 89 } |
105 | 90 |
106 func AddInt64(val *int64, delta int64) int64 { | 91 func AddInt64(val *int64, delta int64) int64 { |
107 return int64(AddUint64((*uint64)(unsafe.Pointer(val)), uint64(delta))) | 92 return int64(AddUint64((*uint64)(unsafe.Pointer(val)), uint64(delta))) |
108 } | 93 } |
109 | 94 |
110 func AddUint64(val *uint64, delta uint64) (new uint64) { | 95 func AddUint64(val *uint64, delta uint64) (new uint64) { |
111 pc := make([]uintptr, 1) | |
112 runtime.Callers(2, pc) | |
113 runtime.RaceSemacquire(&mtx) | 96 runtime.RaceSemacquire(&mtx) |
114 runtime.RaceAcquire(unsafe.Pointer(val)) | 97 runtime.RaceAcquire(unsafe.Pointer(val)) |
115 *val = *val + delta | 98 *val = *val + delta |
116 new = *val | 99 new = *val |
117 runtime.RaceReleaseMerge(unsafe.Pointer(val)) | 100 runtime.RaceReleaseMerge(unsafe.Pointer(val)) |
118 runtime.RaceSemrelease(&mtx) | 101 runtime.RaceSemrelease(&mtx) |
119 | 102 |
120 return | 103 return |
121 } | 104 } |
122 | 105 |
123 func AddUintptr(val *uintptr, delta uintptr) (new uintptr) { | 106 func AddUintptr(val *uintptr, delta uintptr) (new uintptr) { |
124 pc := make([]uintptr, 1) | |
125 runtime.Callers(2, pc) | |
126 runtime.RaceSemacquire(&mtx) | 107 runtime.RaceSemacquire(&mtx) |
127 runtime.RaceAcquire(unsafe.Pointer(val)) | 108 runtime.RaceAcquire(unsafe.Pointer(val)) |
128 *val = *val + delta | 109 *val = *val + delta |
129 new = *val | 110 new = *val |
130 runtime.RaceReleaseMerge(unsafe.Pointer(val)) | 111 runtime.RaceReleaseMerge(unsafe.Pointer(val)) |
131 runtime.RaceSemrelease(&mtx) | 112 runtime.RaceSemrelease(&mtx) |
132 | 113 |
133 return | 114 return |
134 } | 115 } |
135 | 116 |
136 func LoadInt32(addr *int32) int32 { | 117 func LoadInt32(addr *int32) int32 { |
137 return int32(LoadUint32((*uint32)(unsafe.Pointer(addr)))) | 118 return int32(LoadUint32((*uint32)(unsafe.Pointer(addr)))) |
138 } | 119 } |
139 | 120 |
140 func LoadUint32(addr *uint32) (val uint32) { | 121 func LoadUint32(addr *uint32) (val uint32) { |
141 pc := make([]uintptr, 1) | |
142 runtime.Callers(2, pc) | |
143 | |
144 runtime.RaceSemacquire(&mtx) | 122 runtime.RaceSemacquire(&mtx) |
145 runtime.RaceAcquire(unsafe.Pointer(addr)) | 123 runtime.RaceAcquire(unsafe.Pointer(addr)) |
146 val = *addr | 124 val = *addr |
147 runtime.RaceSemrelease(&mtx) | 125 runtime.RaceSemrelease(&mtx) |
148 return | 126 return |
149 } | 127 } |
150 | 128 |
151 func LoadInt64(addr *int64) int64 { | 129 func LoadInt64(addr *int64) int64 { |
152 return int64(LoadUint64((*uint64)(unsafe.Pointer(addr)))) | 130 return int64(LoadUint64((*uint64)(unsafe.Pointer(addr)))) |
153 } | 131 } |
154 | 132 |
155 func LoadUint64(addr *uint64) (val uint64) { | 133 func LoadUint64(addr *uint64) (val uint64) { |
156 pc := make([]uintptr, 1) | |
157 runtime.Callers(2, pc) | |
158 | |
159 runtime.RaceSemacquire(&mtx) | 134 runtime.RaceSemacquire(&mtx) |
160 runtime.RaceAcquire(unsafe.Pointer(addr)) | 135 runtime.RaceAcquire(unsafe.Pointer(addr)) |
161 val = *addr | 136 val = *addr |
162 runtime.RaceSemrelease(&mtx) | 137 runtime.RaceSemrelease(&mtx) |
163 return | 138 return |
164 } | 139 } |
165 | 140 |
166 func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer) { | 141 func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer) { |
167 pc := make([]uintptr, 1) | |
168 runtime.Callers(2, pc) | |
169 | |
170 runtime.RaceSemacquire(&mtx) | 142 runtime.RaceSemacquire(&mtx) |
171 runtime.RaceAcquire(unsafe.Pointer(addr)) | 143 runtime.RaceAcquire(unsafe.Pointer(addr)) |
172 val = *addr | 144 val = *addr |
173 runtime.RaceSemrelease(&mtx) | 145 runtime.RaceSemrelease(&mtx) |
174 return | 146 return |
175 } | 147 } |
176 | 148 |
177 func LoadUintptr(addr *uintptr) (val uintptr) { | 149 func LoadUintptr(addr *uintptr) (val uintptr) { |
178 pc := make([]uintptr, 1) | |
179 runtime.Callers(2, pc) | |
180 | |
181 runtime.RaceSemacquire(&mtx) | 150 runtime.RaceSemacquire(&mtx) |
182 runtime.RaceAcquire(unsafe.Pointer(addr)) | 151 runtime.RaceAcquire(unsafe.Pointer(addr)) |
183 val = *addr | 152 val = *addr |
184 runtime.RaceSemrelease(&mtx) | 153 runtime.RaceSemrelease(&mtx) |
185 return | 154 return |
186 } | 155 } |
187 | 156 |
188 func StoreInt32(addr *int32, val int32) { | 157 func StoreInt32(addr *int32, val int32) { |
189 StoreUint32((*uint32)(unsafe.Pointer(addr)), uint32(val)) | 158 StoreUint32((*uint32)(unsafe.Pointer(addr)), uint32(val)) |
190 } | 159 } |
191 | 160 |
192 func StoreUint32(addr *uint32, val uint32) { | 161 func StoreUint32(addr *uint32, val uint32) { |
193 pc := make([]uintptr, 1) | |
194 runtime.Callers(2, pc) | |
195 | |
196 runtime.RaceSemacquire(&mtx) | 162 runtime.RaceSemacquire(&mtx) |
197 *addr = val | 163 *addr = val |
198 runtime.RaceRelease(unsafe.Pointer(addr)) | 164 runtime.RaceRelease(unsafe.Pointer(addr)) |
199 runtime.RaceSemrelease(&mtx) | 165 runtime.RaceSemrelease(&mtx) |
200 } | 166 } |
201 | 167 |
202 func StoreInt64(addr *int64, val int64) { | 168 func StoreInt64(addr *int64, val int64) { |
203 StoreUint64((*uint64)(unsafe.Pointer(addr)), uint64(val)) | 169 StoreUint64((*uint64)(unsafe.Pointer(addr)), uint64(val)) |
204 } | 170 } |
205 | 171 |
206 func StoreUint64(addr *uint64, val uint64) { | 172 func StoreUint64(addr *uint64, val uint64) { |
207 pc := make([]uintptr, 1) | |
208 runtime.Callers(2, pc) | |
209 | |
210 runtime.RaceSemacquire(&mtx) | 173 runtime.RaceSemacquire(&mtx) |
211 *addr = val | 174 *addr = val |
212 runtime.RaceRelease(unsafe.Pointer(addr)) | 175 runtime.RaceRelease(unsafe.Pointer(addr)) |
213 runtime.RaceSemrelease(&mtx) | 176 runtime.RaceSemrelease(&mtx) |
214 } | 177 } |
215 | 178 |
216 func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) { | 179 func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) { |
217 pc := make([]uintptr, 1) | |
218 runtime.Callers(2, pc) | |
219 | |
220 runtime.RaceSemacquire(&mtx) | 180 runtime.RaceSemacquire(&mtx) |
221 *addr = val | 181 *addr = val |
222 runtime.RaceRelease(unsafe.Pointer(addr)) | 182 runtime.RaceRelease(unsafe.Pointer(addr)) |
223 runtime.RaceSemrelease(&mtx) | 183 runtime.RaceSemrelease(&mtx) |
224 } | 184 } |
225 | 185 |
226 func StoreUintptr(addr *uintptr, val uintptr) { | 186 func StoreUintptr(addr *uintptr, val uintptr) { |
227 pc := make([]uintptr, 1) | |
228 runtime.Callers(2, pc) | |
229 | |
230 runtime.RaceSemacquire(&mtx) | 187 runtime.RaceSemacquire(&mtx) |
231 *addr = val | 188 *addr = val |
232 runtime.RaceRelease(unsafe.Pointer(addr)) | 189 runtime.RaceRelease(unsafe.Pointer(addr)) |
233 runtime.RaceSemrelease(&mtx) | 190 runtime.RaceSemrelease(&mtx) |
234 } | 191 } |
LEFT | RIGHT |