rt/include/rt/atomic.h

64 lines
2.1 KiB
C++

#pragma once
#include <stdatomic.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
/* Some C++ compilers don't support _Atomic as a qualifier and instead define
* _Atomic as a macro in stdatomic.h, in terms of std::atomic. */
#define rt_atomic(t) _Atomic(t)
#else
#define rt_atomic(t) t _Atomic
#endif
typedef rt_atomic(bool) rt_atomic_bool;
typedef rt_atomic(unsigned char) rt_atomic_uchar;
typedef rt_atomic(int) rt_atomic_int;
typedef rt_atomic(unsigned int) rt_atomic_uint;
typedef rt_atomic(long) rt_atomic_long;
typedef rt_atomic(unsigned long) rt_atomic_ulong;
typedef rt_atomic(size_t) rt_atomic_size_t;
typedef rt_atomic(uintptr_t) rt_atomic_uintptr_t;
typedef rt_atomic(uint32_t) rt_atomic_uint32_t;
#define rt_atomic_load atomic_load_explicit
#define rt_atomic_store atomic_store_explicit
#define rt_atomic_fetch_add atomic_fetch_add_explicit
#define rt_atomic_fetch_sub atomic_fetch_sub_explicit
#define rt_atomic_fetch_and atomic_fetch_and_explicit
#define rt_atomic_fetch_or atomic_fetch_or_explicit
#define rt_atomic_exchange atomic_exchange_explicit
#define rt_atomic_compare_exchange_weak atomic_compare_exchange_weak_explicit
#define rt_atomic_compare_exchange atomic_compare_exchange_strong_explicit
#define RT_ATOMIC_RELAXED memory_order_relaxed
#define RT_ATOMIC_CONSUME memory_order_consume
#define RT_ATOMIC_ACQUIRE memory_order_acquire
#define RT_ATOMIC_RELEASE memory_order_release
#define RT_ATOMIC_ACQ_REL memory_order_acq_rel
#define RT_ATOMIC_SEQ_CST memory_order_seq_cst
/* Work around a bug in gcc where atomic_flag operations silently don't
* generate atomic code on armv6-m rather than failing to link. The equivalent
* atomic_exchange operations on an atomic_bool work.
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107567 */
typedef rt_atomic_bool rt_atomic_flag;
#define RT_ATOMIC_FLAG_INIT false
#define rt_atomic_flag_test_and_set(f, mo) atomic_exchange_explicit(f, true, mo)
#define rt_atomic_flag_clear(f, mo) atomic_store_explicit(f, false, mo)
#ifdef __cplusplus
}
#endif