Path: blob/main/contrib/llvm-project/libcxx/include/__atomic/support/c11.h
213799 views
//===----------------------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef _LIBCPP___ATOMIC_SUPPORT_C11_H9#define _LIBCPP___ATOMIC_SUPPORT_C11_H1011#include <__atomic/memory_order.h>12#include <__config>13#include <__cstddef/ptrdiff_t.h>14#include <__memory/addressof.h>15#include <__type_traits/remove_const.h>1617#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)18# pragma GCC system_header19#endif2021//22// This file implements support for C11-style atomics23//2425_LIBCPP_BEGIN_NAMESPACE_STD2627template <typename _Tp>28struct __cxx_atomic_base_impl {29_LIBCPP_HIDE_FROM_ABI30#ifndef _LIBCPP_CXX03_LANG31__cxx_atomic_base_impl() _NOEXCEPT = default;32#else33__cxx_atomic_base_impl() _NOEXCEPT : __a_value() {34}35#endif // _LIBCPP_CXX03_LANG36_LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT : __a_value(__value) {}37_Atomic(_Tp) __a_value;38};3940#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)4142_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {43__c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));44}4546_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {47__c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));48}4950template <class _Tp>51_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {52__c11_atomic_init(std::addressof(__a->__a_value), __val);53}54template <class _Tp>55_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) _NOEXCEPT {56__c11_atomic_init(std::addressof(__a->__a_value), __val);57}5859template <class _Tp>60_LIBCPP_HIDE_FROM_ABI void61__cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {62__c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order));63}64template <class _Tp>65_LIBCPP_HIDE_FROM_ABI void66__cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) _NOEXCEPT {67__c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order));68}6970template <class _Tp>71_LIBCPP_HIDE_FROM_ABI _Tp72__cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {73using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;74return __c11_atomic_load(75const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));76}77template <class _Tp>78_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {79using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;80return __c11_atomic_load(81const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));82}8384template <class _Tp>85_LIBCPP_HIDE_FROM_ABI void86__cxx_atomic_load_inplace(__cxx_atomic_base_impl<_Tp> const volatile* __a, _Tp* __dst, memory_order __order) _NOEXCEPT {87using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;88*__dst = __c11_atomic_load(89const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));90}91template <class _Tp>92_LIBCPP_HIDE_FROM_ABI void93__cxx_atomic_load_inplace(__cxx_atomic_base_impl<_Tp> const* __a, _Tp* __dst, memory_order __order) _NOEXCEPT {94using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;95*__dst = __c11_atomic_load(96const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));97}9899template <class _Tp>100_LIBCPP_HIDE_FROM_ABI _Tp101__cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {102return __c11_atomic_exchange(103std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order));104}105template <class _Tp>106_LIBCPP_HIDE_FROM_ABI _Tp107__cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) _NOEXCEPT {108return __c11_atomic_exchange(109std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order));110}111112_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {113// Avoid switch statement to make this a constexpr.114return __order == memory_order_release115? memory_order_relaxed116: (__order == memory_order_acq_rel ? memory_order_acquire : __order);117}118119template <class _Tp>120_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong(121__cxx_atomic_base_impl<_Tp> volatile* __a,122_Tp* __expected,123_Tp __value,124memory_order __success,125memory_order __failure) _NOEXCEPT {126return __c11_atomic_compare_exchange_strong(127std::addressof(__a->__a_value),128__expected,129__value,130static_cast<__memory_order_underlying_t>(__success),131static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));132}133template <class _Tp>134_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong(135__cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure)136_NOEXCEPT {137return __c11_atomic_compare_exchange_strong(138std::addressof(__a->__a_value),139__expected,140__value,141static_cast<__memory_order_underlying_t>(__success),142static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));143}144145template <class _Tp>146_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak(147__cxx_atomic_base_impl<_Tp> volatile* __a,148_Tp* __expected,149_Tp __value,150memory_order __success,151memory_order __failure) _NOEXCEPT {152return __c11_atomic_compare_exchange_weak(153std::addressof(__a->__a_value),154__expected,155__value,156static_cast<__memory_order_underlying_t>(__success),157static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));158}159template <class _Tp>160_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak(161__cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure)162_NOEXCEPT {163return __c11_atomic_compare_exchange_weak(164std::addressof(__a->__a_value),165__expected,166__value,167static_cast<__memory_order_underlying_t>(__success),168static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));169}170171template <class _Tp>172_LIBCPP_HIDE_FROM_ABI _Tp173__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {174return __c11_atomic_fetch_add(175std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));176}177template <class _Tp>178_LIBCPP_HIDE_FROM_ABI _Tp179__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Tp __delta, memory_order __order) _NOEXCEPT {180return __c11_atomic_fetch_add(181std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));182}183184template <class _Tp>185_LIBCPP_HIDE_FROM_ABI _Tp*186__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {187return __c11_atomic_fetch_add(188std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));189}190template <class _Tp>191_LIBCPP_HIDE_FROM_ABI _Tp*192__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {193return __c11_atomic_fetch_add(194std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));195}196197template <class _Tp>198_LIBCPP_HIDE_FROM_ABI _Tp199__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {200return __c11_atomic_fetch_sub(201std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));202}203template <class _Tp>204_LIBCPP_HIDE_FROM_ABI _Tp205__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Tp __delta, memory_order __order) _NOEXCEPT {206return __c11_atomic_fetch_sub(207std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));208}209template <class _Tp>210_LIBCPP_HIDE_FROM_ABI _Tp*211__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {212return __c11_atomic_fetch_sub(213std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));214}215template <class _Tp>216_LIBCPP_HIDE_FROM_ABI _Tp*217__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {218return __c11_atomic_fetch_sub(219std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));220}221222template <class _Tp>223_LIBCPP_HIDE_FROM_ABI _Tp224__cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {225return __c11_atomic_fetch_and(226std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));227}228template <class _Tp>229_LIBCPP_HIDE_FROM_ABI _Tp230__cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {231return __c11_atomic_fetch_and(232std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));233}234235template <class _Tp>236_LIBCPP_HIDE_FROM_ABI _Tp237__cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {238return __c11_atomic_fetch_or(239std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));240}241template <class _Tp>242_LIBCPP_HIDE_FROM_ABI _Tp243__cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {244return __c11_atomic_fetch_or(245std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));246}247248template <class _Tp>249_LIBCPP_HIDE_FROM_ABI _Tp250__cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {251return __c11_atomic_fetch_xor(252std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));253}254template <class _Tp>255_LIBCPP_HIDE_FROM_ABI _Tp256__cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {257return __c11_atomic_fetch_xor(258std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));259}260261_LIBCPP_END_NAMESPACE_STD262263#endif // _LIBCPP___ATOMIC_SUPPORT_C11_H264265266