diff --git a/libcxx/include/__threading_support b/libcxx/include/__threading_support --- a/libcxx/include/__threading_support +++ b/libcxx/include/__threading_support @@ -277,18 +277,51 @@ #endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) -#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ - defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) - struct __libcpp_timed_backoff_policy { _LIBCPP_THREAD_ABI_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const; }; +inline _LIBCPP_INLINE_VISIBILITY +bool __libcpp_timed_backoff_policy::operator()(chrono::nanoseconds __elapsed) const +{ + if(__elapsed > chrono::milliseconds(128)) + __libcpp_thread_sleep_for(chrono::milliseconds(8)); + else if(__elapsed > chrono::microseconds(64)) + __libcpp_thread_sleep_for(__elapsed / 2); + else if(__elapsed > chrono::microseconds(4)) + __libcpp_thread_yield(); + else + ; // poll + return false; +} + +static _LIBCPP_CONSTEXPR const int __libcpp_polling_count = 64; + template _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY bool __libcpp_thread_poll_with_backoff( - _Fn && __f, _BFn && __bf, chrono::nanoseconds __max_elapsed = chrono::nanoseconds::zero()); + _Fn && __f, _BFn && __bf, chrono::nanoseconds __max_elapsed = chrono::nanoseconds::zero()) +{ + auto const __start = chrono::high_resolution_clock::now(); + for(int __count = 0;;) { + if(__f()) + return true; // _Fn completion means success + if(__count < __libcpp_polling_count) { + __count += 1; + continue; + } + chrono::nanoseconds const __elapsed = chrono::high_resolution_clock::now() - __start; + if(__max_elapsed != chrono::nanoseconds::zero() && __max_elapsed < __elapsed) + return false; // timeout failure + if(__bf(__elapsed)) + return false; // _BFn completion means failure + } +} + +#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ + defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) + namespace __thread_detail { @@ -677,41 +710,6 @@ #endif -inline _LIBCPP_INLINE_VISIBILITY -bool __libcpp_timed_backoff_policy::operator()(chrono::nanoseconds __elapsed) const -{ - if(__elapsed > chrono::milliseconds(128)) - __libcpp_thread_sleep_for(chrono::milliseconds(8)); - else if(__elapsed > chrono::microseconds(64)) - __libcpp_thread_sleep_for(__elapsed / 2); - else if(__elapsed > chrono::microseconds(4)) - __libcpp_thread_yield(); - else - ; // poll - return false; -} - -static _LIBCPP_CONSTEXPR const int __libcpp_polling_count = 64; - -template -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY -bool __libcpp_thread_poll_with_backoff(_Fn && __f, _BFn && __bf, chrono::nanoseconds __max_elapsed) -{ - auto const __start = chrono::high_resolution_clock::now(); - for(int __count = 0;;) { - if(__f()) - return true; // _Fn completion means success - if(__count < __libcpp_polling_count) { - __count += 1; - continue; - } - chrono::nanoseconds const __elapsed = chrono::high_resolution_clock::now() - __start; - if(__max_elapsed != chrono::nanoseconds::zero() && __max_elapsed < __elapsed) - return false; // timeout failure - if(__bf(__elapsed)) - return false; // _BFn completion means failure - } -} #endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL