On 09/12/20 12:49 +0000, Jonathan Wakely wrote:
On 09/12/20 13:32 +0100, Vladimir V wrote:
Hello.

While testing with the current upstream I encountered a compilation issue.
Although I build with "--disable-threads" flag the following error occurs:

../../../../../libstdc++-v3/src/c++11/thread.cc:39:4: error: #error "No
sleep function known for this target"

Previously the check was inside the  #ifdef _GLIBCXX_HAS_GTHREADS that
prevented the error from happening (in my case with gcc v10.1),
So I would like to ask if the thread.cc should be involved in the build if
the threads support is configured to be disabled?

Yes, the file is always built, but which definitions it contains
depends on what is configured for the target.

The std::this_thread::sleep_for and std::this_thread::sleep_until
functions don't actually depend on threads at all. They just sleep.

But that still requires target support, just different support from
threads.

And if it should, then can the condition be reworked to cover the described
case?

Yes, I'll do that. Thanks for bringing it to my attention.

I assume we can't use avr-libc's delay functions, because they depend
on the CPU clock frequency, which isn't known when we compile
libstdc++. So I'll just suppress the declarations of those functions
and remove the #error.

The attached patch adds a new _GLIBCXX_NO_SLEEP configure macro which
should get defined for your hosted AVR build. That should mean that
std::this_thread::sleep_for is not defined, and src/c++11/thread.cc
will no longer insist on some way to sleep being supported.

I've only tested this on powerpc64le-linux, so please let me know if
it works for you.

Pushed to master.


commit 0aa1786d34b891c8e1e219fb11255af5358013c4
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Wed Dec 9 16:53:18 2020

    libstdc++: Fix build failure for target with no way to sleep
    
    In previous releases the std::this_thread::sleep_for function was only
    declared if the target supports multiple threads. I changed that
    recently in r11-2649-g5bbb1f3000c57fd4d95969b30fa0e35be6d54ffb so that
    sleep_for could be used single-threaded. But that means that targets
    using --disable-threads are now required to provide some way to sleep.
    This breaks the build for (at least) AVR when trying to build a hosted
    library.
    
    This patch adds a new autoconf macro that is defined when no way to
    sleep is available, and uses that to suppress the sleeping functions in
    std::this_thread.
    
    The #error in src/c++11/thread.cc is retained for the case where there
    is no sleep function available but multiple threads are supported. This
    is consistent with previous releases, but that #error could probably be
    removed without any consequences.
    
    libstdc++-v3/ChangeLog:
    
            * acinclude.m4 (GLIBCXX_ENABLE_LIBSTDCXX_TIME): Define NO_SLEEP
            if none of nanosleep, sleep and Sleep is available.
            * config.h.in: Regenerate.
            * configure: Regenerate.
            * include/std/thread [_GLIBCXX_NO_SLEEP] (__sleep_for): Do
            not declare.
            [_GLIBCXX_NO_SLEEP] (sleep_for, sleep_until): Do not
            define.
            * src/c++11/thread.cc [_GLIBCXX_NO_SLEEP] (__sleep_for): Do
            not define.

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index fcd9ea3d23a..61191812c92 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -1626,16 +1626,22 @@ AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_TIME], [
   fi
 
   if test x"$ac_has_nanosleep$ac_has_sleep" = x"nono"; then
+      ac_no_sleep=yes
       AC_MSG_CHECKING([for Sleep])
       AC_TRY_COMPILE([#include <windows.h>],
                      [Sleep(1)],
                      [ac_has_win32_sleep=yes],[ac_has_win32_sleep=no])
       if test x"$ac_has_win32_sleep" = x"yes"; then
         AC_DEFINE(HAVE_WIN32_SLEEP,1, [Defined if Sleep exists.])
+	ac_no_sleep=no
       fi
       AC_MSG_RESULT($ac_has_win32_sleep)
   fi
 
+  if test x"$ac_no_sleep" = x"yes"; then
+    AC_DEFINE(NO_SLEEP,1, [Defined if no way to sleep is available.])
+  fi
+
   AC_SUBST(GLIBCXX_LIBS)
 
   CXXFLAGS="$ac_save_CXXFLAGS"
diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread
index 6ea8a51c0cf..8d0ede2b6c2 100644
--- a/libstdc++-v3/include/std/thread
+++ b/libstdc++-v3/include/std/thread
@@ -122,8 +122,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    */
   namespace this_thread
   {
+#ifndef _GLIBCXX_NO_SLEEP
+
+#ifndef _GLIBCXX_USE_NANOSLEEP
     void
     __sleep_for(chrono::seconds, chrono::nanoseconds);
+#endif
 
     /// this_thread::sleep_for
     template<typename _Rep, typename _Period>
@@ -168,7 +172,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	    __now = _Clock::now();
 	  }
       }
-  }
+  } // namespace this_thread
+#endif // ! NO_SLEEP
 
 #ifdef __cpp_lib_jthread
 
diff --git a/libstdc++-v3/src/c++11/thread.cc b/libstdc++-v3/src/c++11/thread.cc
index a9c92804959..62f6ddcd802 100644
--- a/libstdc++-v3/src/c++11/thread.cc
+++ b/libstdc++-v3/src/c++11/thread.cc
@@ -35,7 +35,8 @@
 #  include <unistd.h>
 # elif defined(_GLIBCXX_HAVE_WIN32_SLEEP)
 #  include <windows.h>
-# else
+# elif defined _GLIBCXX_NO_SLEEP && defined _GLIBCXX_HAS_GTHREADS
+// We expect to be able to sleep for targets that support multiple threads:
 #  error "No sleep function known for this target"
 # endif
 #endif
@@ -196,6 +197,7 @@ _GLIBCXX_END_NAMESPACE_VERSION
 
 #endif // _GLIBCXX_HAS_GTHREADS
 
+#ifndef _GLIBCXX_NO_SLEEP
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -252,3 +254,4 @@ namespace this_thread
 }
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
+#endif // ! NO_SLEEP

Reply via email to