diff options
author | Howard Hinnant <hhinnant@apple.com> | 2012-07-30 17:13:21 +0000 |
---|---|---|
committer | Howard Hinnant <hhinnant@apple.com> | 2012-07-30 17:13:21 +0000 |
commit | 088e37c77aafaec5ead8fbe7ebf918265e6b86f2 (patch) | |
tree | 20c95d7e75e78dc0efa5826ff856bcd4f76318e7 /libcxx/src/memory.cpp | |
parent | ebcd1c7ca2e21192dee17985221c7c0efb017506 (diff) | |
download | bcm5719-llvm-088e37c77aafaec5ead8fbe7ebf918265e6b86f2.tar.gz bcm5719-llvm-088e37c77aafaec5ead8fbe7ebf918265e6b86f2.zip |
Despite my pathological distrust of spin locks, the number just don't lie. I've put a small spin in __sp_mut::lock() on std::mutex::try_lock(), which is testing quite well. In my experience, putting in a yield for every failed iteration is also a major performance booster. This change makes one of the performance tests I was using (a highly contended one) run about 20 times faster.
llvm-svn: 160967
Diffstat (limited to 'libcxx/src/memory.cpp')
-rw-r--r-- | libcxx/src/memory.cpp | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/libcxx/src/memory.cpp b/libcxx/src/memory.cpp index 7caab26c42e..1c108b8c352 100644 --- a/libcxx/src/memory.cpp +++ b/libcxx/src/memory.cpp @@ -10,6 +10,7 @@ #define _LIBCPP_BUILDING_MEMORY #include "memory" #include "mutex" +#include "thread" _LIBCPP_BEGIN_NAMESPACE_STD @@ -129,13 +130,23 @@ _LIBCPP_CONSTEXPR __sp_mut::__sp_mut(void* p) _NOEXCEPT void __sp_mut::lock() _NOEXCEPT { - reinterpret_cast<mutex*>(_)->lock(); + mutex& m = *static_cast<mutex*>(_); + unsigned count = 0; + while (!m.try_lock()) + { + if (++count > 16) + { + m.lock(); + break; + } + this_thread::yield(); + } } void __sp_mut::unlock() _NOEXCEPT { - reinterpret_cast<mutex*>(_)->unlock(); + static_cast<mutex*>(_)->unlock(); } __sp_mut& |