Skip to content

Commit

Permalink
[libc++] Replace __sync_* functions with __libcpp_atomic_* functions
Browse files Browse the repository at this point in the history
Summary:
This patch replaces __sync_* with __libcpp_atomic_* and adds a wrapper
function for __atomic_exchange to support _LIBCPP_HAS_NO_THREADS.

Reviewers: EricWF, jroelofs, mclow.lists, compnerd

Reviewed By: EricWF, compnerd

Subscribers: compnerd, efriedma, cfe-commits, joerg, llvm-commits

Differential Revision: https://reviews.llvm.org/D35235

llvm-svn: 313694
  • Loading branch information
Weiming Zhao committed Sep 19, 2017
1 parent 3ac802a commit fbfaec7
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 12 deletions.
1 change: 1 addition & 0 deletions libcxx/src/exception.cpp
Expand Up @@ -31,6 +31,7 @@
#include "support/runtime/exception_glibcxx.ipp"
#include "support/runtime/exception_pointer_glibcxx.ipp"
#else
#include "include/atomic_support.h"
#include "support/runtime/exception_fallback.ipp"
#include "support/runtime/exception_pointer_unimplemented.ipp"
#endif
19 changes: 19 additions & 0 deletions libcxx/src/include/atomic_support.h
Expand Up @@ -16,6 +16,7 @@
#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) \
Expand Down Expand Up @@ -82,6 +83,14 @@ _ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a,
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,
Expand Down Expand Up @@ -135,6 +144,16 @@ _ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a,
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,
Expand Down
9 changes: 5 additions & 4 deletions libcxx/src/include/refstring.h
Expand Up @@ -18,6 +18,7 @@
#include <dlfcn.h>
#include <mach-o/dyld.h>
#endif
#include "atomic_support.h"

_LIBCPP_BEGIN_NAMESPACE_STD

Expand Down Expand Up @@ -83,7 +84,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
Expand All @@ -92,10 +93,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);
}
Expand All @@ -107,7 +108,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);
}
}
Expand Down
3 changes: 2 additions & 1 deletion libcxx/src/locale.cpp
Expand Up @@ -36,6 +36,7 @@
#endif
#include <stdlib.h>
#include <stdio.h>
#include "include/atomic_support.h"
#include "__undef_macros"

// On Linux, wint_t and wchar_t have different signed-ness, and this causes
Expand Down Expand Up @@ -667,7 +668,7 @@ locale::id::__get()
void
locale::id::__init()
{
__id_ = __sync_add_and_fetch(&__next_id, 1);
__id_ = __libcpp_atomic_add(&__next_id, 1);
}

// template <> class collate_byname<char>
Expand Down
1 change: 1 addition & 0 deletions libcxx/src/new.cpp
Expand Up @@ -12,6 +12,7 @@
#include <stdlib.h>

#include "new"
#include "include/atomic_support.h"

#if defined(_LIBCPP_ABI_MICROSOFT)
// nothing todo
Expand Down
9 changes: 4 additions & 5 deletions libcxx/src/support/runtime/exception_fallback.ipp
Expand Up @@ -20,13 +20,13 @@ _LIBCPP_SAFE_STATIC static std::unexpected_handler __unexpected_handler;
unexpected_handler
set_unexpected(unexpected_handler func) _NOEXCEPT
{
return __sync_lock_test_and_set(&__unexpected_handler, func);
return __libcpp_atomic_exchange(&__unexpected_handler, func);
}

unexpected_handler
get_unexpected() _NOEXCEPT
{
return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0);
return __libcpp_atomic_load(&__unexpected_handler);

}

Expand All @@ -41,14 +41,13 @@ void unexpected()
terminate_handler
set_terminate(terminate_handler func) _NOEXCEPT
{
return __sync_lock_test_and_set(&__terminate_handler, func);
return __libcpp_atomic_exchange(&__terminate_handler, func);
}

terminate_handler
get_terminate() _NOEXCEPT
{
return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0);

return __libcpp_atomic_load(&__terminate_handler);
}

#ifndef __EMSCRIPTEN__ // We provide this in JS
Expand Down
4 changes: 2 additions & 2 deletions libcxx/src/support/runtime/new_handler_fallback.ipp
Expand Up @@ -15,13 +15,13 @@ _LIBCPP_SAFE_STATIC static std::new_handler __new_handler;
new_handler
set_new_handler(new_handler handler) _NOEXCEPT
{
return __sync_lock_test_and_set(&__new_handler, handler);
return __libcpp_atomic_exchange(&__new_handler, handler);
}

new_handler
get_new_handler() _NOEXCEPT
{
return __sync_fetch_and_add(&__new_handler, nullptr);
return __libcpp_atomic_load(&__new_handler);
}

} // namespace std

0 comments on commit fbfaec7

Please sign in to comment.