brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.4 KiB · 410f64b Raw
133 lines · c
1//===----------------------------------------------------------------------===////2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===////8 9#ifndef ATOMIC_SUPPORT_H10#define ATOMIC_SUPPORT_H11 12#include <__config>13#include <memory> // for __libcpp_relaxed_load14 15#if defined(__clang__) && __has_builtin(__atomic_load_n) && __has_builtin(__atomic_store_n) &&                         \16    __has_builtin(__atomic_add_fetch) && __has_builtin(__atomic_exchange_n) &&                                         \17    __has_builtin(__atomic_compare_exchange_n) && defined(__ATOMIC_RELAXED) && defined(__ATOMIC_CONSUME) &&            \18    defined(__ATOMIC_ACQUIRE) && defined(__ATOMIC_RELEASE) && defined(__ATOMIC_ACQ_REL) && defined(__ATOMIC_SEQ_CST)19#  define _LIBCPP_HAS_ATOMIC_BUILTINS20#elif defined(_LIBCPP_COMPILER_GCC)21#  define _LIBCPP_HAS_ATOMIC_BUILTINS22#endif23 24#if !defined(_LIBCPP_HAS_ATOMIC_BUILTINS) && _LIBCPP_HAS_THREADS25#  if defined(_LIBCPP_WARNING)26_LIBCPP_WARNING("Building libc++ without __atomic builtins is unsupported")27#  else28#    warning Building libc++ without __atomic builtins is unsupported29#  endif30#endif31 32_LIBCPP_BEGIN_NAMESPACE_STD33 34namespace {35 36#if defined(_LIBCPP_HAS_ATOMIC_BUILTINS) && _LIBCPP_HAS_THREADS37 38enum __libcpp_atomic_order {39  _AO_Relaxed = __ATOMIC_RELAXED,40  _AO_Consume = __ATOMIC_CONSUME,41  _AO_Acquire = __ATOMIC_ACQUIRE,42  _AO_Release = __ATOMIC_RELEASE,43  _AO_Acq_Rel = __ATOMIC_ACQ_REL,44  _AO_Seq     = __ATOMIC_SEQ_CST45};46 47template <class _ValueType, class _FromType>48inline _LIBCPP_HIDE_FROM_ABI void __libcpp_atomic_store(_ValueType* __dest, _FromType __val, int __order = _AO_Seq) {49  __atomic_store_n(__dest, __val, __order);50}51 52template <class _ValueType, class _FromType>53inline _LIBCPP_HIDE_FROM_ABI void __libcpp_relaxed_store(_ValueType* __dest, _FromType __val) {54  __atomic_store_n(__dest, __val, _AO_Relaxed);55}56 57template <class _ValueType>58inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_atomic_load(_ValueType const* __val, int __order = _AO_Seq) {59  return __atomic_load_n(__val, __order);60}61 62template <class _ValueType, class _AddType>63inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a, int __order = _AO_Seq) {64  return __atomic_add_fetch(__val, __a, __order);65}66 67template <class _ValueType>68inline _LIBCPP_HIDE_FROM_ABI _ValueType69__libcpp_atomic_exchange(_ValueType* __target, _ValueType __value, int __order = _AO_Seq) {70  return __atomic_exchange_n(__target, __value, __order);71}72 73template <class _ValueType>74inline _LIBCPP_HIDE_FROM_ABI bool __libcpp_atomic_compare_exchange(75    _ValueType* __val,76    _ValueType* __expected,77    _ValueType __after,78    int __success_order = _AO_Seq,79    int __fail_order    = _AO_Seq) {80  return __atomic_compare_exchange_n(__val, __expected, __after, true, __success_order, __fail_order);81}82 83#else // _LIBCPP_HAS_THREADS84 85enum __libcpp_atomic_order { _AO_Relaxed, _AO_Consume, _AO_Acquire, _AO_Release, _AO_Acq_Rel, _AO_Seq };86 87template <class _ValueType, class _FromType>88inline _LIBCPP_HIDE_FROM_ABI void __libcpp_atomic_store(_ValueType* __dest, _FromType __val, int = 0) {89  *__dest = __val;90}91 92template <class _ValueType, class _FromType>93inline _LIBCPP_HIDE_FROM_ABI void __libcpp_relaxed_store(_ValueType* __dest, _FromType __val) {94  *__dest = __val;95}96 97template <class _ValueType>98inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_atomic_load(_ValueType const* __val, int = 0) {99  return *__val;100}101 102template <class _ValueType, class _AddType>103inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a, int = 0) {104  return *__val += __a;105}106 107template <class _ValueType>108inline _LIBCPP_HIDE_FROM_ABI _ValueType109__libcpp_atomic_exchange(_ValueType* __target, _ValueType __value, int = _AO_Seq) {110  _ValueType old = *__target;111  *__target      = __value;112  return old;113}114 115template <class _ValueType>116inline _LIBCPP_HIDE_FROM_ABI bool117__libcpp_atomic_compare_exchange(_ValueType* __val, _ValueType* __expected, _ValueType __after, int = 0, int = 0) {118  if (*__val == *__expected) {119    *__val = __after;120    return true;121  }122  *__expected = *__val;123  return false;124}125 126#endif // _LIBCPP_HAS_THREADS127 128} // namespace129 130_LIBCPP_END_NAMESPACE_STD131 132#endif // ATOMIC_SUPPORT_H133