13#ifndef XTC_OS_ATOMIC_H
14#define XTC_OS_ATOMIC_H
18#if defined(__STDC_NO_ATOMICS__)
19# error "xtc requires C11 atomics; rebuild with a compiler that has <stdatomic.h>"
34#define __OS_ATOMIC_LOAD_DEFINE(suffix, T) \
36 __os_atomic_load_##suffix(const T *p) \
38 return atomic_load_explicit( \
39 (_Atomic T *)(uintptr_t)p, \
40 memory_order_seq_cst); \
43#define __OS_ATOMIC_STORE_DEFINE(suffix, T) \
45 __os_atomic_store_##suffix(T *p, T v) \
47 atomic_store_explicit( \
48 (_Atomic T *)p, v, memory_order_seq_cst); \
51#define __OS_ATOMIC_CAS_DEFINE(suffix, T) \
53 __os_atomic_cas_##suffix(T *p, T *expect, T desired) \
55 return atomic_compare_exchange_strong_explicit( \
56 (_Atomic T *)p, expect, desired, \
57 memory_order_seq_cst, memory_order_seq_cst); \
60#define __OS_ATOMIC_FETCH_ADD_DEFINE(suffix, T) \
62 __os_atomic_fetch_add_##suffix(T *p, T delta) \
64 return atomic_fetch_add_explicit( \
65 (_Atomic T *)p, delta, \
66 memory_order_seq_cst); \
69#define __OS_ATOMIC_DEFINE_ALL(suffix, T) \
70 __OS_ATOMIC_LOAD_DEFINE(suffix, T) \
71 __OS_ATOMIC_STORE_DEFINE(suffix, T) \
72 __OS_ATOMIC_CAS_DEFINE(suffix, T) \
73 __OS_ATOMIC_FETCH_ADD_DEFINE(suffix, T)
75__OS_ATOMIC_DEFINE_ALL(i32, int32_t)
76__OS_ATOMIC_DEFINE_ALL(i64, int64_t)
77__OS_ATOMIC_DEFINE_ALL(u32, uint32_t)
78__OS_ATOMIC_DEFINE_ALL(u64, uint64_t)
86__os_atomic_load_ptr(
void *
const *p)
88 return (
void *)(intptr_t)atomic_load_explicit(
89 (_Atomic intptr_t *)(uintptr_t)p, memory_order_seq_cst);
92__os_atomic_store_ptr(
void **p,
void *v)
94 atomic_store_explicit(
95 (_Atomic intptr_t *)p, (intptr_t)v, memory_order_seq_cst);
98__os_atomic_cas_ptr(
void **p,
void **expect,
void *desired)
100 intptr_t e = (intptr_t)*expect;
101 int ok = atomic_compare_exchange_strong_explicit(
102 (_Atomic intptr_t *)p, &e, (intptr_t)desired,
103 memory_order_seq_cst, memory_order_seq_cst);
104 if (!ok) *expect = (
void *)e;
109__os_atomic_fence(
void)
111 atomic_thread_fence(memory_order_seq_cst);
119#if defined(__x86_64__) || defined(__i386__)
120# define __os_pause() __asm__ __volatile__("pause" ::: "memory")
121#elif defined(__aarch64__)
122# define __os_pause() __asm__ __volatile__("yield" ::: "memory")
123#elif defined(__powerpc64__) || defined(__powerpc__)
124# define __os_pause() __asm__ __volatile__("or 27,27,27" ::: "memory")
126# define __os_pause() ((void)0)
129#undef __OS_ATOMIC_DEFINE_ALL
130#undef __OS_ATOMIC_FETCH_ADD_DEFINE
131#undef __OS_ATOMIC_CAS_DEFINE
132#undef __OS_ATOMIC_STORE_DEFINE
133#undef __OS_ATOMIC_LOAD_DEFINE