From 088e37c77aafaec5ead8fbe7ebf918265e6b86f2 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Mon, 30 Jul 2012 17:13:21 +0000 Subject: [PATCH] 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 --- libcxx/src/memory.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/libcxx/src/memory.cpp b/libcxx/src/memory.cpp index 7caab26c42eb..1c108b8c352a 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(_)->lock(); + mutex& m = *static_cast(_); + unsigned count = 0; + while (!m.try_lock()) + { + if (++count > 16) + { + m.lock(); + break; + } + this_thread::yield(); + } } void __sp_mut::unlock() _NOEXCEPT { - reinterpret_cast(_)->unlock(); + static_cast(_)->unlock(); } __sp_mut&