Index: include/__threading_support =================================================================== --- include/__threading_support +++ include/__threading_support @@ -26,6 +26,22 @@ #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) # include # include + +#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) +# include +# if defined(BSD) +# include +# endif // defined(BSD) +#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) + +#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__CloudABI__) +# include +#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__CloudABI__) + +#if defined(__NetBSD__) +#pragma weak pthread_create // Do not create libpthread dependency +#endif + #elif defined(_LIBCPP_HAS_THREAD_API_WIN32) #include #include @@ -186,6 +202,9 @@ _LIBCPP_THREAD_ABI_VISIBILITY void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns); +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_thread_hw_concurrency(); + // Thread local storage _LIBCPP_THREAD_ABI_VISIBILITY int __libcpp_tls_create(__libcpp_tls_key* __key, @@ -370,6 +389,28 @@ while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR); } +int __libcpp_thread_hw_concurrency() +{ +#if defined(CTL_HW) && defined(HW_NCPU) + int __n; + int __mib[2] = {CTL_HW, HW_NCPU}; + std::size_t __sz = sizeof(__n); + sysctl(__mib, 2, &__n, &__sz, 0, 0); + return __n; +#elif defined(_SC_NPROCESSORS_ONLN) + return sysconf(_SC_NPROCESSORS_ONLN); +#else // !(defined(CTL_HW) && defined(HW_NCPU)) + // TODO: grovel through /proc or check cpuid on x86 and similar + // instructions on other architectures. +# if defined(_LIBCPP_MSVC) + _LIBCPP_WARNING("hardware_concurrency not yet implemented") +# else +# warning hardware_concurrency not yet implemented +# endif + return 0; // Means not computable [thread.thread.static] +#endif // defined(CTL_HW) && defined(HW_NCPU +} + // Thread local storage int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *)) { @@ -596,6 +637,13 @@ Sleep(__ms.count()); } +int __libcpp_thread_hw_concurrency() +{ + SYSTEM_INFO __info; + GetSystemInfo(&__info); + return __info.dwNumberOfProcessors; +} + // Thread Local Storage int __libcpp_tls_create(__libcpp_tls_key* __key, void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*)) Index: src/thread.cpp =================================================================== --- src/thread.cpp +++ src/thread.cpp @@ -15,26 +15,6 @@ #include "vector" #include "future" #include "limits" -#include - -#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) -# include -# if defined(BSD) -# include -# endif // defined(BSD) -#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) - -#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__CloudABI__) -# include -#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__CloudABI__) - -#if defined(__NetBSD__) -#pragma weak pthread_create // Do not create libpthread dependency -#endif - -#if defined(_LIBCPP_WIN32API) -#include -#endif // defined(_LIBCPP_WIN32API) _LIBCPP_BEGIN_NAMESPACE_STD @@ -77,35 +57,13 @@ unsigned thread::hardware_concurrency() _NOEXCEPT { -#if defined(CTL_HW) && defined(HW_NCPU) - unsigned n; - int mib[2] = {CTL_HW, HW_NCPU}; - std::size_t s = sizeof(n); - sysctl(mib, 2, &n, &s, 0, 0); - return n; -#elif defined(_SC_NPROCESSORS_ONLN) - long result = sysconf(_SC_NPROCESSORS_ONLN); - // sysconf returns -1 if the name is invalid, the option does not exist or - // does not have a definite limit. - // if sysconf returns some other negative number, we have no idea - // what is going on. Default to something safe. + int result = __libcpp_thread_hw_concurrency(); + + // Treat negative values as errors. Use a safe default value. if (result < 0) return 0; - return static_cast(result); -#elif defined(_LIBCPP_WIN32API) - SYSTEM_INFO info; - GetSystemInfo(&info); - return info.dwNumberOfProcessors; -#else // defined(CTL_HW) && defined(HW_NCPU) - // TODO: grovel through /proc or check cpuid on x86 and similar - // instructions on other architectures. -# if defined(_LIBCPP_MSVC) - _LIBCPP_WARNING("hardware_concurrency not yet implemented") -# else -# warning hardware_concurrency not yet implemented -# endif - return 0; // Means not computable [thread.thread.static] -#endif // defined(CTL_HW) && defined(HW_NCPU) + + return result; } namespace this_thread