[gcc(refs/users/aoliva/heads/testme)] link pthread_join from std::thread ctor
Alexandre Oliva
aoliva@gcc.gnu.org
Fri Mar 3 12:39:40 GMT 2023
https://gcc.gnu.org/g:4d6372bccaf7bb429ede0ece301001e724272eb0
commit 4d6372bccaf7bb429ede0ece301001e724272eb0
Author: Alexandre Oliva <oliva@adacore.com>
Date: Fri Mar 3 02:14:53 2023 -0300
link pthread_join from std::thread ctor
Like pthread_create, pthread_join may fail to be statically linked in
absent strong uses, so add to user code strong references to both when
std::thread objects are created.
for libstdc++-v3/ChangeLog
* include/bits/std_thread.h (std::thread ctor): Add strong
reference to pthread_join.
Diff:
---
libstdc++-v3/include/bits/std_thread.h | 35 +++++++++++++++++++++++++++-------
1 file changed, 28 insertions(+), 7 deletions(-)
diff --git a/libstdc++-v3/include/bits/std_thread.h b/libstdc++-v3/include/bits/std_thread.h
index adbd3928ff7..94aef1ae6d9 100644
--- a/libstdc++-v3/include/bits/std_thread.h
+++ b/libstdc++-v3/include/bits/std_thread.h
@@ -132,6 +132,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
thread() noexcept = default;
#ifdef _GLIBCXX_HAS_GTHREADS
+ private:
+ // This adds to user code that creates std:thread objects (because
+ // it is called by the template ctor below) strong references to
+ // pthread_create and pthread_join, which ensures they are both
+ // linked in even during static linking. We can't depend on
+ // gthread calls to bring them in, because those may use weak
+ // references.
+ static inline __attribute__ ((__always_inline__)) void
+ _M_thread_deps() {
+#ifdef GTHR_ACTIVE_PROXY
+#if 1
+ static auto const __attribute__ ((__used__)) _M_create = pthread_create;
+ static auto const __attribute__ ((__used__)) _M_join = pthread_join;
+#else
+ bool _M_skip_always = false;
+ asm ("" : "+X" (_M_skip_always));
+ if (__builtin_expect (_M_skip_always, false))
+ {
+ pthread_create (nullptr, nullptr, nullptr, nullptr);
+ pthread_join (nullptr, nullptr);
+ }
+#endif
+ }
+
+ public:
template<typename _Callable, typename... _Args,
typename = _Require<__not_same<_Callable>>>
explicit
@@ -142,18 +167,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
"std::thread arguments must be invocable after conversion to rvalues"
);
-#ifdef GTHR_ACTIVE_PROXY
- // Create a reference to pthread_create, not just the gthr weak symbol.
- auto __depend = reinterpret_cast<void(*)()>(&pthread_create);
-#else
- auto __depend = nullptr;
-#endif
+ _M_thread_deps ();
+
using _Wrapper = _Call_wrapper<_Callable, _Args...>;
// Create a call wrapper with DECAY_COPY(__f) as its target object
// and DECAY_COPY(__args)... as its bound argument entities.
_M_start_thread(_State_ptr(new _State_impl<_Wrapper>(
std::forward<_Callable>(__f), std::forward<_Args>(__args)...)),
- __depend);
+ nullptr);
}
#endif // _GLIBCXX_HAS_GTHREADS
More information about the Libstdc++-cvs
mailing list