23 #ifndef PLATFORM_HPP__
24 #define PLATFORM_HPP__
26 #include <stm/config.h>
46 #define CACHELINE_BYTES 64
47 #define NORETURN __attribute__((noreturn))
48 #define NOINLINE __attribute__((noinline))
49 #define ALWAYS_INLINE __attribute__((always_inline))
50 #define USED __attribute__((used))
51 #define REGPARM(N) __attribute__((regparm(N)))
67 #if defined(__LP64__) && defined(STM_CPU_X86)
70 #define GCC_FASTCALL __attribute__((fastcall))
76 #if !defined(STM_CC_GCC) || !defined(STM_CPU_SPARC)
77 #define TM_INLINE ALWAYS_INLINE
82 #if defined(STM_CPU_X86) && !defined(STM_CC_SUN)
83 #define TM_FASTCALL REGPARM(3)
88 #define TM_ALIGN(N) __attribute__((aligned(N)))
102 #if defined(STM_CPU_X86) && defined(__ICC)
111 #if defined(STM_CPU_X86) && !defined(STM_CC_SUN)
113 #define CFENCE __asm__ volatile ("":::"memory")
114 #define WBR __sync_synchronize()
116 #define cas32(p, o, n) __sync_val_compare_and_swap(p, o, n)
117 #define cas64(p, o, n) __sync_val_compare_and_swap(p, o, n)
118 #define casptr(p, o, n) __sync_val_compare_and_swap(p, o, n)
119 #define bcas32(p, o, n) __sync_bool_compare_and_swap(p, o, n)
120 #define bcas64(p, o, n) __sync_bool_compare_and_swap(p, o, n)
121 #define bcasptr(p, o, n) __sync_bool_compare_and_swap(p, o, n)
123 #define tas(p) __sync_lock_test_and_set(p, 1)
125 #define nop() __asm__ volatile("nop")
128 #define atomicswap8(p, v) __sync_lock_test_and_set(p, v)
129 #define atomicswap32(p, v) __sync_lock_test_and_set(p, v)
130 #define atomicswap64(p, v) __sync_lock_test_and_set(p, v)
131 #define atomicswapptr(p, v) __sync_lock_test_and_set(p, v)
133 #define fai32(p) __sync_fetch_and_add(p, 1)
134 #define fai64(p) __sync_fetch_and_add(p, 1)
135 #define faiptr(p) __sync_fetch_and_add(p, 1)
136 #define faa32(p, a) __sync_fetch_and_add(p, a)
137 #define faa64(p, a) __sync_fetch_and_add(p, a)
138 #define faaptr(p, a) __sync_fetch_and_add(p, a)
151 #if defined(STM_CPU_SPARC) && defined (STM_CC_GCC)
152 #define CFENCE __asm__ volatile ("":::"memory")
153 #define WBR __sync_synchronize()
158 inline uint32_t internal_cas32(
volatile uint32_t*
ptr, uint32_t old,
161 __asm__
volatile(
"cas [%2], %3, %0"
163 :
"0"(_new),
"r"(
ptr),
"r"(old)
174 inline uint64_t internal_cas64(
volatile uint64_t*
ptr, uint64_t old,
177 __asm__
volatile(
"casx [%2], %3, %0"
179 :
"0"(_new),
"r"(
ptr),
"r"(old)
184 #define cas32(p, o, n) internal_cas32((uint32_t*)(p), (uint32_t)(o), (uint32_t)(n))
186 #define cas64(p, o, n) internal_cas64((uint64_t*)(p), (uint64_t)(o), (uint64_t)(n))
187 #define casptr(p, o, n) cas64(p, o, n)
189 #define cas64(p, o, n) __sync_val_compare_and_swap(p, o, n)
190 #define casptr(p, o, n) cas32(p, o, n)
193 #define bcas32(p, o, n) ({ o == cas32(p, (o), (n)); })
194 #define bcas64(p, o, n) ({ o == cas64(p, (o), (n)); })
195 #define bcasptr(p, o, n) ({ ((void*)o) == (void*)casptr(p, (o), (n)); })
197 #define tas(p) __sync_lock_test_and_set(p, 1)
199 #define nop() __asm__ volatile("nop")
203 #define atomicswapptr(p, v) \
205 __typeof((v)) v1 = v; \
206 __typeof((p)) p1 = p; \
207 __asm__ volatile("swap [%2], %0;" \
208 :"=r"(v1) :"0"(v1), "r"(p1):"memory"); \
212 #define atomicswapptr(p, v) \
217 if (bcasptr((p), tmp, (v))) break; \
224 ({ __typeof(*p) _f, _e; \
226 while ((_f = (__typeof(*p))cas32(p, _e, (_e+a))) != _e); \
229 #define fai32(p) faa32(p,1)
230 #define faiptr(p) __sync_fetch_and_add(p, 1)
231 #define faa64(p, a) __sync_fetch_and_add(p, a)
232 #define faaptr(p, a) __sync_fetch_and_add(p, a)
239 #if (defined(STM_CPU_X86) || defined(STM_CPU_SPARC)) && defined(STM_CC_SUN)
241 #define CFENCE __asm__ volatile("":::"memory")
242 #define WBR membar_enter()
244 #define cas32(p, o, n) atomic_cas_32(p, (o), (n))
245 #define cas64(p, o, n) atomic_cas_64(p, (o), (n))
246 #define casptr(p, o, n) atomic_cas_ptr(p, (void*)(o), (void*)(n))
247 #define bcas32(p, o, n) ({ o == cas32(p, (o), (n)); })
248 #define bcas64(p, o, n) ({ o == cas64(p, (o), (n)); })
249 #define bcasptr(p, o, n) ({ ((void*)o) == casptr(p, (o), (n)); })
251 #define tas(p) atomic_set_long_excl((volatile unsigned long*)p, 0)
253 #define nop() __asm__ volatile("nop")
255 #define atomicswap8(p, v) atomic_swap_8(p, v)
256 #define atomicswap32(p, v) atomic_swap_32(p, v)
257 #define atomicswap64(p, v) atomic_swap_64(p, v)
258 #define atomicswapptr(p, v) atomic_swap_ptr(p, (void*)(v))
260 #define fai32(p) (atomic_inc_32_nv(p)-1)
261 #define fai64(p) __sync_fetch_and_add(p, 1)
262 #define faiptr(p) (atomic_inc_ulong_nv((volatile unsigned long*)p)-1)
263 #define faa32(p, a) atomic_add_32(p, a)
264 #define faa64(p, a) atomic_add_64(p, a)
265 #define faaptr(p, a) atomic_add_long((volatile unsigned long*)p, a)
268 #define __builtin_expect(a, b) a
278 #if defined(STM_BITS_64)
282 inline void mvx(
const volatile uint64_t* src,
volatile uint64_t* dest)
288 #if defined(STM_BITS_32) && defined(STM_CPU_X86)
292 inline void mvx(
const volatile uint64_t* src,
volatile uint64_t* dest)
294 const volatile double* srcd = (
const volatile double*)src;
295 volatile double* destd = (
volatile double*)dest;
300 #if defined(STM_BITS_32) && defined(STM_CPU_SPARC)
304 inline void mvx(
const volatile uint64_t* from,
volatile uint64_t* to)
306 __asm__
volatile(
"ldx [%0], %%o4;"
308 ::
"r"(from),
"r"(to)
318 #if defined(STM_CPU_X86)
322 inline uint64_t tick()
325 __asm__ (
"rdtsc" :
"=a" (tmp[1]),
"=d" (tmp[0]) :
"c" (0x10) );
326 return (((uint64_t)tmp[0]) << 32) | tmp[1];
330 #if defined(STM_CPU_SPARC) && defined(STM_BITS_64)
337 inline uint64_t tick()
340 __asm__
volatile(
"rd %%tick, %[val]" : [val]
"=r" (val) : :);
345 #if defined(STM_CPU_SPARC) && defined(STM_BITS_32)
355 inline uint64_t tick()
357 uint32_t lo = 0, hi = 0;
358 __asm__
volatile(
"rd %%tick, %%o2;"
359 "srlx %%o2, 32, %[high];"
360 "sra %%o2, 0, %[low];"
380 inline void sleep_ms(uint32_t ms) { usleep(ms*1000); }
387 #if defined(STM_OS_LINUX)
397 inline void yield_cpu() { pthread_yield(); }
405 inline uint64_t getElapsedTime()
408 clock_gettime(CLOCK_REALTIME, &t);
410 uint64_t tt = (((
long long)t.tv_sec) * 1000000000L) + ((
long long)t.tv_nsec);
414 #endif // STM_OS_LINUX
416 #if defined(STM_OS_SOLARIS)
417 #include <sys/time.h>
422 inline void yield_cpu() { yield(); }
427 inline uint64_t getElapsedTime()
432 #endif // STM_OS_SOLARIS
434 #if defined(STM_OS_MACOS)
435 #include <mach/mach_time.h>
441 inline void yield_cpu() {
451 inline uint64_t getElapsedTime()
453 static mach_timebase_info_data_t sTimebaseInfo;
454 if (sTimebaseInfo.denom == 0)
455 (void)mach_timebase_info(&sTimebaseInfo);
456 return mach_absolute_time() * sTimebaseInfo.numer / sTimebaseInfo.denom;
459 #endif // STM_OS_MACOS
461 #endif // PLATFORM_HPP__
void *volatile ptr
Definition: counted_ptr.hpp:57