[libc++] Split a few utilities out of __threading_support
This change is the basis for a further refactoring where I'm going to split up the various implementations we have in __threading_support to make that code easier to understand. Note that I had to make __convert_to_timespec a template to break circular dependencies. Concretely, we never seem to use it with anything other than ::timespec, but I am wary of hardcoding that assumption as part of this change, since I suspect there's a reason for going through these hoops in the first place. Differential Revision: https://reviews.llvm.org/D116944
This commit is contained in:
parent
5f4ae56457
commit
df51be85e4
|
@ -105,6 +105,7 @@ set(files
|
|||
__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 @@ set(files
|
|||
__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
|
||||
|
|
|
@ -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 <limits>
|
||||
|
||||
#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 <class _TimeSpec>
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
_TimeSpec __convert_to_timespec(const chrono::nanoseconds& __ns)
|
||||
{
|
||||
using namespace chrono;
|
||||
seconds __s = duration_cast<seconds>(__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<decltype(__ts.tv_nsec)>((__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
|
|
@ -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 <chrono>
|
||||
|
||||
#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
|
|
@ -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 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
|
|||
|
||||
#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<seconds>(__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<decltype(__ts.tv_nsec)>((__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 @@ void __libcpp_thread_yield()
|
|||
_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 @@ void __libcpp_thread_yield()
|
|||
_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 @@ get_id() _NOEXCEPT
|
|||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP_THREADING_SUPPORT
|
||||
|
|
|
@ -521,6 +521,7 @@ template <class T>
|
|||
#include <__availability>
|
||||
#include <__config>
|
||||
#include <__thread/poll_with_backoff.h>
|
||||
#include <__thread/timed_backoff_policy.h>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
|
|
@ -47,6 +47,7 @@ namespace std
|
|||
|
||||
#include <__availability>
|
||||
#include <__config>
|
||||
#include <__thread/timed_backoff_policy.h>
|
||||
#include <atomic>
|
||||
#ifndef _LIBCPP_HAS_NO_TREE_BARRIER
|
||||
# include <memory>
|
||||
|
|
|
@ -695,6 +695,7 @@ constexpr chrono::year operator ""y(unsigned lo
|
|||
*/
|
||||
|
||||
#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>
|
||||
|
|
|
@ -367,6 +367,7 @@ module std [system] {
|
|||
|
||||
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 @@ module std [system] {
|
|||
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 {
|
||||
|
|
|
@ -47,6 +47,7 @@ using binary_semaphore = counting_semaphore<1>;
|
|||
|
||||
#include <__availability>
|
||||
#include <__config>
|
||||
#include <__thread/timed_backoff_policy.h>
|
||||
#include <__threading_support>
|
||||
#include <atomic>
|
||||
#include <version>
|
||||
|
|
|
@ -87,6 +87,7 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
|
|||
#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 <chrono>
|
||||
|
|
|
@ -9,9 +9,10 @@
|
|||
#include <__config>
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
|
||||
#include <climits>
|
||||
#include <atomic>
|
||||
#include <climits>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
Loading…
Reference in New Issue