freebsd-src/contrib/libcxxrt/atomic.h
Ed Maste 13da1af1cd libcxxrt: Update to upstream 698997bfde1f
Interesting fixes:

045c52c Mark __cxa_allocate_exception, __cxa_free_exception and
        __cxa_init_primary_exception noexcept.
8a2f123 Define _LIBCXXRT_NOEXCEPT in cxxabi.h and use it instead of
        throw()
9529236 Fix memory corruption in cpp_demangle_read_sname()
8f5c74e Add test cases, fix more bugs, and improve perf
391a3dc Add a simple implementation of __cxa_call_terminate
40e4fa2 mark std::terminate as noreturn and noexcept
5eede09 Print diagnostics in default std::terminate handler

Reviewed by:	dim
Sponsored by:	The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D47238
2024-10-22 19:43:54 -04:00

103 lines
2.0 KiB
C++

#ifndef __has_builtin
# define __has_builtin(x) 0
#endif
#ifndef __has_feature
# define __has_feature(x) 0
#endif
#ifndef __has_extension
# define __has_extension(x) 0
#endif
#if !__has_extension(c_atomic)
# define _Atomic(T) T
#endif
#if __has_builtin(__c11_atomic_exchange)
# define ATOMIC_BUILTIN(name) __c11_atomic_##name
#else
# define ATOMIC_BUILTIN(name) __atomic_##name##_n
#endif
namespace
{
/**
* C++11 memory orders. We only need a subset of them.
*/
enum memory_order
{
/**
* Acquire order.
*/
acquire = __ATOMIC_ACQUIRE,
/**
* Release order.
*/
release = __ATOMIC_RELEASE,
/**
* Sequentially consistent memory ordering.
*/
seqcst = __ATOMIC_SEQ_CST
};
/**
* Atomic, implements a subset of `std::atomic`.
*/
template<typename T>
class atomic
{
/**
* The underlying value. Use C11 atomic qualification if available.
*/
_Atomic(T) val;
public:
/**
* Constructor, takes a value.
*/
constexpr atomic(T init) : val(init) {}
/**
* Atomically load with the specified memory order.
*/
T load(memory_order order = memory_order::seqcst)
{
return ATOMIC_BUILTIN(load)(&val, order);
}
/**
* Atomically store with the specified memory order.
*/
void store(T v, memory_order order = memory_order::seqcst)
{
return ATOMIC_BUILTIN(store)(&val, v, order);
}
/**
* Atomically exchange with the specified memory order.
*/
T exchange(T v, memory_order order = memory_order::seqcst)
{
return ATOMIC_BUILTIN(exchange)(&val, v, order);
}
/**
* Atomically exchange with the specified memory order.
*/
bool compare_exchange(T & expected,
T desired,
memory_order order = memory_order::seqcst)
{
#if __has_builtin(__c11_atomic_compare_exchange_strong)
return __c11_atomic_compare_exchange_strong(
&val, &expected, desired, order, order);
#else
return __atomic_compare_exchange_n(
&val, &expected, desired, true, order, order);
#endif
}
};
} // namespace
#undef ATOMIC_BUILTIN