[libc++] Replace __sync_* functions with __libcpp_atomic_* functions

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
diff --git a/libcxx/src/include/atomic_support.h b/libcxx/src/include/atomic_support.h
index 08847e6..ccd8d78 100644
--- a/libcxx/src/include/atomic_support.h
+++ b/libcxx/src/include/atomic_support.h
@@ -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)                  \
@@ -84,6 +85,14 @@
 
 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,
@@ -137,6 +146,16 @@
 
 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)