[libc++abi] Replace __sync_* functions with __libcpp_atomic_* functions.
This is basically part 2 of r313694. It's a little unfortunate that I had to copy-paste atomic_support.h, but I don't really see any alternative. The refstring.h changes are the same as the libcxx changes in r313694. llvm-svn: 330162
This commit is contained in:
parent
aca6d0013c
commit
17a47b915a
|
@ -18,6 +18,7 @@
|
|||
#include "cxa_handlers.hpp"
|
||||
#include "cxa_exception.hpp"
|
||||
#include "private_typeinfo.h"
|
||||
#include "include/atomic_support.h"
|
||||
|
||||
#if !defined(LIBCXXABI_SILENT_TERMINATE)
|
||||
static const char* cause = "uncaught";
|
||||
|
@ -101,10 +102,6 @@ std::terminate_handler __cxa_terminate_handler = default_terminate_handler;
|
|||
_LIBCXXABI_DATA_VIS
|
||||
std::unexpected_handler __cxa_unexpected_handler = default_unexpected_handler;
|
||||
|
||||
// In the future these will become:
|
||||
// std::atomic<std::terminate_handler> __cxa_terminate_handler(default_terminate_handler);
|
||||
// std::atomic<std::unexpected_handler> __cxa_unexpected_handler(default_unexpected_handler);
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
|
@ -113,10 +110,8 @@ set_unexpected(unexpected_handler func) _NOEXCEPT
|
|||
{
|
||||
if (func == 0)
|
||||
func = default_unexpected_handler;
|
||||
return __atomic_exchange_n(&__cxa_unexpected_handler, func,
|
||||
__ATOMIC_ACQ_REL);
|
||||
// Using of C++11 atomics this should be rewritten
|
||||
// return __cxa_unexpected_handler.exchange(func, memory_order_acq_rel);
|
||||
return __libcpp_atomic_exchange(&__cxa_unexpected_handler, func,
|
||||
_AO_Acq_Rel);
|
||||
}
|
||||
|
||||
terminate_handler
|
||||
|
@ -124,10 +119,8 @@ set_terminate(terminate_handler func) _NOEXCEPT
|
|||
{
|
||||
if (func == 0)
|
||||
func = default_terminate_handler;
|
||||
return __atomic_exchange_n(&__cxa_terminate_handler, func,
|
||||
__ATOMIC_ACQ_REL);
|
||||
// Using of C++11 atomics this should be rewritten
|
||||
// return __cxa_terminate_handler.exchange(func, memory_order_acq_rel);
|
||||
return __libcpp_atomic_exchange(&__cxa_terminate_handler, func,
|
||||
_AO_Acq_Rel);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "cxa_exception.hpp"
|
||||
#include "cxa_handlers.hpp"
|
||||
#include "fallback_malloc.h"
|
||||
#include "include/atomic_support.h"
|
||||
|
||||
#if __has_feature(address_sanitizer)
|
||||
extern "C" void __asan_handle_no_return(void);
|
||||
|
@ -618,7 +619,7 @@ __cxa_increment_exception_refcount(void *thrown_object) throw() {
|
|||
if (thrown_object != NULL )
|
||||
{
|
||||
__cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);
|
||||
__sync_add_and_fetch(&exception_header->referenceCount, 1);
|
||||
std::__libcpp_atomic_add(&exception_header->referenceCount, size_t(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -635,7 +636,7 @@ void __cxa_decrement_exception_refcount(void *thrown_object) throw() {
|
|||
if (thrown_object != NULL )
|
||||
{
|
||||
__cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);
|
||||
if (__sync_sub_and_fetch(&exception_header->referenceCount, size_t(1)) == 0)
|
||||
if (std::__libcpp_atomic_add(&exception_header->referenceCount, size_t(-1)) == 0)
|
||||
{
|
||||
if (NULL != exception_header->exceptionDestructor)
|
||||
exception_header->exceptionDestructor(thrown_object);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "cxa_handlers.hpp"
|
||||
#include "cxa_exception.hpp"
|
||||
#include "private_typeinfo.h"
|
||||
#include "include/atomic_support.h"
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
@ -25,10 +26,7 @@ namespace std
|
|||
unexpected_handler
|
||||
get_unexpected() _NOEXCEPT
|
||||
{
|
||||
return __sync_fetch_and_add(&__cxa_unexpected_handler, (unexpected_handler)0);
|
||||
// The above is safe but overkill on x86
|
||||
// Using of C++11 atomics this should be rewritten
|
||||
// return __cxa_unexpected_handler.load(memory_order_acq);
|
||||
return __libcpp_atomic_load(&__cxa_unexpected_handler, _AO_Acquire);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -49,10 +47,7 @@ unexpected()
|
|||
terminate_handler
|
||||
get_terminate() _NOEXCEPT
|
||||
{
|
||||
return __sync_fetch_and_add(&__cxa_terminate_handler, (terminate_handler)0);
|
||||
// The above is safe but overkill on x86
|
||||
// Using of C++11 atomics this should be rewritten
|
||||
// return __cxa_terminate_handler.load(memory_order_acq);
|
||||
return __libcpp_atomic_load(&__cxa_terminate_handler, _AO_Acquire);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -99,8 +94,6 @@ terminate() _NOEXCEPT
|
|||
__terminate(get_terminate());
|
||||
}
|
||||
|
||||
// In the future this will become:
|
||||
// std::atomic<std::new_handler> __cxa_new_handler(0);
|
||||
extern "C" {
|
||||
new_handler __cxa_new_handler = 0;
|
||||
}
|
||||
|
@ -108,18 +101,13 @@ new_handler __cxa_new_handler = 0;
|
|||
new_handler
|
||||
set_new_handler(new_handler handler) _NOEXCEPT
|
||||
{
|
||||
return __atomic_exchange_n(&__cxa_new_handler, handler, __ATOMIC_ACQ_REL);
|
||||
// Using of C++11 atomics this should be rewritten
|
||||
// return __cxa_new_handler.exchange(handler, memory_order_acq_rel);
|
||||
return __libcpp_atomic_exchange(&__cxa_new_handler, handler, _AO_Acq_Rel);
|
||||
}
|
||||
|
||||
new_handler
|
||||
get_new_handler() _NOEXCEPT
|
||||
{
|
||||
return __sync_fetch_and_add(&__cxa_new_handler, (new_handler)0);
|
||||
// The above is safe but overkill on x86
|
||||
// Using of C++11 atomics this should be rewritten
|
||||
// return __cxa_new_handler.load(memory_order_acq);
|
||||
return __libcpp_atomic_load(&__cxa_new_handler, _AO_Acquire);
|
||||
}
|
||||
|
||||
} // std
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
//===----------------------------------------------------------------------===////
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===////
|
||||
|
||||
// FIXME: This file is copied from libcxx/src/include/atomic_support.h. Instead
|
||||
// of duplicating the file in libc++abi we should require that the libc++
|
||||
// sources are available when building libc++abi.
|
||||
|
||||
#ifndef ATOMIC_SUPPORT_H
|
||||
#define ATOMIC_SUPPORT_H
|
||||
|
||||
#include "__config"
|
||||
#include "memory" // for __libcpp_relaxed_load
|
||||
|
||||
#if defined(__clang__) && __has_builtin(__atomic_load_n) \
|
||||
&& __has_builtin(__atomic_store_n) \
|
||||
&& __has_builtin(__atomic_add_fetch) \
|
||||
&& __has_builtin(__atomic_exchange_n) \
|
||||
&& __has_builtin(__atomic_compare_exchange_n) \
|
||||
&& defined(__ATOMIC_RELAXED) \
|
||||
&& defined(__ATOMIC_CONSUME) \
|
||||
&& defined(__ATOMIC_ACQUIRE) \
|
||||
&& defined(__ATOMIC_RELEASE) \
|
||||
&& defined(__ATOMIC_ACQ_REL) \
|
||||
&& defined(__ATOMIC_SEQ_CST)
|
||||
# define _LIBCXXABI_HAS_ATOMIC_BUILTINS
|
||||
#elif !defined(__clang__) && defined(_GNUC_VER) && _GNUC_VER >= 407
|
||||
# define _LIBCXXABI_HAS_ATOMIC_BUILTINS
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCXXABI_HAS_ATOMIC_BUILTINS) && !defined(_LIBCXXABI_HAS_NO_THREADS)
|
||||
# if defined(_LIBCPP_WARNING)
|
||||
_LIBCPP_WARNING("Building libc++ without __atomic builtins is unsupported")
|
||||
# else
|
||||
# warning Building libc++ without __atomic builtins is unsupported
|
||||
# endif
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace {
|
||||
|
||||
#if defined(_LIBCXXABI_HAS_ATOMIC_BUILTINS) && !defined(_LIBCXXABI_HAS_NO_THREADS)
|
||||
|
||||
enum __libcpp_atomic_order {
|
||||
_AO_Relaxed = __ATOMIC_RELAXED,
|
||||
_AO_Consume = __ATOMIC_CONSUME,
|
||||
_AO_Acquire = __ATOMIC_ACQUIRE,
|
||||
_AO_Release = __ATOMIC_RELEASE,
|
||||
_AO_Acq_Rel = __ATOMIC_ACQ_REL,
|
||||
_AO_Seq = __ATOMIC_SEQ_CST
|
||||
};
|
||||
|
||||
template <class _ValueType, class _FromType>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void __libcpp_atomic_store(_ValueType* __dest, _FromType __val,
|
||||
int __order = _AO_Seq)
|
||||
{
|
||||
__atomic_store_n(__dest, __val, __order);
|
||||
}
|
||||
|
||||
template <class _ValueType, class _FromType>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void __libcpp_relaxed_store(_ValueType* __dest, _FromType __val)
|
||||
{
|
||||
__atomic_store_n(__dest, __val, _AO_Relaxed);
|
||||
}
|
||||
|
||||
template <class _ValueType>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
_ValueType __libcpp_atomic_load(_ValueType const* __val,
|
||||
int __order = _AO_Seq)
|
||||
{
|
||||
return __atomic_load_n(__val, __order);
|
||||
}
|
||||
|
||||
template <class _ValueType, class _AddType>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
_ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a,
|
||||
int __order = _AO_Seq)
|
||||
{
|
||||
return __atomic_add_fetch(__val, __a, __order);
|
||||
}
|
||||
|
||||
template <class _ValueType>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
_ValueType __libcpp_atomic_exchange(_ValueType* __target,
|
||||
_ValueType __value, int __order = _AO_Seq)
|
||||
{
|
||||
return __atomic_exchange_n(__target, __value, __order);
|
||||
}
|
||||
|
||||
template <class _ValueType>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
bool __libcpp_atomic_compare_exchange(_ValueType* __val,
|
||||
_ValueType* __expected, _ValueType __after,
|
||||
int __success_order = _AO_Seq,
|
||||
int __fail_order = _AO_Seq)
|
||||
{
|
||||
return __atomic_compare_exchange_n(__val, __expected, __after, true,
|
||||
__success_order, __fail_order);
|
||||
}
|
||||
|
||||
#else // _LIBCPP_HAS_NO_THREADS
|
||||
|
||||
enum __libcpp_atomic_order {
|
||||
_AO_Relaxed,
|
||||
_AO_Consume,
|
||||
_AO_Acquire,
|
||||
_AO_Release,
|
||||
_AO_Acq_Rel,
|
||||
_AO_Seq
|
||||
};
|
||||
|
||||
template <class _ValueType, class _FromType>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void __libcpp_atomic_store(_ValueType* __dest, _FromType __val,
|
||||
int = 0)
|
||||
{
|
||||
*__dest = __val;
|
||||
}
|
||||
|
||||
template <class _ValueType, class _FromType>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void __libcpp_relaxed_store(_ValueType* __dest, _FromType __val)
|
||||
{
|
||||
*__dest = __val;
|
||||
}
|
||||
|
||||
template <class _ValueType>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
_ValueType __libcpp_atomic_load(_ValueType const* __val,
|
||||
int = 0)
|
||||
{
|
||||
return *__val;
|
||||
}
|
||||
|
||||
template <class _ValueType, class _AddType>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
_ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a,
|
||||
int = 0)
|
||||
{
|
||||
return *__val += __a;
|
||||
}
|
||||
|
||||
template <class _ValueType>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
_ValueType __libcpp_atomic_exchange(_ValueType* __target,
|
||||
_ValueType __value, int __order = _AO_Seq)
|
||||
{
|
||||
_ValueType old = *__target;
|
||||
*__target = __value;
|
||||
return old;
|
||||
}
|
||||
|
||||
template <class _ValueType>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
bool __libcpp_atomic_compare_exchange(_ValueType* __val,
|
||||
_ValueType* __expected, _ValueType __after,
|
||||
int = 0, int = 0)
|
||||
{
|
||||
if (*__val == *__expected) {
|
||||
*__val = __after;
|
||||
return true;
|
||||
}
|
||||
*__expected = *__val;
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_THREADS
|
||||
|
||||
} // end namespace
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // ATOMIC_SUPPORT_H
|
|
@ -22,6 +22,7 @@
|
|||
#include <dlfcn.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#endif
|
||||
#include "atomic_support.h"
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
|
@ -87,7 +88,7 @@ __libcpp_refstring::__libcpp_refstring(const __libcpp_refstring &s) _NOEXCEPT
|
|||
: __imp_(s.__imp_)
|
||||
{
|
||||
if (__uses_refcount())
|
||||
__sync_add_and_fetch(&rep_from_data(__imp_)->count, 1);
|
||||
__libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);
|
||||
}
|
||||
|
||||
inline
|
||||
|
@ -96,10 +97,10 @@ __libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring const& s) _
|
|||
struct _Rep_base *old_rep = rep_from_data(__imp_);
|
||||
__imp_ = s.__imp_;
|
||||
if (__uses_refcount())
|
||||
__sync_add_and_fetch(&rep_from_data(__imp_)->count, 1);
|
||||
__libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);
|
||||
if (adjust_old_count)
|
||||
{
|
||||
if (__sync_add_and_fetch(&old_rep->count, count_t(-1)) < 0)
|
||||
if (__libcpp_atomic_add(&old_rep->count, count_t(-1)) < 0)
|
||||
{
|
||||
::operator delete(old_rep);
|
||||
}
|
||||
|
@ -111,7 +112,7 @@ inline
|
|||
__libcpp_refstring::~__libcpp_refstring() {
|
||||
if (__uses_refcount()) {
|
||||
_Rep_base* rep = rep_from_data(__imp_);
|
||||
if (__sync_add_and_fetch(&rep->count, count_t(-1)) < 0) {
|
||||
if (__libcpp_atomic_add(&rep->count, count_t(-1)) < 0) {
|
||||
::operator delete(rep);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue