Index: libcxx/trunk/include/__threading_support =================================================================== --- libcxx/trunk/include/__threading_support +++ libcxx/trunk/include/__threading_support @@ -12,6 +12,8 @@ #define _LIBCPP_THREADING_SUPPORT #include <__config> +#include +#include #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER #pragma GCC system_header @@ -28,8 +30,6 @@ #include #include #include - -#include #endif #if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ @@ -183,6 +183,9 @@ _LIBCPP_THREAD_ABI_VISIBILITY void __libcpp_thread_yield(); +_LIBCPP_THREAD_ABI_VISIBILITY +void __libcpp_thread_sleep_for(const chrono::nanoseconds& ns); + // Thread local storage _LIBCPP_THREAD_ABI_VISIBILITY int __libcpp_tls_create(__libcpp_tls_key* __key, @@ -345,6 +348,28 @@ sched_yield(); } +void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) +{ + using namespace chrono; + seconds __s = duration_cast(__ns); + timespec __ts; + typedef decltype(__ts.tv_sec) ts_sec; + _LIBCPP_CONSTEXPR ts_sec __ts_sec_max = numeric_limits::max(); + + if (__s.count() < __ts_sec_max) + { + __ts.tv_sec = static_cast(__s.count()); + __ts.tv_nsec = static_cast((__ns - __s).count()); + } + else + { + __ts.tv_sec = __ts_sec_max; + __ts.tv_nsec = 999999999; // (10^9 - 1) + } + + while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR); +} + // Thread local storage int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *)) { @@ -562,6 +587,14 @@ SwitchToThread(); } +void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) +{ + using namespace chrono; + // round-up to the nearest milisecond + milliseconds __ms = duration_cast(__ns + 999999); + Sleep(__ms.count()); +} + // Thread Local Storage int __libcpp_tls_create(__libcpp_tls_key* __key, void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*)) Index: libcxx/trunk/src/thread.cpp =================================================================== --- libcxx/trunk/src/thread.cpp +++ libcxx/trunk/src/thread.cpp @@ -114,33 +114,9 @@ void sleep_for(const chrono::nanoseconds& ns) { - using namespace chrono; - if (ns > nanoseconds::zero()) + if (ns > chrono::nanoseconds::zero()) { -#if defined(_LIBCPP_WIN32API) - milliseconds ms = duration_cast(ns); - if (ms.count() == 0 || ns > duration_cast(ms)) - ++ms; - Sleep(ms.count()); -#else - seconds s = duration_cast(ns); - timespec ts; - typedef decltype(ts.tv_sec) ts_sec; - _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits::max(); - if (s.count() < ts_sec_max) - { - ts.tv_sec = static_cast(s.count()); - ts.tv_nsec = static_cast((ns-s).count()); - } - else - { - ts.tv_sec = ts_sec_max; - ts.tv_nsec = giga::num - 1; - } - - while (nanosleep(&ts, &ts) == -1 && errno == EINTR) - ; -#endif + __libcpp_thread_sleep_for(ns); } }