diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2019-11-16 21:47:28 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2019-11-16 21:47:28 +0000 |
commit | 7453376403450b757b10b3d37b52b5db1f5c8d30 (patch) | |
tree | 2282726fd3424c934787eba1232b9fed2279900a | |
parent | 970a9bfaadcca4489613ca76a1800a32d1a93e14 (diff) | |
download | gcc-7453376403450b757b10b3d37b52b5db1f5c8d30.zip gcc-7453376403450b757b10b3d37b52b5db1f5c8d30.tar.gz gcc-7453376403450b757b10b3d37b52b5db1f5c8d30.tar.bz2 |
libstdc++: Optimize std::jthread construction
This change avoids storing a copy of a stop_token object that isn't
needed and won't be passed to the callable object. This slightly reduces
memory usage when the callable doesn't use a stop_token. It also removes
indirection in the invocation of the callable in the new thread, as
there is no lambda and no additional calls to std::invoke.
It also adds some missing [[nodiscard]] attributes, and the non-member
swap overload for std::jthread.
* include/std/thread (jthread::jthread()): Use nostopstate constant.
(jthread::jthread(Callable&&, Args&&...)): Use helper function to
create std::thread instead of indirection through a lambda. Use
remove_cvref_t instead of decay_t.
(jthread::joinable(), jthread::get_id(), jthread::native_handle())
(jthread::hardware_concurrency()): Add nodiscard attribute.
(swap(jthread&. jthread&)): Define hidden friend.
(jthread::_S_create): New helper function for constructor.
From-SVN: r278364
-rw-r--r-- | libstdc++-v3/ChangeLog | 11 | ||||
-rw-r--r-- | libstdc++-v3/include/std/thread | 55 |
2 files changed, 40 insertions, 26 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index ccbb0b4..bd1afdf 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,14 @@ +2019-11-16 Jonathan Wakely <jwakely@redhat.com> + + * include/std/thread (jthread::jthread()): Use nostopstate constant. + (jthread::jthread(Callable&&, Args&&...)): Use helper function to + create std::thread instead of indirection through a lambda. Use + remove_cvref_t instead of decay_t. + (jthread::joinable(), jthread::get_id(), jthread::native_handle()) + (jthread::hardware_concurrency()): Add nodiscard attribute. + (swap(jthread&. jthread&)): Define hidden friend. + (jthread::_S_create): New helper function for constructor. + 2019-11-15 Edward Smith-Rowland <3dw4rd@verizon.net> Implement the <tuple> part of C++20 p1032 Misc constexpr bits. diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread index 93afa76..010921b 100644 --- a/libstdc++-v3/include/std/thread +++ b/libstdc++-v3/include/std/thread @@ -425,31 +425,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using native_handle_type = std::thread::native_handle_type; jthread() noexcept - : _M_stop_source{ nostopstate_t{ } } + : _M_stop_source{nostopstate} { } template<typename _Callable, typename... _Args, - typename = std::enable_if_t<!std::is_same_v<std::decay_t<_Callable>, jthread>>> - explicit - jthread(_Callable&& __f, _Args&&... __args) - : _M_thread{[](stop_token __token, auto&& __cb, auto&&... __args) - { - if constexpr(std::is_invocable_v<_Callable, stop_token, _Args...>) - { - std::invoke(std::forward<decltype(__cb)>(__cb), - std::move(__token), - std::forward<decltype(__args)>(__args)...); - } - else - { - std::invoke(std::forward<decltype(__cb)>(__cb), - std::forward<decltype(__args)>(__args)...); - } - }, - _M_stop_source.get_token(), - std::forward<_Callable>(__f), - std::forward<_Args>(__args)...} - { } + typename = enable_if_t<!is_same_v<remove_cvref_t<_Callable>, + jthread>>> + explicit + jthread(_Callable&& __f, _Args&&... __args) + : _M_thread{_S_create(_M_stop_source, std::forward<_Callable>(__f), + std::forward<_Args>(__args)...)} + { } jthread(const jthread&) = delete; jthread(jthread&&) noexcept = default; @@ -476,7 +462,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::swap(_M_thread, __other._M_thread); } - bool + [[nodiscard]] bool joinable() const noexcept { return _M_thread.joinable(); @@ -494,19 +480,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_thread.detach(); } - id + [[nodiscard]] id get_id() const noexcept { _M_thread.get_id(); } - native_handle_type + [[nodiscard]] native_handle_type native_handle() { return _M_thread.native_handle(); } - static unsigned + [[nodiscard]] static unsigned hardware_concurrency() noexcept { return std::thread::hardware_concurrency(); @@ -529,7 +515,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return get_stop_source().request_stop(); } + friend void swap(jthread& __lhs, jthread& __rhs) noexcept + { + __lhs.swap(__rhs); + } + private: + template<typename _Callable, typename... _Args> + static thread + _S_create(stop_source& __ssrc, _Callable&& __f, _Args&&... __args) + { + if constexpr(is_invocable_v<_Callable, stop_token, _Args...>) + return thread{std::forward<_Callable>(__f), __ssrc.get_token(), + std::forward<_Args>(__args)...}; + else + return thread{std::forward<_Callable>(__f), + std::forward<_Args>(__args)...}; + } + stop_source _M_stop_source; std::thread _M_thread; }; |