diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -102,6 +102,7 @@ __charconv/chars_format.h __charconv/from_chars_result.h __charconv/to_chars_result.h + __chrono/convert_to_timespec.h __compare/common_comparison_category.h __compare/compare_three_way.h __compare/compare_three_way_result.h @@ -356,6 +357,7 @@ __support/xlocale/__posix_l_fallback.h __support/xlocale/__strtonum_fallback.h __thread/poll_with_backoff.h + __thread/timed_backoff_policy.h __threading_support __tree __tuple diff --git a/libcxx/include/__chrono/convert_to_timespec.h b/libcxx/include/__chrono/convert_to_timespec.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__chrono/convert_to_timespec.h @@ -0,0 +1,54 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#ifndef _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H +#define _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Convert a nanoseconds duration to the given TimeSpec type, which must have +// the same properties as std::timespec. +template +_LIBCPP_HIDE_FROM_ABI inline +_TimeSpec __convert_to_timespec(const chrono::nanoseconds& __ns) +{ + using namespace chrono; + seconds __s = duration_cast(__ns); + _TimeSpec __ts; + typedef decltype(__ts.tv_sec) __ts_sec; + const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); + + if (__s.count() < __ts_sec_max) + { + __ts.tv_sec = static_cast<__ts_sec>(__s.count()); + __ts.tv_nsec = static_cast((__ns - __s).count()); + } + else + { + __ts.tv_sec = __ts_sec_max; + __ts.tv_nsec = 999999999; // (10^9 - 1) + } + + return __ts; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H diff --git a/libcxx/include/__thread/timed_backoff_policy.h b/libcxx/include/__thread/timed_backoff_policy.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__thread/timed_backoff_policy.h @@ -0,0 +1,45 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#ifndef _LIBCPP___THREAD_TIMED_BACKOFF_POLICY_H +#define _LIBCPP___THREAD_TIMED_BACKOFF_POLICY_H + +#include <__config> + +#ifndef _LIBCPP_HAS_NO_THREADS + +#include <__threading_support> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct __libcpp_timed_backoff_policy { + _LIBCPP_INLINE_VISIBILITY + bool 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; + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_HAS_NO_THREADS + +#endif // _LIBCPP___THREAD_TIMED_BACKOFF_POLICY_H diff --git a/libcxx/include/__threading_support b/libcxx/include/__threading_support --- a/libcxx/include/__threading_support +++ b/libcxx/include/__threading_support @@ -54,9 +54,6 @@ typedef ::timespec __libcpp_timespec_t; #endif // !defined(_LIBCPP_HAS_NO_THREADS) -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD #if !defined(_LIBCPP_HAS_NO_THREADS) @@ -252,53 +249,9 @@ #endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) -struct __libcpp_timed_backoff_policy { - _LIBCPP_INLINE_VISIBILITY - bool 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; - } -}; - #if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) - -namespace __thread_detail { - -_LIBCPP_HIDE_FROM_ABI inline -__libcpp_timespec_t __convert_to_timespec(const chrono::nanoseconds& __ns) -{ - using namespace chrono; - seconds __s = duration_cast(__ns); - __libcpp_timespec_t __ts; - typedef decltype(__ts.tv_sec) __ts_sec; - const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); - - if (__s.count() < __ts_sec_max) - { - __ts.tv_sec = static_cast<__ts_sec>(__s.count()); - __ts.tv_nsec = static_cast((__ns - __s).count()); - } - else - { - __ts.tv_sec = __ts_sec_max; - __ts.tv_nsec = 999999999; // (10^9 - 1) - } - - return __ts; -} - -} // namespace __thread_detail - #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) _LIBCPP_HIDE_FROM_ABI inline @@ -479,7 +432,7 @@ _LIBCPP_HIDE_FROM_ABI inline void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) { - __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns); + __libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns); while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR); } @@ -664,7 +617,7 @@ _LIBCPP_HIDE_FROM_ABI inline void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) { - __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns); + __libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns); thrd_sleep(&__ts, nullptr); } @@ -776,6 +729,4 @@ _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP_THREADING_SUPPORT diff --git a/libcxx/include/atomic b/libcxx/include/atomic --- a/libcxx/include/atomic +++ b/libcxx/include/atomic @@ -521,6 +521,7 @@ #include <__availability> #include <__config> #include <__thread/poll_with_backoff.h> +#include <__thread/timed_backoff_policy.h> #include #include #include diff --git a/libcxx/include/barrier b/libcxx/include/barrier --- a/libcxx/include/barrier +++ b/libcxx/include/barrier @@ -47,6 +47,7 @@ #include <__availability> #include <__config> +#include <__thread/timed_backoff_policy.h> #include #ifndef _LIBCPP_HAS_NO_TREE_BARRIER # include diff --git a/libcxx/include/chrono b/libcxx/include/chrono --- a/libcxx/include/chrono +++ b/libcxx/include/chrono @@ -2835,4 +2835,7 @@ _LIBCPP_POP_MACROS +// TODO: Modularize so this header doesn't have to sit alone here. +#include <__chrono/convert_to_timespec.h> + #endif // _LIBCPP_CHRONO diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -362,6 +362,10 @@ module chrono { header "chrono" export * + + module __chrono { + module convert_to_timespec { private header "__thread/convert_to_timespec.h" } + } } module codecvt { header "codecvt" @@ -885,7 +889,8 @@ export * module __thread { - module poll_with_backoff { private header "__thread/poll_with_backoff.h" } + module poll_with_backoff { private header "__thread/poll_with_backoff.h" } + module timed_backoff_policy { private header "__thread/timed_backoff_policy.h" } } } module tuple { diff --git a/libcxx/include/semaphore b/libcxx/include/semaphore --- a/libcxx/include/semaphore +++ b/libcxx/include/semaphore @@ -47,6 +47,7 @@ #include <__availability> #include <__config> +#include <__thread/timed_backoff_policy.h> #include <__threading_support> #include #include diff --git a/libcxx/include/thread b/libcxx/include/thread --- a/libcxx/include/thread +++ b/libcxx/include/thread @@ -87,6 +87,7 @@ #include <__functional_base> #include <__mutex_base> #include <__thread/poll_with_backoff.h> +#include <__thread/timed_backoff_policy.h> #include <__threading_support> #include <__utility/forward.h> #include diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp --- a/libcxx/src/atomic.cpp +++ b/libcxx/src/atomic.cpp @@ -9,9 +9,10 @@ #include <__config> #ifndef _LIBCPP_HAS_NO_THREADS -#include #include +#include #include +#include #ifdef __linux__ diff --git a/libcxx/test/libcxx/diagnostics/detail.headers/chrono/convert_to_timespec.module.verify.cpp b/libcxx/test/libcxx/diagnostics/detail.headers/chrono/convert_to_timespec.module.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/diagnostics/detail.headers/chrono/convert_to_timespec.module.verify.cpp @@ -0,0 +1,15 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: modules-build + +// WARNING: This test was generated by 'generate_private_header_tests.py' +// and should not be edited manually. + +// expected-error@*:* {{use of private header from outside its module: '__chrono/convert_to_timespec.h'}} +#include <__chrono/convert_to_timespec.h> diff --git a/libcxx/test/libcxx/diagnostics/detail.headers/thread/timed_backoff_policy.module.verify.cpp b/libcxx/test/libcxx/diagnostics/detail.headers/thread/timed_backoff_policy.module.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/diagnostics/detail.headers/thread/timed_backoff_policy.module.verify.cpp @@ -0,0 +1,15 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: modules-build + +// WARNING: This test was generated by 'generate_private_header_tests.py' +// and should not be edited manually. + +// expected-error@*:* {{use of private header from outside its module: '__thread/timed_backoff_policy.h'}} +#include <__thread/timed_backoff_policy.h>