Skip to content

Commit df51be8

Browse files
committed
[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
1 parent 5f4ae56 commit df51be8

File tree

13 files changed

+144
-53
lines changed

13 files changed

+144
-53
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ set(files
105105
__charconv/from_chars_result.h
106106
__charconv/to_chars_result.h
107107
__chrono/calendar.h
108+
__chrono/convert_to_timespec.h
108109
__chrono/duration.h
109110
__chrono/file_clock.h
110111
__chrono/high_resolution_clock.h
@@ -367,6 +368,7 @@ set(files
367368
__support/xlocale/__posix_l_fallback.h
368369
__support/xlocale/__strtonum_fallback.h
369370
__thread/poll_with_backoff.h
371+
__thread/timed_backoff_policy.h
370372
__threading_support
371373
__tree
372374
__tuple
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// -*- C++ -*-
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
#ifndef _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H
10+
#define _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H
11+
12+
#include <__chrono/duration.h>
13+
#include <__config>
14+
#include <limits>
15+
16+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17+
#pragma GCC system_header
18+
#endif
19+
20+
_LIBCPP_PUSH_MACROS
21+
#include <__undef_macros>
22+
23+
_LIBCPP_BEGIN_NAMESPACE_STD
24+
25+
// Convert a nanoseconds duration to the given TimeSpec type, which must have
26+
// the same properties as std::timespec.
27+
template <class _TimeSpec>
28+
_LIBCPP_HIDE_FROM_ABI inline
29+
_TimeSpec __convert_to_timespec(const chrono::nanoseconds& __ns)
30+
{
31+
using namespace chrono;
32+
seconds __s = duration_cast<seconds>(__ns);
33+
_TimeSpec __ts;
34+
typedef decltype(__ts.tv_sec) __ts_sec;
35+
const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max();
36+
37+
if (__s.count() < __ts_sec_max)
38+
{
39+
__ts.tv_sec = static_cast<__ts_sec>(__s.count());
40+
__ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count());
41+
}
42+
else
43+
{
44+
__ts.tv_sec = __ts_sec_max;
45+
__ts.tv_nsec = 999999999; // (10^9 - 1)
46+
}
47+
48+
return __ts;
49+
}
50+
51+
_LIBCPP_END_NAMESPACE_STD
52+
53+
_LIBCPP_POP_MACROS
54+
55+
#endif // _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// -*- C++ -*-
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
#ifndef _LIBCPP___THREAD_TIMED_BACKOFF_POLICY_H
10+
#define _LIBCPP___THREAD_TIMED_BACKOFF_POLICY_H
11+
12+
#include <__config>
13+
14+
#ifndef _LIBCPP_HAS_NO_THREADS
15+
16+
#include <__threading_support>
17+
#include <chrono>
18+
19+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20+
#pragma GCC system_header
21+
#endif
22+
23+
_LIBCPP_BEGIN_NAMESPACE_STD
24+
25+
struct __libcpp_timed_backoff_policy {
26+
_LIBCPP_INLINE_VISIBILITY
27+
bool operator()(chrono::nanoseconds __elapsed) const
28+
{
29+
if(__elapsed > chrono::milliseconds(128))
30+
__libcpp_thread_sleep_for(chrono::milliseconds(8));
31+
else if(__elapsed > chrono::microseconds(64))
32+
__libcpp_thread_sleep_for(__elapsed / 2);
33+
else if(__elapsed > chrono::microseconds(4))
34+
__libcpp_thread_yield();
35+
else
36+
{} // poll
37+
return false;
38+
}
39+
};
40+
41+
_LIBCPP_END_NAMESPACE_STD
42+
43+
#endif // _LIBCPP_HAS_NO_THREADS
44+
45+
#endif // _LIBCPP___THREAD_TIMED_BACKOFF_POLICY_H

libcxx/include/__threading_support

Lines changed: 2 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,6 @@
5454
typedef ::timespec __libcpp_timespec_t;
5555
#endif // !defined(_LIBCPP_HAS_NO_THREADS)
5656

57-
_LIBCPP_PUSH_MACROS
58-
#include <__undef_macros>
59-
6057
_LIBCPP_BEGIN_NAMESPACE_STD
6158

6259
#if !defined(_LIBCPP_HAS_NO_THREADS)
@@ -252,53 +249,9 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
252249

253250
#endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
254251

255-
struct __libcpp_timed_backoff_policy {
256-
_LIBCPP_INLINE_VISIBILITY
257-
bool operator()(chrono::nanoseconds __elapsed) const
258-
{
259-
if(__elapsed > chrono::milliseconds(128))
260-
__libcpp_thread_sleep_for(chrono::milliseconds(8));
261-
else if(__elapsed > chrono::microseconds(64))
262-
__libcpp_thread_sleep_for(__elapsed / 2);
263-
else if(__elapsed > chrono::microseconds(4))
264-
__libcpp_thread_yield();
265-
else
266-
{} // poll
267-
return false;
268-
}
269-
};
270-
271252
#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
272253
defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL))
273254

274-
275-
namespace __thread_detail {
276-
277-
_LIBCPP_HIDE_FROM_ABI inline
278-
__libcpp_timespec_t __convert_to_timespec(const chrono::nanoseconds& __ns)
279-
{
280-
using namespace chrono;
281-
seconds __s = duration_cast<seconds>(__ns);
282-
__libcpp_timespec_t __ts;
283-
typedef decltype(__ts.tv_sec) __ts_sec;
284-
const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max();
285-
286-
if (__s.count() < __ts_sec_max)
287-
{
288-
__ts.tv_sec = static_cast<__ts_sec>(__s.count());
289-
__ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count());
290-
}
291-
else
292-
{
293-
__ts.tv_sec = __ts_sec_max;
294-
__ts.tv_nsec = 999999999; // (10^9 - 1)
295-
}
296-
297-
return __ts;
298-
}
299-
300-
} // namespace __thread_detail
301-
302255
#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
303256

304257
_LIBCPP_HIDE_FROM_ABI inline
@@ -479,7 +432,7 @@ void __libcpp_thread_yield()
479432
_LIBCPP_HIDE_FROM_ABI inline
480433
void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
481434
{
482-
__libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns);
435+
__libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns);
483436
while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR);
484437
}
485438

@@ -664,7 +617,7 @@ void __libcpp_thread_yield()
664617
_LIBCPP_HIDE_FROM_ABI inline
665618
void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
666619
{
667-
__libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns);
620+
__libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns);
668621
thrd_sleep(&__ts, nullptr);
669622
}
670623

@@ -776,6 +729,4 @@ get_id() _NOEXCEPT
776729

777730
_LIBCPP_END_NAMESPACE_STD
778731

779-
_LIBCPP_POP_MACROS
780-
781732
#endif // _LIBCPP_THREADING_SUPPORT

libcxx/include/atomic

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,7 @@ template <class T>
521521
#include <__availability>
522522
#include <__config>
523523
#include <__thread/poll_with_backoff.h>
524+
#include <__thread/timed_backoff_policy.h>
524525
#include <cstddef>
525526
#include <cstdint>
526527
#include <cstring>

libcxx/include/barrier

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ namespace std
4747

4848
#include <__availability>
4949
#include <__config>
50+
#include <__thread/timed_backoff_policy.h>
5051
#include <atomic>
5152
#ifndef _LIBCPP_HAS_NO_TREE_BARRIER
5253
# include <memory>

libcxx/include/chrono

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,7 @@ constexpr chrono::year operator ""y(unsigned lo
695695
*/
696696

697697
#include <__chrono/calendar.h>
698+
#include <__chrono/convert_to_timespec.h>
698699
#include <__chrono/duration.h>
699700
#include <__chrono/file_clock.h>
700701
#include <__chrono/high_resolution_clock.h>

libcxx/include/module.modulemap

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ module std [system] {
367367

368368
module __chrono {
369369
module calendar { private header "__chrono/calendar.h" }
370+
module convert_to_timespec { private header "__chrono/convert_to_timespec.h" }
370371
module duration { private header "__chrono/duration.h" }
371372
module file_clock { private header "__chrono/file_clock.h" }
372373
module high_resolution_clock { private header "__chrono/high_resolution_clock.h" }
@@ -902,7 +903,8 @@ module std [system] {
902903
export *
903904

904905
module __thread {
905-
module poll_with_backoff { private header "__thread/poll_with_backoff.h" }
906+
module poll_with_backoff { private header "__thread/poll_with_backoff.h" }
907+
module timed_backoff_policy { private header "__thread/timed_backoff_policy.h" }
906908
}
907909
}
908910
module tuple {

libcxx/include/semaphore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ using binary_semaphore = counting_semaphore<1>;
4747

4848
#include <__availability>
4949
#include <__config>
50+
#include <__thread/timed_backoff_policy.h>
5051
#include <__threading_support>
5152
#include <atomic>
5253
#include <version>

libcxx/include/thread

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
8787
#include <__functional_base>
8888
#include <__mutex_base>
8989
#include <__thread/poll_with_backoff.h>
90+
#include <__thread/timed_backoff_policy.h>
9091
#include <__threading_support>
9192
#include <__utility/forward.h>
9293
#include <chrono>

0 commit comments

Comments
 (0)