diff --git a/libstdc++-v3/config/os/gnu-linux/os_defines.h b/libstdc++-v3/config/os/gnu-linux/os_defines.h
index f821486ec8f5a7cf37ceae3edbe7d239fcf51a02..01bfa9ddd4f28419f41e6106249e3cecb8fe76a6 100644
--- a/libstdc++-v3/config/os/gnu-linux/os_defines.h
+++ b/libstdc++-v3/config/os/gnu-linux/os_defines.h
@@ -49,4 +49,16 @@
 // 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
diff --git a/libstdc++-v3/include/bits/std_thread.h b/libstdc++-v3/include/bits/std_thread.h
index 96c8d1bb19ff0b93e29a19c20d611a4cf191b027..24bd5fbd44e8e8f1c6970a88c1242d21398c8694 100644
--- a/libstdc++-v3/include/bits/std_thread.h
+++ b/libstdc++-v3/include/bits/std_thread.h
@@ -294,26 +294,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     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
     }
 
diff --git a/libstdc++-v3/testsuite/30_threads/jthread/95989.cc b/libstdc++-v3/testsuite/30_threads/jthread/95989.cc
new file mode 100644
index 0000000000000000000000000000000000000000..46444b5ccabcaffd468431084c8786743cb601b8
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/jthread/95989.cc
@@ -0,0 +1,54 @@
+// 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();
+}
diff --git a/libstdc++-v3/testsuite/30_threads/this_thread/95989.cc b/libstdc++-v3/testsuite/30_threads/this_thread/95989.cc
new file mode 100644
index 0000000000000000000000000000000000000000..16535af8b7432944726ea8420d77a5d7f443993a
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/this_thread/95989.cc
@@ -0,0 +1,51 @@
+// 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();
+}