|
28 | 28 |
|
29 | 29 | #include <stdbool.h>
|
30 | 30 | #include <stdint.h>
|
31 |
| -#include <nuttx/spinlock.h> |
| 31 | +#include <nuttx/irq.h> |
| 32 | +#include <nuttx/mutex.h> |
| 33 | + |
| 34 | +/**************************************************************************** |
| 35 | + * Private Data |
| 36 | + ****************************************************************************/ |
| 37 | + |
| 38 | +#ifdef CONFIG_SMP |
| 39 | +static mutex_t g_atomic_lock = NXMUTEX_INITIALIZER; |
| 40 | + |
| 41 | +static inline irqstate_t atomic_lock(void) |
| 42 | +{ |
| 43 | + return nxmutex_lock(&g_atomic_lock); |
| 44 | +} |
| 45 | + |
| 46 | +static inline void atomic_unlock(irqstate_t flags) |
| 47 | +{ |
| 48 | + UNUSED(flags); |
| 49 | + nxmutex_unlock(&g_atomic_lock); |
| 50 | +} |
| 51 | +#else |
| 52 | +static inline irqstate_t atomic_lock(void) |
| 53 | +{ |
| 54 | + return up_irq_save(); |
| 55 | +} |
| 56 | + |
| 57 | +static inline void atomic_unlock(irqstate_t flags) |
| 58 | +{ |
| 59 | + up_irq_restore(flags); |
| 60 | +} |
| 61 | +#endif |
32 | 62 |
|
33 | 63 | /****************************************************************************
|
34 | 64 | * Pre-processor Definitions
|
|
39 | 69 | void weak_function __atomic_store_##n (FAR volatile void *ptr, \
|
40 | 70 | type value, int memorder) \
|
41 | 71 | { \
|
42 |
| - irqstate_t irqstate = spin_lock_irqsave(NULL); \ |
| 72 | + irqstate_t irqstate = atomic_lock(); \ |
43 | 73 | \
|
44 | 74 | *(FAR type *)ptr = value; \
|
45 | 75 | \
|
46 |
| - spin_unlock_irqrestore(NULL, irqstate); \ |
| 76 | + atomic_unlock(irqstate); \ |
47 | 77 | }
|
48 | 78 |
|
49 | 79 | #define LOAD(n, type) \
|
50 | 80 | \
|
51 | 81 | type weak_function __atomic_load_##n (FAR const volatile void *ptr, \
|
52 | 82 | int memorder) \
|
53 | 83 | { \
|
54 |
| - irqstate_t irqstate = spin_lock_irqsave(NULL); \ |
| 84 | + irqstate_t irqstate = atomic_lock(); \ |
55 | 85 | \
|
56 | 86 | type ret = *(FAR type *)ptr; \
|
57 | 87 | \
|
58 |
| - spin_unlock_irqrestore(NULL, irqstate); \ |
| 88 | + atomic_unlock(irqstate); \ |
59 | 89 | return ret; \
|
60 | 90 | }
|
61 | 91 |
|
|
64 | 94 | type weak_function __atomic_exchange_##n (FAR volatile void *ptr, \
|
65 | 95 | type value, int memorder) \
|
66 | 96 | { \
|
67 |
| - irqstate_t irqstate = spin_lock_irqsave(NULL); \ |
| 97 | + irqstate_t irqstate = atomic_lock(); \ |
68 | 98 | FAR type *tmp = (FAR type *)ptr; \
|
69 | 99 | \
|
70 | 100 | type ret = *tmp; \
|
71 | 101 | *tmp = value; \
|
72 | 102 | \
|
73 |
| - spin_unlock_irqrestore(NULL, irqstate); \ |
| 103 | + atomic_unlock(irqstate); \ |
74 | 104 | return ret; \
|
75 | 105 | }
|
76 | 106 |
|
|
82 | 112 | int success, int failure) \
|
83 | 113 | { \
|
84 | 114 | bool ret = false; \
|
85 |
| - irqstate_t irqstate = spin_lock_irqsave(NULL); \ |
| 115 | + irqstate_t irqstate = atomic_lock(); \ |
86 | 116 | FAR type *tmpmem = (FAR type *)mem; \
|
87 | 117 | FAR type *tmpexp = (FAR type *)expect; \
|
88 | 118 | \
|
|
96 | 126 | *tmpexp = *tmpmem; \
|
97 | 127 | } \
|
98 | 128 | \
|
99 |
| - spin_unlock_irqrestore(NULL, irqstate); \ |
| 129 | + atomic_unlock(irqstate); \ |
100 | 130 | return ret; \
|
101 | 131 | }
|
102 | 132 |
|
|
105 | 135 | type weak_function __atomic_flags_test_and_set##n (FAR volatile void *ptr, \
|
106 | 136 | int memorder) \
|
107 | 137 | { \
|
108 |
| - irqstate_t irqstate = spin_lock_irqsave(NULL); \ |
| 138 | + irqstate_t irqstate = atomic_lock(); \ |
109 | 139 | FAR type *tmp = (FAR type *)ptr; \
|
110 | 140 | type ret = *tmp; \
|
111 | 141 | \
|
112 | 142 | *(FAR type *)ptr = 1; \
|
113 | 143 | \
|
114 |
| - spin_unlock_irqrestore(NULL, irqstate); \ |
| 144 | + atomic_unlock(irqstate); \ |
115 | 145 | return ret; \
|
116 | 146 | }
|
117 | 147 |
|
|
120 | 150 | type weak_function __atomic_fetch_add_##n (FAR volatile void *ptr, \
|
121 | 151 | type value, int memorder) \
|
122 | 152 | { \
|
123 |
| - irqstate_t irqstate = spin_lock_irqsave(NULL); \ |
| 153 | + irqstate_t irqstate = atomic_lock(); \ |
124 | 154 | FAR type *tmp = (FAR type *)ptr; \
|
125 | 155 | type ret = *tmp; \
|
126 | 156 | \
|
127 | 157 | *tmp = *tmp + value; \
|
128 | 158 | \
|
129 |
| - spin_unlock_irqrestore(NULL, irqstate); \ |
| 159 | + atomic_unlock(irqstate); \ |
130 | 160 | return ret; \
|
131 | 161 | }
|
132 | 162 |
|
|
135 | 165 | type weak_function __atomic_fetch_sub_##n (FAR volatile void *ptr, \
|
136 | 166 | type value, int memorder) \
|
137 | 167 | { \
|
138 |
| - irqstate_t irqstate = spin_lock_irqsave(NULL); \ |
| 168 | + irqstate_t irqstate = atomic_lock(); \ |
139 | 169 | FAR type *tmp = (FAR type *)ptr; \
|
140 | 170 | type ret = *tmp; \
|
141 | 171 | \
|
142 | 172 | *tmp = *tmp - value; \
|
143 | 173 | \
|
144 |
| - spin_unlock_irqrestore(NULL, irqstate); \ |
| 174 | + atomic_unlock(irqstate); \ |
145 | 175 | return ret; \
|
146 | 176 | }
|
147 | 177 |
|
|
150 | 180 | type weak_function __atomic_fetch_and_##n (FAR volatile void *ptr, \
|
151 | 181 | type value, int memorder) \
|
152 | 182 | { \
|
153 |
| - irqstate_t irqstate = spin_lock_irqsave(NULL); \ |
| 183 | + irqstate_t irqstate = atomic_lock(); \ |
154 | 184 | FAR type *tmp = (FAR type *)ptr; \
|
155 | 185 | type ret = *tmp; \
|
156 | 186 | \
|
157 | 187 | *tmp = *tmp & value; \
|
158 | 188 | \
|
159 |
| - spin_unlock_irqrestore(NULL, irqstate); \ |
| 189 | + atomic_unlock(irqstate); \ |
160 | 190 | return ret; \
|
161 | 191 | }
|
162 | 192 |
|
|
165 | 195 | type weak_function __atomic_fetch_or_##n (FAR volatile void *ptr, \
|
166 | 196 | type value, int memorder) \
|
167 | 197 | { \
|
168 |
| - irqstate_t irqstate = spin_lock_irqsave(NULL); \ |
| 198 | + irqstate_t irqstate = atomic_lock(); \ |
169 | 199 | FAR type *tmp = (FAR type *)ptr; \
|
170 | 200 | type ret = *tmp; \
|
171 | 201 | \
|
172 | 202 | *tmp = *tmp | value; \
|
173 | 203 | \
|
174 |
| - spin_unlock_irqrestore(NULL, irqstate); \ |
| 204 | + atomic_unlock(irqstate); \ |
175 | 205 | return ret; \
|
176 | 206 | }
|
177 | 207 |
|
|
180 | 210 | type weak_function __atomic_fetch_xor_##n (FAR volatile void *ptr, \
|
181 | 211 | type value, int memorder) \
|
182 | 212 | { \
|
183 |
| - irqstate_t irqstate = spin_lock_irqsave(NULL); \ |
| 213 | + irqstate_t irqstate = atomic_lock(); \ |
184 | 214 | FAR type *tmp = (FAR type *)ptr; \
|
185 | 215 | type ret = *tmp; \
|
186 | 216 | \
|
187 | 217 | *tmp = *tmp ^ value; \
|
188 | 218 | \
|
189 |
| - spin_unlock_irqrestore(NULL, irqstate); \ |
| 219 | + atomic_unlock(irqstate); \ |
190 | 220 | return ret; \
|
191 | 221 | }
|
192 | 222 |
|
|
195 | 225 | type weak_function __sync_add_and_fetch_##n (FAR volatile void *ptr, \
|
196 | 226 | type value) \
|
197 | 227 | { \
|
198 |
| - irqstate_t irqstate = spin_lock_irqsave(NULL); \ |
| 228 | + irqstate_t irqstate = atomic_lock(); \ |
199 | 229 | FAR type *tmp = (FAR type *)ptr; \
|
200 | 230 | \
|
201 | 231 | *tmp = *tmp + value; \
|
202 | 232 | \
|
203 |
| - spin_unlock_irqrestore(NULL, irqstate); \ |
| 233 | + atomic_unlock(irqstate); \ |
204 | 234 | return *tmp; \
|
205 | 235 | }
|
206 | 236 |
|
|
209 | 239 | type weak_function __sync_sub_and_fetch_##n (FAR volatile void *ptr, \
|
210 | 240 | type value) \
|
211 | 241 | { \
|
212 |
| - irqstate_t irqstate = spin_lock_irqsave(NULL); \ |
| 242 | + irqstate_t irqstate = atomic_lock(); \ |
213 | 243 | FAR type *tmp = (FAR type *)ptr; \
|
214 | 244 | \
|
215 | 245 | *tmp = *tmp - value; \
|
216 | 246 | \
|
217 |
| - spin_unlock_irqrestore(NULL, irqstate); \ |
| 247 | + atomic_unlock(irqstate); \ |
218 | 248 | return *tmp; \
|
219 | 249 | }
|
220 | 250 |
|
|
223 | 253 | type weak_function __sync_or_and_fetch_##n (FAR volatile void *ptr, \
|
224 | 254 | type value) \
|
225 | 255 | { \
|
226 |
| - irqstate_t irqstate = spin_lock_irqsave(NULL); \ |
| 256 | + irqstate_t irqstate = atomic_lock(); \ |
227 | 257 | FAR type *tmp = (FAR type *)ptr; \
|
228 | 258 | \
|
229 | 259 | *tmp = *tmp | value; \
|
230 | 260 | \
|
231 |
| - spin_unlock_irqrestore(NULL, irqstate); \ |
| 261 | + atomic_unlock(irqstate); \ |
232 | 262 | return *tmp; \
|
233 | 263 | }
|
234 | 264 |
|
|
237 | 267 | type weak_function __sync_and_and_fetch_##n (FAR volatile void *ptr, \
|
238 | 268 | type value) \
|
239 | 269 | { \
|
240 |
| - irqstate_t irqstate = spin_lock_irqsave(NULL); \ |
| 270 | + irqstate_t irqstate = atomic_lock(); \ |
241 | 271 | FAR type *tmp = (FAR type *)ptr; \
|
242 | 272 | \
|
243 | 273 | *tmp = *tmp & value; \
|
244 | 274 | \
|
245 |
| - spin_unlock_irqrestore(NULL, irqstate); \ |
| 275 | + atomic_unlock(irqstate); \ |
246 | 276 | return *tmp; \
|
247 | 277 | }
|
248 | 278 |
|
|
251 | 281 | type weak_function __sync_xor_and_fetch_##n (FAR volatile void *ptr, \
|
252 | 282 | type value) \
|
253 | 283 | { \
|
254 |
| - irqstate_t irqstate = spin_lock_irqsave(NULL); \ |
| 284 | + irqstate_t irqstate = atomic_lock(); \ |
255 | 285 | FAR type *tmp = (FAR type *)ptr; \
|
256 | 286 | \
|
257 | 287 | *tmp = *tmp ^ value; \
|
258 | 288 | \
|
259 |
| - spin_unlock_irqrestore(NULL, irqstate); \ |
| 289 | + atomic_unlock(irqstate); \ |
260 | 290 | return *tmp; \
|
261 | 291 | }
|
262 | 292 |
|
|
265 | 295 | type weak_function __sync_nand_and_fetch_##n (FAR volatile void *ptr, \
|
266 | 296 | type value) \
|
267 | 297 | { \
|
268 |
| - irqstate_t irqstate = spin_lock_irqsave(NULL); \ |
| 298 | + irqstate_t irqstate = atomic_lock(); \ |
269 | 299 | FAR type *tmp = (FAR type *)ptr; \
|
270 | 300 | \
|
271 | 301 | *tmp = ~(*tmp & value); \
|
272 | 302 | \
|
273 |
| - spin_unlock_irqrestore(NULL, irqstate); \ |
| 303 | + atomic_unlock(irqstate); \ |
274 | 304 | return *tmp; \
|
275 | 305 | }
|
276 | 306 |
|
|
281 | 311 | type newvalue) \
|
282 | 312 | { \
|
283 | 313 | bool ret = false; \
|
284 |
| - irqstate_t irqstate = spin_lock_irqsave(NULL); \ |
| 314 | + irqstate_t irqstate = atomic_lock(); \ |
285 | 315 | FAR type *tmp = (FAR type *)ptr; \
|
286 | 316 | \
|
287 | 317 | if (*tmp == oldvalue) \
|
|
290 | 320 | *tmp = newvalue; \
|
291 | 321 | } \
|
292 | 322 | \
|
293 |
| - spin_unlock_irqrestore(NULL, irqstate); \ |
| 323 | + atomic_unlock(irqstate); \ |
294 | 324 | return ret; \
|
295 | 325 | }
|
296 | 326 |
|
|
300 | 330 | type oldvalue, \
|
301 | 331 | type newvalue) \
|
302 | 332 | { \
|
303 |
| - irqstate_t irqstate = spin_lock_irqsave(NULL); \ |
| 333 | + irqstate_t irqstate = atomic_lock(); \ |
304 | 334 | FAR type *tmp = (FAR type *)ptr; \
|
305 | 335 | type ret = *tmp; \
|
306 | 336 | \
|
|
309 | 339 | *tmp = newvalue; \
|
310 | 340 | } \
|
311 | 341 | \
|
312 |
| - spin_unlock_irqrestore(NULL, irqstate); \ |
| 342 | + atomic_unlock(irqstate); \ |
313 | 343 | return ret; \
|
314 | 344 | }
|
315 | 345 |
|
|
0 commit comments