diff options
| author | Eric Fiselier <eric@efcs.ca> | 2015-07-07 00:27:16 +0000 |
|---|---|---|
| committer | Eric Fiselier <eric@efcs.ca> | 2015-07-07 00:27:16 +0000 |
| commit | 1faf289e27bcb54e54b2e3e0f492d6f54d59cd9e (patch) | |
| tree | e3663203fe77563429ca010009a19d2d2c926dcd /libcxx/include | |
| parent | d529d04fd73c55f35d3f6425314a6780e9146f23 (diff) | |
| download | bcm5719-llvm-1faf289e27bcb54e54b2e3e0f492d6f54d59cd9e.tar.gz bcm5719-llvm-1faf289e27bcb54e54b2e3e0f492d6f54d59cd9e.zip | |
[libcxx] Add atomic_support.h header to src that handles needed atomic operations.
Summary:
In some places in libc++ we need to use the `__atomic_*` builtins. This patch adds a header that provides access to those builtins in a uniform way from within the dylib source.
If the compiler building the dylib does not support these builtins then a warning is issued.
Only relaxed loads are needed within the headers. A singe function to do these relaxed loads has been added to `<memory>`.
This patch applies the new atomic builtins to `__shared_count` and `call_once`.
Reviewers: mclow.lists
Subscribers: majnemer, jroelofs, cfe-commits
Differential Revision: http://reviews.llvm.org/D10406
llvm-svn: 241532
Diffstat (limited to 'libcxx/include')
| -rw-r--r-- | libcxx/include/memory | 16 | ||||
| -rw-r--r-- | libcxx/include/mutex | 5 |
2 files changed, 18 insertions, 3 deletions
diff --git a/libcxx/include/memory b/libcxx/include/memory index 26ba5642ce1..4f59d804a03 100644 --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -625,6 +625,18 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space); _LIBCPP_BEGIN_NAMESPACE_STD +template <class _ValueType> +inline _LIBCPP_ALWAYS_INLINE +_ValueType __libcpp_relaxed_load(_ValueType const* __value) { +#if !defined(_LIBCPP_HAS_NO_THREADS) && \ + defined(__ATOMIC_RELAXED) && \ + (__has_builtin(__atomic_load_n) || _GNUC_VER >= 407) + return __atomic_load_n(__value, __ATOMIC_RELAXED); +#else + return *__value; +#endif +} + // addressof moved to <__functional_base> template <class _Tp> class allocator; @@ -3672,7 +3684,9 @@ public: void __add_shared() _NOEXCEPT; bool __release_shared() _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY - long use_count() const _NOEXCEPT {return __shared_owners_ + 1;} + long use_count() const _NOEXCEPT { + return __libcpp_relaxed_load(&__shared_owners_) + 1; + } }; class _LIBCPP_TYPE_VIS __shared_weak_count diff --git a/libcxx/include/mutex b/libcxx/include/mutex index 0adf1e69bf2..373d75b0978 100644 --- a/libcxx/include/mutex +++ b/libcxx/include/mutex @@ -175,6 +175,7 @@ template<class Callable, class ...Args> #include <__config> #include <__mutex_base> #include <functional> +#include <memory> #ifndef _LIBCPP_HAS_NO_VARIADICS #include <tuple> #endif @@ -539,7 +540,7 @@ inline _LIBCPP_INLINE_VISIBILITY void call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args) { - if (__flag.__state_ != ~0ul) + if (__libcpp_relaxed_load(&__flag.__state_) != ~0ul) { typedef tuple<_Callable&&, _Args&&...> _Gp; _Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...); @@ -555,7 +556,7 @@ inline _LIBCPP_INLINE_VISIBILITY void call_once(once_flag& __flag, _Callable& __func) { - if (__flag.__state_ != ~0ul) + if (__libcpp_relaxed_load(&__flag.__state_) != ~0ul) { __call_once_param<_Callable> __p(__func); __call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>); |

