[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
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 1faf289e27bcb54e54b2e3e0f492d6f54d59cd9e
diff --git a/include/memory b/include/memory
index 26ba564..4f59d80 100644
--- a/include/memory
+++ b/include/memory
@@ -625,6 +625,18 @@
 
 _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 @@
     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/include/mutex b/include/mutex
index 0adf1e6..373d75b 100644
--- a/include/mutex
+++ b/include/mutex
@@ -175,6 +175,7 @@
 #include <__config>
 #include <__mutex_base>
 #include <functional>
+#include <memory>
 #ifndef _LIBCPP_HAS_NO_VARIADICS
 #include <tuple>
 #endif
@@ -539,7 +540,7 @@
 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 @@
 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>);