diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -105,6 +105,7 @@ __charconv/from_chars_result.h __charconv/to_chars_result.h __chrono/calendar.h + __chrono/convert_to_timespec.h __chrono/duration.h __chrono/file_clock.h __chrono/high_resolution_clock.h @@ -367,6 +368,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,55 @@ +// -*- 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 <__chrono/duration.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 @@ -695,6 +695,7 @@ */ #include <__chrono/calendar.h> +#include <__chrono/convert_to_timespec.h> #include <__chrono/duration.h> #include <__chrono/file_clock.h> #include <__chrono/high_resolution_clock.h> diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -367,6 +367,7 @@ module __chrono { module calendar { private header "__chrono/calendar.h" } + module convert_to_timespec { private header "__chrono/convert_to_timespec.h" } module duration { private header "__chrono/duration.h" } module file_clock { private header "__chrono/file_clock.h" } module high_resolution_clock { private header "__chrono/high_resolution_clock.h" } @@ -902,7 +903,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>