From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1725) id 4D6AC386F467; Tue, 18 Aug 2020 18:35:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4D6AC386F467 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1597775734; bh=OpS4zpoJE1Hqi7TO9m7+wSiDs6J3agLcsqvBS3xrdXQ=; h=From:To:Subject:Date:From; b=IF1WBL3xomCxSiTljsTowJjyX/noOPGrh6dRdBKdZGpr2O6gJ3zPN2rqHJIHAE4iY mzewQzHnDeH/V68tcEzroUs20JhLetlnhEiCz6nbJJWoqU0B5XhKnLC+4H4s9aCBMt v8N1SED/7liGh6PjeAosLltAN5zyh9+02p3l6po4= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: William Schmidt To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc(refs/users/wschmidt/heads/builtins3)] libstdc++: Make std::this_thread functions work without gthreads X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/users/wschmidt/heads/builtins3 X-Git-Oldrev: 7840b4dc05539cf5575b3e9ff57ff5f6c3da2cae X-Git-Newrev: 5bbb1f3000c57fd4d95969b30fa0e35be6d54ffb Message-Id: <20200818183534.4D6AC386F467@sourceware.org> Date: Tue, 18 Aug 2020 18:35:34 +0000 (GMT) X-BeenThere: libstdc++-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Aug 2020 18:35:34 -0000 https://gcc.gnu.org/g:5bbb1f3000c57fd4d95969b30fa0e35be6d54ffb commit 5bbb1f3000c57fd4d95969b30fa0e35be6d54ffb Author: Jonathan Wakely Date: Tue Aug 11 16:16:21 2020 +0100 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. Diff: --- libstdc++-v3/include/std/thread | 29 +++++++++------ libstdc++-v3/src/c++11/thread.cc | 33 ++++++++++------- .../testsuite/30_threads/this_thread/58038.cc | 1 + .../testsuite/30_threads/this_thread/60421.cc | 1 + .../this_thread/{3.cc => sleep_for-mt.cc} | 0 .../testsuite/30_threads/this_thread/sleep_for.cc | 43 ++++++++++++++++++++++ .../this_thread/{4.cc => sleep_until-mt.cc} | 0 .../30_threads/this_thread/sleep_until.cc | 43 ++++++++++++++++++++++ .../30_threads/this_thread/{2.cc => yield.cc} | 9 ++--- 9 files changed, 127 insertions(+), 32 deletions(-) diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread index 0445ab1e319..30ae93a0d5b 100644 --- a/libstdc++-v3/include/std/thread +++ b/libstdc++-v3/include/std/thread @@ -35,12 +35,16 @@ # include #else -#include +#include // std::chrono::* + +#ifdef _GLIBCXX_USE_NANOSLEEP +# include // errno, EINTR +# include // nanosleep +#endif #if defined(_GLIBCXX_HAS_GTHREADS) #include -#include // std::chrono::* #include // std::unique_ptr #include // std::tuple @@ -49,14 +53,11 @@ # include // std::stop_source, std::stop_token, std::nostopstate #endif -#ifdef _GLIBCXX_USE_NANOSLEEP -# include // errno, EINTR -# include // nanosleep -#endif - #include // std::hash #include // 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(__rtime); auto __ns = chrono::duration_cast(__rtime - __s); #ifdef _GLIBCXX_USE_NANOSLEEP - __gthread_time_t __ts = + struct ::timespec __ts = { static_cast(__s.count()), static_cast(__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 2d8781724f2..a4c87d816a5 100644 --- a/libstdc++-v3/src/c++11/thread.cc +++ b/libstdc++-v3/src/c++11/thread.cc @@ -29,6 +29,16 @@ #include #include +#ifndef _GLIBCXX_USE_NANOSLEEP +# ifdef _GLIBCXX_HAVE_SLEEP +# include +# elif defined(_GLIBCXX_HAVE_WIN32_SLEEP) +# include +# 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 -# elif defined(_GLIBCXX_HAVE_WIN32_SLEEP) -# include -# 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(__s.count()), static_cast(__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 54ff0fb5321..fd007368527 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 #include diff --git a/libstdc++-v3/testsuite/30_threads/this_thread/60421.cc b/libstdc++-v3/testsuite/30_threads/this_thread/60421.cc index 531bb366c01..3f9d8b134d2 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 #include diff --git a/libstdc++-v3/testsuite/30_threads/this_thread/3.cc b/libstdc++-v3/testsuite/30_threads/this_thread/sleep_for-mt.cc similarity index 100% rename from libstdc++-v3/testsuite/30_threads/this_thread/3.cc rename to 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 00000000000..9552a23435e --- /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 +// . + +#include +#include +#include + +// 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 similarity index 100% rename from libstdc++-v3/testsuite/30_threads/this_thread/4.cc rename to 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 00000000000..6af875911df --- /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 +// . + +#include +#include +#include + +// 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 similarity index 85% rename from libstdc++-v3/testsuite/30_threads/this_thread/2.cc rename to libstdc++-v3/testsuite/30_threads/this_thread/yield.cc index 00dde147486..08f4efaaaf5 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(); }