[libcxx-commits] [libcxx] df51be8 - [libc++] Split a few utilities out of __threading_support

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jan 18 09:23:48 PST 2022


Author: Louis Dionne
Date: 2022-01-18T12:23:44-05:00
New Revision: df51be85e4aee2365338186e38aebf7ffe81fc90

URL: https://github.com/llvm/llvm-project/commit/df51be85e4aee2365338186e38aebf7ffe81fc90
DIFF: https://github.com/llvm/llvm-project/commit/df51be85e4aee2365338186e38aebf7ffe81fc90.diff

LOG: [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

Added: 
    libcxx/include/__chrono/convert_to_timespec.h
    libcxx/include/__thread/timed_backoff_policy.h
    libcxx/test/libcxx/diagnostics/detail.headers/chrono/convert_to_timespec.module.verify.cpp
    libcxx/test/libcxx/diagnostics/detail.headers/thread/timed_backoff_policy.module.verify.cpp

Modified: 
    libcxx/include/CMakeLists.txt
    libcxx/include/__threading_support
    libcxx/include/atomic
    libcxx/include/barrier
    libcxx/include/chrono
    libcxx/include/module.modulemap
    libcxx/include/semaphore
    libcxx/include/thread
    libcxx/src/atomic.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 39f23ee856b0e..7d56123a69d1a 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -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

diff  --git a/libcxx/include/__chrono/convert_to_timespec.h b/libcxx/include/__chrono/convert_to_timespec.h
new file mode 100644
index 0000000000000..0106e6dec3e1c
--- /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 <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

diff  --git a/libcxx/include/__thread/timed_backoff_policy.h b/libcxx/include/__thread/timed_backoff_policy.h
new file mode 100644
index 0000000000000..d85a34071c6d4
--- /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 <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

diff  --git a/libcxx/include/__threading_support b/libcxx/include/__threading_support
index 68f381a621830..bf85d5f5d9f05 100644
--- 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 @@ 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

diff  --git a/libcxx/include/atomic b/libcxx/include/atomic
index 4b60d4d6802b4..02844642fa08d 100644
--- a/libcxx/include/atomic
+++ b/libcxx/include/atomic
@@ -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>

diff  --git a/libcxx/include/barrier b/libcxx/include/barrier
index aef88556a011d..c7af46271745d 100644
--- a/libcxx/include/barrier
+++ b/libcxx/include/barrier
@@ -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>

diff  --git a/libcxx/include/chrono b/libcxx/include/chrono
index ee2d63cda7788..eada2b8520e3b 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -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>

diff  --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index e5a92e97f53fe..c17ecc98aa5d9 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -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 {

diff  --git a/libcxx/include/semaphore b/libcxx/include/semaphore
index f83f7b4551116..7dffc94b13bab 100644
--- a/libcxx/include/semaphore
+++ b/libcxx/include/semaphore
@@ -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>

diff  --git a/libcxx/include/thread b/libcxx/include/thread
index 00c4ae35eccbc..27756e42cdcb9 100644
--- a/libcxx/include/thread
+++ b/libcxx/include/thread
@@ -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>

diff  --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp
index 9b61a16106c28..250d33e98b027 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -9,9 +9,10 @@
 #include <__config>
 #ifndef _LIBCPP_HAS_NO_THREADS
 
-#include <climits>
 #include <atomic>
+#include <climits>
 #include <functional>
+#include <thread>
 
 #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
index 0000000000000..664ccd72f20aa
--- /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
index 0000000000000..45e04f4cb86c4
--- /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>


        


More information about the libcxx-commits mailing list