6 #include "atomic_arch.h"
20 static inline int a_cas(volatile int *p, int t, int s)
25 while (old==t && !a_sc(p, s));
33 static inline int a_swap(volatile int *p, int v)
45 #define a_fetch_add a_fetch_add
46 static inline int a_fetch_add(volatile int *p, int v)
51 while (!a_sc(p, (unsigned)old + v));
58 #define a_fetch_and a_fetch_and
59 static inline int a_fetch_and(volatile int *p, int v)
64 while (!a_sc(p, old & v));
71 #define a_fetch_or a_fetch_or
72 static inline int a_fetch_or(volatile int *p, int v)
77 while (!a_sc(p, old | v));
88 #define a_cas_p a_cas_p
89 static inline void *a_cas_p(volatile void *p, void *t, void *s)
94 while (old==t && !a_sc_p(p, s));
103 #error missing definition of a_cas
107 #define a_swap a_swap
108 static inline int a_swap(volatile int *p, int v)
112 while (a_cas(p, old, v) != old);
118 #define a_fetch_add a_fetch_add
119 static inline int a_fetch_add(volatile int *p, int v)
123 while (a_cas(p, old, (unsigned)old+v) != old);
129 #define a_fetch_and a_fetch_and
130 static inline int a_fetch_and(volatile int *p, int v)
134 while (a_cas(p, old, old&v) != old);
139 #define a_fetch_or a_fetch_or
140 static inline int a_fetch_or(volatile int *p, int v)
144 while (a_cas(p, old, old|v) != old);
151 static inline void a_and(volatile int *p, int v)
159 static inline void a_or(volatile int *p, int v)
167 static inline void a_inc(volatile int *p)
175 static inline void a_dec(volatile int *p)
182 #define a_store a_store
183 static inline void a_store(volatile int *p, int v)
196 #define a_barrier a_barrier
197 static void a_barrier()
199 volatile int tmp = 0;
205 #define a_spin a_barrier
209 #define a_and_64 a_and_64
210 static inline void a_and_64(volatile uint64_t *p, uint64_t v)
212 union { uint64_t v; uint32_t r[2]; } u = { v };
213 if (u.r[0]+1) a_and((int *)p, u.r[0]);
214 if (u.r[1]+1) a_and((int *)p+1, u.r[1]);
219 #define a_or_64 a_or_64
220 static inline void a_or_64(volatile uint64_t *p, uint64_t v)
222 union { uint64_t v; uint32_t r[2]; } u = { v };
223 if (u.r[0]) a_or((int *)p, u.r[0]);
224 if (u.r[1]) a_or((int *)p+1, u.r[1]);
229 typedef char a_cas_p_undefined_but_pointer_not_32bit[-sizeof(char) == 0xffffffff ? 1 : -1];
230 #define a_cas_p a_cas_p
231 static inline void *a_cas_p(volatile void *p, void *t, void *s)
233 return (void *)a_cas((volatile int *)p, (int)t, (int)s);
238 #define a_or_l a_or_l
239 static inline void a_or_l(volatile void *p, long v)
241 if (sizeof(long) == sizeof(int)) a_or(p, v);
247 #define a_crash a_crash
248 static inline void a_crash()
250 *(volatile char *)0=0;
255 #define a_ctz_64 a_ctz_64
256 static inline int a_ctz_64(uint64_t x)
258 static const char debruijn64[64] = {
259 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
260 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
261 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
262 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
264 static const char debruijn32[32] = {
265 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
266 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
268 if (sizeof(long) < 8) {
272 return 32 + debruijn32[(y&-y)*0x076be629 >> 27];
274 return debruijn32[(y&-y)*0x076be629 >> 27];
276 return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58];
281 #define a_ctz_l a_ctz_l
282 static inline int a_ctz_l(unsigned long x)
284 static const char debruijn32[32] = {
285 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
286 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
288 if (sizeof(long) == 8) return a_ctz_64(x);
289 return debruijn32[(x&-x)*0x076be629 >> 27];