On Fri, 29 Aug 2025 at 14:31, Tomasz Kaminski <tkami...@redhat.com> wrote: > > > > On Fri, Aug 29, 2025 at 2:06 AM Nathan Myers <n...@cantrip.org> wrote: >> >> Changes in v2: >> * Make a global function __syncbuf_get_mutex, not an extern template >> instantiation. >> >> 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. > > Wouldn't it be more extensible, if we always would define _S_get_mutex
Do you mean when ! HAS_GTHREADS? Is that useful? >> >> >> 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. >> --- >> libstdc++-v3/config/abi/pre/gnu.ver | 3 ++ >> libstdc++-v3/include/std/syncstream | 19 ++++-------- >> 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(+), 15 deletions(-) >> create mode 100644 libstdc++-v3/src/c++20/syncbuf.cc >> >> diff --git a/libstdc++-v3/config/abi/pre/gnu.ver >> b/libstdc++-v3/config/abi/pre/gnu.ver >> index e1601dc39d2..2e48241d51f 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 e2b5a199ec9..649756b2581 100644 >> --- a/libstdc++-v3/include/std/syncstream >> +++ b/libstdc++-v3/include/std/syncstream >> @@ -46,13 +46,17 @@ >> #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) >> { >> _GLIBCXX_BEGIN_NAMESPACE_VERSION >> >> +#if _GLIBCXX_HAS_GTHREADS >> + extern mutex& >> + __syncbuf_get_mutex(void*); // in src/c++20/syncbuf.cc >> +#endif >> + >> template<typename _CharT, typename _Traits, typename _Alloc> >> class basic_syncbuf : public __syncbuf_base<_CharT, _Traits> >> { >> @@ -202,7 +206,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >> mutex* _M_mtx; >> >> __mutex(void* __t) >> - : _M_mtx(__t ? &_S_get_mutex(__t) : nullptr) >> + : _M_mtx(__t ? &__syncbuf_get_mutex(__t) : nullptr) >> { } > > You could put the declaration of the __syncbuf_get_mutex function inside the > constructor, > to avoid having a separate _GLIBCXX_HAS_GTHREADS block. > __mutex(void* __t) > : _M_mtx(nullptr) > { > extern mutex& __syncbuf_get_mutex(void*); // in > src/c++20/syncbuf.cc > if (__t) > _M_mtx = &_S_get_mutex(__t); > } > But let's see what other think. Yes, we do that in a few other places, so that there's no user-accessible declaration of the function.