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));
86 #error missing definition of a_cas
91 static inline int a_swap(volatile int *p, int v)
95 while (a_cas(p, old, v) != old);
101 #define a_fetch_add a_fetch_add
102 static inline int a_fetch_add(volatile int *p, int v)
106 while (a_cas(p, old, (unsigned)old+v) != old);
112 #define a_fetch_and a_fetch_and
113 static inline int a_fetch_and(volatile int *p, int v)
117 while (a_cas(p, old, old&v) != old);
122 #define a_fetch_or a_fetch_or
123 static inline int a_fetch_or(volatile int *p, int v)
127 while (a_cas(p, old, old|v) != old);
134 static inline void a_and(volatile int *p, int v)
142 static inline void a_or(volatile int *p, int v)
150 static inline void a_inc(volatile int *p)
158 static inline void a_dec(volatile int *p)
165 #define a_store a_store
166 static inline void a_store(volatile int *p, int v)
179 #define a_barrier a_barrier
180 static void a_barrier()
182 volatile int tmp = 0;
188 #define a_spin a_barrier
192 #define a_and_64 a_and_64
193 static inline void a_and_64(volatile uint64_t *p, uint64_t v)
195 union { uint64_t v; uint32_t r[2]; } u = { v };
196 if (u.r[0]+1) a_and((int *)p, u.r[0]);
197 if (u.r[1]+1) a_and((int *)p+1, u.r[1]);
202 #define a_or_64 a_or_64
203 static inline void a_or_64(volatile uint64_t *p, uint64_t v)
205 union { uint64_t v; uint32_t r[2]; } u = { v };
206 if (u.r[0]) a_or((int *)p, u.r[0]);
207 if (u.r[1]) a_or((int *)p+1, u.r[1]);
212 #define a_cas_p a_cas_p
213 static inline void *a_cas_p(volatile void *p, void *t, void *s)
215 return (void *)a_cas((volatile int *)p, (int)t, (int)s);
220 #define a_or_l a_or_l
221 static inline void a_or_l(volatile void *p, long v)
223 if (sizeof(long) == sizeof(int)) a_or(p, v);
229 #define a_crash a_crash
230 static inline void a_crash()
232 *(volatile char *)0=0;
237 #define a_ctz_64 a_ctz_64
238 static inline int a_ctz_64(uint64_t x)
240 static const char debruijn64[64] = {
241 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
242 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
243 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
244 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
246 static const char debruijn32[32] = {
247 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
248 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
250 if (sizeof(long) < 8) {
254 return 32 + debruijn32[(y&-y)*0x076be629 >> 27];
256 return debruijn32[(y&-y)*0x076be629 >> 27];
258 return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58];
263 #define a_ctz_l a_ctz_l
264 static inline int a_ctz_l(unsigned long x)
266 static const char debruijn32[32] = {
267 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
268 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
270 if (sizeof(long) == 8) return a_ctz_64(x);
271 return debruijn32[(x&-x)*0x076be629 >> 27];