From: Jonathan Wakely Date: Sat, 16 Nov 2019 21:47:28 +0000 (+0000) Subject: libstdc++: Optimize std::jthread construction X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7453376403450b757b10b3d37b52b5db1f5c8d30;p=gcc.git 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 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index ccbb0b456da..bd1afdfd0a5 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,14 @@ +2019-11-16 Jonathan Wakely + + * 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 part of C++20 p1032 Misc constexpr bits. diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread index 93afa766d18..010921b2160 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, 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(__cb), - std::move(__token), - std::forward(__args)...); - } - else - { - std::invoke(std::forward(__cb), - std::forward(__args)...); - } - }, - _M_stop_source.get_token(), - std::forward<_Callable>(__f), - std::forward<_Args>(__args)...} - { } + typename = enable_if_t, + 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 + 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; };