https://gcc.gnu.org/g:4eb12ddd32d53ef55c2bd9bb03db057f096fff8f

commit r16-3668-g4eb12ddd32d53ef55c2bd9bb03db057f096fff8f
Author: Nathan Myers <n...@cantrip.org>
Date:   Thu Aug 28 13:11:57 2025 -0400

    libstdc++: Make syncbuf _S_get_mutex definition extern.
    
    This patch creates a global function __syncbuf_get_mutex, gated by
    _GLIBCXX_HAS_GTHREADS, replacing a static instantiated member
    _S_get_mutex used in syncbuf<> construction, and makes the global
    symbol visible. A static local table of 16 mutexes is shared among
    all specializations of syncbuf<>, chosen on construction by a hash
    of the wrapped streambuf's address.
    
    It detaches the implementation of _S_get_mutex from the C++20 ABI.
    
    libstdc++-v3/ChangeLog:
            * include/std/syncstream: (syncbuf<>::__mutex) Remove _S_get_mutex,
            use extern function instead.
            * src/c++20/syncbuf.cc: Define global __syncbuf_get_mutex.
            * src/c++20/Makefile.am: Mention syncbuf.cc.
            * src/c++20/Makefile.in: Regenerate.
            * config/abi/pre/gnu.ver: Mention mangled __syncbuf_get_mutex.

Diff:
---
 libstdc++-v3/config/abi/pre/gnu.ver |  3 +++
 libstdc++-v3/include/std/syncstream | 22 +++++-------------
 libstdc++-v3/src/c++20/Makefile.am  |  2 +-
 libstdc++-v3/src/c++20/Makefile.in  |  2 +-
 libstdc++-v3/src/c++20/syncbuf.cc   | 45 +++++++++++++++++++++++++++++++++++++
 5 files changed, 56 insertions(+), 18 deletions(-)

diff --git a/libstdc++-v3/config/abi/pre/gnu.ver 
b/libstdc++-v3/config/abi/pre/gnu.ver
index e1601dc39d25..2e48241d51f9 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -2559,6 +2559,9 @@ GLIBCXX_3.4.35 {
     _ZNSt6chrono9gps_clock3nowEv;
     _ZNSt6chrono9tai_clock3nowEv;
 
+    # mutex& __syncbuf_get_mutex(void*)
+    _ZSt19__syncbuf_get_mutexPv;
+
     # __gnu_debug::_Safe_iterator_base and _Safe_sequence_base const
     
_ZN11__gnu_debug19_Safe_iterator_base9_M_attachEPKNS_19_Safe_sequence_baseEb;
     
_ZN11__gnu_debug19_Safe_iterator_base16_M_attach_singleEPKNS_19_Safe_sequence_baseEb;
diff --git a/libstdc++-v3/include/std/syncstream 
b/libstdc++-v3/include/std/syncstream
index e2b5a199ec93..92fbbdc760e7 100644
--- a/libstdc++-v3/include/std/syncstream
+++ b/libstdc++-v3/include/std/syncstream
@@ -46,7 +46,6 @@
 #include <bits/alloc_traits.h>
 #include <bits/allocator.h>
 #include <bits/functexcept.h>
-#include <bits/functional_hash.h>
 #include <bits/std_mutex.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -199,11 +198,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       struct __mutex
       {
 #if _GLIBCXX_HAS_GTHREADS
-       mutex* _M_mtx;
+       mutex* _M_mtx = nullptr;
 
-       __mutex(void* __t)
-         : _M_mtx(__t ? &_S_get_mutex(__t) : nullptr)
-       { }
+       __mutex(void* __t)  // __t is the underlying sbuf, as hash seed.
+       { 
+         extern mutex& __syncbuf_get_mutex(void*);  // in src/c++20/syncbuf.cc
+         if (__t) _M_mtx = &__syncbuf_get_mutex(__t);
+       }
 
        void
        swap(__mutex& __other) noexcept
@@ -220,17 +221,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        {
          _M_mtx->unlock();
        }
-
-       // FIXME: This should be put in the .so
-       static mutex&
-       _S_get_mutex(void* __t)
-       {
-         const unsigned char __mask = 0xf;
-         static mutex __m[__mask + 1];
-
-         auto __key = _Hash_impl::hash(__t) & __mask;
-         return __m[__key];
-       }
 #else
        __mutex(void*) { }
        void swap(__mutex&&) noexcept { }
diff --git a/libstdc++-v3/src/c++20/Makefile.am 
b/libstdc++-v3/src/c++20/Makefile.am
index 736558ff24a7..384990aed776 100644
--- a/libstdc++-v3/src/c++20/Makefile.am
+++ b/libstdc++-v3/src/c++20/Makefile.am
@@ -36,7 +36,7 @@ else
 inst_sources =
 endif
 
-sources = tzdb.cc format.cc atomic.cc clock.cc
+sources = tzdb.cc format.cc atomic.cc clock.cc syncbuf.cc
 
 vpath % $(top_srcdir)/src/c++20
 
diff --git a/libstdc++-v3/src/c++20/Makefile.in 
b/libstdc++-v3/src/c++20/Makefile.in
index 3cb6d6fea5f3..1e005ae3c14e 100644
--- a/libstdc++-v3/src/c++20/Makefile.in
+++ b/libstdc++-v3/src/c++20/Makefile.in
@@ -432,7 +432,7 @@ headers =
 @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \
 @ENABLE_EXTERN_TEMPLATE_TRUE@  sstream-inst.cc
 
-sources = tzdb.cc format.cc atomic.cc clock.cc
+sources = tzdb.cc format.cc atomic.cc clock.cc syncbuf.cc
 @GLIBCXX_HOSTED_FALSE@libc__20convenience_la_SOURCES = 
 @GLIBCXX_HOSTED_TRUE@libc__20convenience_la_SOURCES = $(sources)  
$(inst_sources)
 
diff --git a/libstdc++-v3/src/c++20/syncbuf.cc 
b/libstdc++-v3/src/c++20/syncbuf.cc
new file mode 100644
index 000000000000..150ba5e3ce4d
--- /dev/null
+++ b/libstdc++-v3/src/c++20/syncbuf.cc
@@ -0,0 +1,45 @@
+// Explicit instantiation file.
+
+// Copyright (C) 2020-2025 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+#include <syncstream>
+#include <bits/functional_hash.h>
+
+#if _GLIBCXX_HAS_GTHREADS
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+mutex&
+__syncbuf_get_mutex(void* __t)
+  {
+    const unsigned char __mask = 0xf;
+    static mutex __m[__mask + 1];
+
+    auto __key = _Hash_impl::hash(__t) & __mask;
+    return __m[__key];
+  }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+}
+#endif // GTHREADS

Reply via email to