diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2020-08-11 16:16:21 +0100 |
---|---|---|
committer | Jonathan Wakely <jwakely@redhat.com> | 2020-08-11 16:16:21 +0100 |
commit | 5bbb1f3000c57fd4d95969b30fa0e35be6d54ffb (patch) | |
tree | 3a4d5f7d465de0a98c1f1f3938e9746c772a03a8 | |
parent | 7840b4dc05539cf5575b3e9ff57ff5f6c3da2cae (diff) | |
download | gcc-5bbb1f3000c57fd4d95969b30fa0e35be6d54ffb.zip gcc-5bbb1f3000c57fd4d95969b30fa0e35be6d54ffb.tar.gz gcc-5bbb1f3000c57fd4d95969b30fa0e35be6d54ffb.tar.bz2 |
libstdc++: Make std::this_thread functions work without gthreads
The only function in namespace std::this_thread that actually depends on
thread support being present is this_thread::get_id(). The other
functions (yield, sleep_for and sleep_until) can be defined for targets
without gthreads.
A small change is needed in std::this_thread::sleep_for which currently
uses the __gthread_time_t typedef. Since it just calls nanosleep
directly, it should use timespec directly instead of the typedef.
Even std::this_thread::get_id() could be made to work, the only
difficulty is that it returns a value of type std::thread::id and
std::thread is only defined when gthreads support exists.
libstdc++-v3/ChangeLog:
* include/std/thread [!_GLIBCXX_HAS_GTHREADS] (this_thread::yield)
(this_thread::sleep_until): Define.
[!_GLIBCXX_HAS_GTHREADS] (this_thread::sleep_for): Define. Replace
use of __gthread_time_t typedef with timespec.
* src/c++11/thread.cc [!_GLIBCXX_HAS_GTHREADS] (__sleep_for):
Likewise.
* testsuite/30_threads/this_thread/2.cc: Moved to...
* testsuite/30_threads/this_thread/yield.cc: ...here.
* testsuite/30_threads/this_thread/3.cc: Moved to...
* testsuite/30_threads/this_thread/sleep_for-mt.cc: ...here.
* testsuite/30_threads/this_thread/4.cc: Moved to...
* testsuite/30_threads/this_thread/sleep_until-mt.cc: ...here.
* testsuite/30_threads/this_thread/58038.cc: Add
dg-require-sleep.
* testsuite/30_threads/this_thread/60421.cc: Likewise.
* testsuite/30_threads/this_thread/sleep_for.cc: New test.
* testsuite/30_threads/this_thread/sleep_until.cc: New test.
-rw-r--r-- | libstdc++-v3/include/std/thread | 29 | ||||
-rw-r--r-- | libstdc++-v3/src/c++11/thread.cc | 33 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/30_threads/this_thread/58038.cc | 1 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/30_threads/this_thread/60421.cc | 1 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/30_threads/this_thread/sleep_for-mt.cc (renamed from libstdc++-v3/testsuite/30_threads/this_thread/3.cc) | 0 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/30_threads/this_thread/sleep_for.cc | 43 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/30_threads/this_thread/sleep_until-mt.cc (renamed from libstdc++-v3/testsuite/30_threads/this_thread/4.cc) | 0 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/30_threads/this_thread/sleep_until.cc | 43 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/30_threads/this_thread/yield.cc (renamed from libstdc++-v3/testsuite/30_threads/this_thread/2.cc) | 9 |
9 files changed, 127 insertions, 32 deletions
diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread index 0445ab1..30ae93a 100644 --- a/libstdc++-v3/include/std/thread +++ b/libstdc++-v3/include/std/thread @@ -35,12 +35,16 @@ # include <bits/c++0x_warning.h> #else -#include <bits/c++config.h> +#include <chrono> // std::chrono::* + +#ifdef _GLIBCXX_USE_NANOSLEEP +# include <cerrno> // errno, EINTR +# include <time.h> // nanosleep +#endif #if defined(_GLIBCXX_HAS_GTHREADS) #include <bits/gthr.h> -#include <chrono> // std::chrono::* #include <memory> // std::unique_ptr #include <tuple> // std::tuple @@ -49,14 +53,11 @@ # include <stop_token> // std::stop_source, std::stop_token, std::nostopstate #endif -#ifdef _GLIBCXX_USE_NANOSLEEP -# include <cerrno> // errno, EINTR -# include <time.h> // nanosleep -#endif - #include <bits/functional_hash.h> // std::hash #include <bits/invoke.h> // std::__invoke +#endif // _GLIBCXX_HAS_GTHREADS + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -69,6 +70,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ +#if defined(_GLIBCXX_HAS_GTHREADS) /// thread class thread { @@ -352,6 +354,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION else return __out << __id._M_thread; } +#endif // _GLIBCXX_HAS_GTHREADS /** @namespace std::this_thread * @brief ISO C++ 2011 namespace for interacting with the current thread @@ -360,6 +363,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ namespace this_thread { +#if defined _GLIBCXX_HAS_GTHREADS /// get_id inline thread::id get_id() noexcept @@ -374,12 +378,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif return thread::id(__gthread_self()); } +#endif // _GLIBCXX_HAS_GTHREADS /// yield inline void yield() noexcept { -#ifdef _GLIBCXX_USE_SCHED_YIELD +#if defined _GLIBCXX_HAS_GTHREADS && defined _GLIBCXX_USE_SCHED_YIELD __gthread_yield(); #endif } @@ -397,7 +402,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION auto __s = chrono::duration_cast<chrono::seconds>(__rtime); auto __ns = chrono::duration_cast<chrono::nanoseconds>(__rtime - __s); #ifdef _GLIBCXX_USE_NANOSLEEP - __gthread_time_t __ts = + struct ::timespec __ts = { static_cast<std::time_t>(__s.count()), static_cast<long>(__ns.count()) @@ -432,8 +437,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } - // @} group threads - #ifdef __cpp_lib_jthread class jthread @@ -562,8 +565,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION thread _M_thread; }; #endif // __cpp_lib_jthread + + // @} group threads + _GLIBCXX_END_NAMESPACE_VERSION } // namespace -#endif // _GLIBCXX_HAS_GTHREADS #endif // C++11 #endif // _GLIBCXX_THREAD diff --git a/libstdc++-v3/src/c++11/thread.cc b/libstdc++-v3/src/c++11/thread.cc index 2d87817..a4c87d8 100644 --- a/libstdc++-v3/src/c++11/thread.cc +++ b/libstdc++-v3/src/c++11/thread.cc @@ -29,6 +29,16 @@ #include <cerrno> #include <cxxabi_forced.h> +#ifndef _GLIBCXX_USE_NANOSLEEP +# ifdef _GLIBCXX_HAVE_SLEEP +# include <unistd.h> +# elif defined(_GLIBCXX_HAVE_WIN32_SLEEP) +# include <windows.h> +# else +# error "No sleep function known for this target" +# endif +#endif + #ifdef _GLIBCXX_HAS_GTHREADS #if defined(_GLIBCXX_USE_GET_NPROCS) @@ -59,16 +69,6 @@ static inline int get_nprocs() # define _GLIBCXX_NPROCS 0 #endif -#ifndef _GLIBCXX_USE_NANOSLEEP -# ifdef _GLIBCXX_HAVE_SLEEP -# include <unistd.h> -# elif defined(_GLIBCXX_HAVE_WIN32_SLEEP) -# include <windows.h> -# else -# error "No sleep function known for this target" -# endif -#endif - namespace std _GLIBCXX_VISIBILITY(default) { extern "C" @@ -180,13 +180,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __n; } +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#endif // _GLIBCXX_HAS_GTHREADS + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION namespace this_thread { void __sleep_for(chrono::seconds __s, chrono::nanoseconds __ns) { #ifdef _GLIBCXX_USE_NANOSLEEP - __gthread_time_t __ts = + struct ::timespec __ts = { static_cast<std::time_t>(__s.count()), static_cast<long>(__ns.count()) @@ -231,8 +239,5 @@ namespace this_thread #endif } } - _GLIBCXX_END_NAMESPACE_VERSION } // namespace std - -#endif // _GLIBCXX_HAS_GTHREADS diff --git a/libstdc++-v3/testsuite/30_threads/this_thread/58038.cc b/libstdc++-v3/testsuite/30_threads/this_thread/58038.cc index 54ff0fb..fd00736 100644 --- a/libstdc++-v3/testsuite/30_threads/this_thread/58038.cc +++ b/libstdc++-v3/testsuite/30_threads/this_thread/58038.cc @@ -17,6 +17,7 @@ // { dg-do run { target c++11 } } // { dg-require-time "" } +// { dg-require-sleep "" } #include <thread> #include <chrono> diff --git a/libstdc++-v3/testsuite/30_threads/this_thread/60421.cc b/libstdc++-v3/testsuite/30_threads/this_thread/60421.cc index 531bb36..3f9d8b1 100644 --- a/libstdc++-v3/testsuite/30_threads/this_thread/60421.cc +++ b/libstdc++-v3/testsuite/30_threads/this_thread/60421.cc @@ -22,6 +22,7 @@ // { dg-require-cstdint "" } // { dg-require-gthreads "" } // { dg-require-time "" } +// { dg-require-sleep "" } #include <thread> #include <chrono> diff --git a/libstdc++-v3/testsuite/30_threads/this_thread/3.cc b/libstdc++-v3/testsuite/30_threads/this_thread/sleep_for-mt.cc index 4599381..4599381 100644 --- a/libstdc++-v3/testsuite/30_threads/this_thread/3.cc +++ b/libstdc++-v3/testsuite/30_threads/this_thread/sleep_for-mt.cc diff --git a/libstdc++-v3/testsuite/30_threads/this_thread/sleep_for.cc b/libstdc++-v3/testsuite/30_threads/this_thread/sleep_for.cc new file mode 100644 index 0000000..9552a23 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/this_thread/sleep_for.cc @@ -0,0 +1,43 @@ +// { dg-do run { target c++11 } } +// { dg-require-sleep "" } + +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <chrono> +#include <thread> +#include <testsuite_hooks.h> + +// This tests this_thread::sleep_until without using -pthread + +namespace chr = std::chrono; + +void +test01() +{ + chr::system_clock::time_point begin = chr::system_clock::now(); + chr::microseconds ms(500); + + std::this_thread::sleep_for(ms); + + VERIFY( (chr::system_clock::now() - begin) >= ms ); +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/30_threads/this_thread/4.cc b/libstdc++-v3/testsuite/30_threads/this_thread/sleep_until-mt.cc index fc8d10d..fc8d10d 100644 --- a/libstdc++-v3/testsuite/30_threads/this_thread/4.cc +++ b/libstdc++-v3/testsuite/30_threads/this_thread/sleep_until-mt.cc diff --git a/libstdc++-v3/testsuite/30_threads/this_thread/sleep_until.cc b/libstdc++-v3/testsuite/30_threads/this_thread/sleep_until.cc new file mode 100644 index 0000000..6af8759 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/this_thread/sleep_until.cc @@ -0,0 +1,43 @@ +// { dg-do run { target c++11 } } +// { dg-require-sleep "" } + +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <chrono> +#include <thread> +#include <testsuite_hooks.h> + +// This tests this_thread::sleep_until without using -pthread + +namespace chr = std::chrono; + +void +test01() +{ + chr::system_clock::time_point begin = chr::system_clock::now(); + chr::microseconds ms(500); + + std::this_thread::sleep_until(chr::system_clock::now() + ms); + + VERIFY( (chr::system_clock::now() - begin) >= ms ); +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/30_threads/this_thread/2.cc b/libstdc++-v3/testsuite/30_threads/this_thread/yield.cc index 00dde14..08f4efa 100644 --- a/libstdc++-v3/testsuite/30_threads/this_thread/2.cc +++ b/libstdc++-v3/testsuite/30_threads/this_thread/yield.cc @@ -1,8 +1,5 @@ -// { dg-do run } -// { dg-options "-pthread" } -// { dg-require-effective-target c++11 } -// { dg-require-effective-target pthread } -// { dg-require-gthreads "" } +// { dg-do run { target c++11 } } +// { dg-additional-options "-pthread" { target pthread } } // Copyright (C) 2008-2020 Free Software Foundation, Inc. // @@ -28,7 +25,7 @@ int main() { - try + try { std::this_thread::yield(); } |