Index: include/future =================================================================== --- include/future +++ include/future @@ -367,7 +367,8 @@ #include #include #include -#include +#include +#include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -533,12 +534,24 @@ { protected: exception_ptr __exception_; - mutable mutex __mut_; - mutable condition_variable __cv_; + + mutable class __spin_lock + { + atomic_flag __locked_ = ATOMIC_FLAG_INIT ; + public: + void lock() { + while (__locked_.test_and_set(memory_order_acquire)) { ; } + } + void unlock() { + __locked_.clear(memory_order_release); + } + } __mut_; + + mutable condition_variable_any __cv_; unsigned __state_; virtual void __on_zero_shared() _NOEXCEPT; - void __sub_wait(unique_lock& __lk); + void __sub_wait(unique_lock<__spin_lock>& __lk); public: enum { @@ -558,7 +571,7 @@ _LIBCPP_INLINE_VISIBILITY void __set_future_attached() { - lock_guard __lk(__mut_); + lock_guard<__spin_lock> __lk(__mut_); __state_ |= __future_attached; } _LIBCPP_INLINE_VISIBILITY @@ -596,7 +609,7 @@ future_status __assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { - unique_lock __lk(__mut_); + unique_lock<__spin_lock> __lk(__mut_); if (__state_ & deferred) return future_status::deferred; while (!(__state_ & ready) && _Clock::now() < __abs_time) @@ -663,7 +676,7 @@ __assoc_state<_Rp>::set_value(_Arg& __arg) #endif { - unique_lock __lk(this->__mut_); + unique_lock<__spin_lock> __lk(this->__mut_); if (this->__has_value()) __throw_future_error(future_errc::promise_already_satisfied); ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg)); @@ -680,7 +693,7 @@ __assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg) #endif { - unique_lock __lk(this->__mut_); + unique_lock<__spin_lock> __lk(this->__mut_); if (this->__has_value()) __throw_future_error(future_errc::promise_already_satisfied); ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg)); @@ -692,7 +705,7 @@ _Rp __assoc_state<_Rp>::move() { - unique_lock __lk(this->__mut_); + unique_lock<__spin_lock> __lk(this->__mut_); this->__sub_wait(__lk); if (this->__exception_ != nullptr) rethrow_exception(this->__exception_); @@ -703,7 +716,7 @@ typename add_lvalue_reference<_Rp>::type __assoc_state<_Rp>::copy() { - unique_lock __lk(this->__mut_); + unique_lock<__spin_lock> __lk(this->__mut_); this->__sub_wait(__lk); if (this->__exception_ != nullptr) rethrow_exception(this->__exception_); @@ -739,7 +752,7 @@ void __assoc_state<_Rp&>::set_value(_Rp& __arg) { - unique_lock __lk(this->__mut_); + unique_lock<__spin_lock> __lk(this->__mut_); if (this->__has_value()) __throw_future_error(future_errc::promise_already_satisfied); __value_ = _VSTD::addressof(__arg); @@ -751,7 +764,7 @@ void __assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg) { - unique_lock __lk(this->__mut_); + unique_lock<__spin_lock> __lk(this->__mut_); if (this->__has_value()) __throw_future_error(future_errc::promise_already_satisfied); __value_ = _VSTD::addressof(__arg); @@ -763,7 +776,7 @@ _Rp& __assoc_state<_Rp&>::copy() { - unique_lock __lk(this->__mut_); + unique_lock<__spin_lock> __lk(this->__mut_); this->__sub_wait(__lk); if (this->__exception_ != nullptr) rethrow_exception(this->__exception_); Index: src/future.cpp =================================================================== --- src/future.cpp +++ src/future.cpp @@ -91,7 +91,7 @@ void __assoc_sub_state::set_value() { - unique_lock __lk(__mut_); + unique_lock<__spin_lock> __lk(__mut_); #ifndef _LIBCPP_NO_EXCEPTIONS if (__has_value()) throw future_error(make_error_code(future_errc::promise_already_satisfied)); @@ -103,7 +103,7 @@ void __assoc_sub_state::set_value_at_thread_exit() { - unique_lock __lk(__mut_); + unique_lock<__spin_lock> __lk(__mut_); #ifndef _LIBCPP_NO_EXCEPTIONS if (__has_value()) throw future_error(make_error_code(future_errc::promise_already_satisfied)); @@ -115,7 +115,7 @@ void __assoc_sub_state::set_exception(exception_ptr __p) { - unique_lock __lk(__mut_); + unique_lock<__spin_lock> __lk(__mut_); #ifndef _LIBCPP_NO_EXCEPTIONS if (__has_value()) throw future_error(make_error_code(future_errc::promise_already_satisfied)); @@ -128,7 +128,7 @@ void __assoc_sub_state::set_exception_at_thread_exit(exception_ptr __p) { - unique_lock __lk(__mut_); + unique_lock<__spin_lock> __lk(__mut_); #ifndef _LIBCPP_NO_EXCEPTIONS if (__has_value()) throw future_error(make_error_code(future_errc::promise_already_satisfied)); @@ -140,7 +140,7 @@ void __assoc_sub_state::__make_ready() { - unique_lock __lk(__mut_); + unique_lock<__spin_lock> __lk(__mut_); __state_ |= ready; __cv_.notify_all(); } @@ -148,7 +148,7 @@ void __assoc_sub_state::copy() { - unique_lock __lk(__mut_); + unique_lock<__spin_lock> __lk(__mut_); __sub_wait(__lk); if (__exception_ != nullptr) rethrow_exception(__exception_); @@ -157,12 +157,12 @@ void __assoc_sub_state::wait() { - unique_lock __lk(__mut_); + unique_lock<__spin_lock> __lk(__mut_); __sub_wait(__lk); } void -__assoc_sub_state::__sub_wait(unique_lock& __lk) +__assoc_sub_state::__sub_wait(unique_lock<__spin_lock>& __lk) { if (!__is_ready()) {