On Fri, Aug 29, 2025 at 2:06 AM Nathan Myers <[email protected]> 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

>
> 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.

>
>         void
> @@ -220,17 +224,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 736558ff24a..384990aed77 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 3cb6d6fea5f..1e005ae3c14 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 00000000000..150ba5e3ce4
> --- /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
> --
> 2.50.1
>
>

Reply via email to