summaryrefslogtreecommitdiffstats
path: root/libcxx/src/memory.cpp
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2015-07-07 00:27:16 +0000
committerEric Fiselier <eric@efcs.ca>2015-07-07 00:27:16 +0000
commit1faf289e27bcb54e54b2e3e0f492d6f54d59cd9e (patch)
treee3663203fe77563429ca010009a19d2d2c926dcd /libcxx/src/memory.cpp
parentd529d04fd73c55f35d3f6425314a6780e9146f23 (diff)
downloadbcm5719-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/src/memory.cpp')
-rw-r--r--libcxx/src/memory.cpp17
1 files changed, 10 insertions, 7 deletions
diff --git a/libcxx/src/memory.cpp b/libcxx/src/memory.cpp
index 8a4eb34811f..66fb143c6a6 100644
--- a/libcxx/src/memory.cpp
+++ b/libcxx/src/memory.cpp
@@ -13,24 +13,28 @@
#include "mutex"
#include "thread"
#endif
+#include "support/atomic_support.h"
_LIBCPP_BEGIN_NAMESPACE_STD
namespace
{
+// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)
+// should be sufficient for thread safety.
+// See https://llvm.org/bugs/show_bug.cgi?id=22803
template <class T>
inline T
increment(T& t) _NOEXCEPT
{
- return __sync_add_and_fetch(&t, 1);
+ return __libcpp_atomic_add(&t, 1, _AO_Relaxed);
}
template <class T>
inline T
decrement(T& t) _NOEXCEPT
{
- return __sync_add_and_fetch(&t, -1);
+ return __libcpp_atomic_add(&t, -1, _AO_Acq_Rel);
}
} // namespace
@@ -99,14 +103,13 @@ __shared_weak_count::__release_weak() _NOEXCEPT
__shared_weak_count*
__shared_weak_count::lock() _NOEXCEPT
{
- long object_owners = __shared_owners_;
+ long object_owners = __libcpp_atomic_load(&__shared_owners_);
while (object_owners != -1)
{
- if (__sync_bool_compare_and_swap(&__shared_owners_,
- object_owners,
- object_owners+1))
+ if (__libcpp_atomic_compare_exchange(&__shared_owners_,
+ &object_owners,
+ object_owners+1))
return this;
- object_owners = __shared_owners_;
}
return 0;
}
OpenPOWER on IntegriCloud