// version dynamically in case it has changed since libstdc++ was configured.
#define _GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC __GLIBC_PREREQ(2,23)
+#if __GLIBC_PREREQ(2, 27)
+// Since glibc 2.27 pthread_self() is usable without linking to libpthread.
+# define _GLIBCXX_NATIVE_THREAD_ID pthread_self()
+#else
+// Before then it was in libc.so.6 but not libc.a, and always returns 0,
+// which breaks the invariant this_thread::get_id() != thread::id{}.
+// So only use it if we know the libpthread version is available.
+// Otherwise use (__gthread_t)1 as the ID of the main (and only) thread.
+# define _GLIBCXX_NATIVE_THREAD_ID \
+ (__gthread_active_p() ? __gthread_self() : (__gthread_t)1)
+#endif
+
#endif
inline thread::id
get_id() noexcept
{
-#ifdef _GLIBCXX_HAS_GTHREADS
-
-#ifdef __GLIBC__
- // For the GNU C library pthread_self() is usable without linking to
- // libpthread, but prior to version 2.27 the version in libc returns 0,
- // which breaks the invariant this_thread::get_id() != thread::id{}.
- //
- // We know that pthread_t is a scalar type in the GNU C library,
- // so just use (__gthread_t)1 as the ID of the main (and only) thread.
- //
- // This uses __gthread_active_p not __gnu_cxx::__is_single_threaded
- // because we don't want the thread::id of the main thread to change
- // if additional threads are created later.
- if (!__gthread_active_p())
- return thread::id((__gthread_t)1);
-#endif
-
- return thread::id(__gthread_self());
-#else
+#ifndef _GLIBCXX_HAS_GTHREADS
return thread::id(1);
+#elif defined _GLIBCXX_NATIVE_THREAD_ID
+ return thread::id(_GLIBCXX_NATIVE_THREAD_ID);
+#else
+ return thread::id(__gthread_self());
#endif
}
--- /dev/null
+// 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/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-require-gthreads {} }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-additional-options "-static" { target static } }
+
+#include <thread>
+
+// PR libstdc++/95989
+// Segfault compiling with static libraries and using jthread::request_stop
+
+void
+test01()
+{
+ std::jthread t{ [] () {} };
+}
+
+void
+test02()
+{
+ std::jthread t{ [] () {} };
+ t.request_stop();
+}
+
+void
+test03()
+{
+ std::jthread t{ [] {} };
+ std::stop_callback cb(t.get_stop_token(), [] () {});
+}
+
+int
+main()
+{
+ test01();
+ test01();
+}
--- /dev/null
+// 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/>.
+
+// { dg-do run { target c++11 } }
+// { dg-require-gthreads {} }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-additional-options "-static" { target static } }
+
+#include <thread>
+#include <testsuite_hooks.h>
+
+__attribute__((noinline,noipa))
+void
+join(std::thread& t)
+{
+ if (!t.joinable())
+ return;
+
+ // Using thread::join() creates a dependency on libpthread symbols
+ // so that __gthread_active_p is true, and we use pthread_self.
+ t.join();
+}
+
+void
+test01()
+{
+ std::thread t;
+ // PR libstdc++/95989
+ auto id = std::this_thread::get_id();
+ VERIFY (t.get_id() != id );
+}
+
+int
+main()
+{
+ test01();
+}