On Mon, 2 Nov 2020 at 19:43, Thomas Rodgers via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > > Testsed x86_64-pc-linux-gnu, committed to master. >
Hi, I can see the new tests failing on bare-metal targets using newlib (arm-eabi, aarch64-elf): 27_io/basic_syncbuf/1.cc (test for excess errors) 27_io/basic_syncbuf/basic_ops/1.cc (test for excess errors) 27_io/basic_syncbuf/requirements/types.cc (test for excess errors) 27_io/basic_syncstream/1.cc (test for excess errors) 27_io/basic_syncstream/basic_ops/1.cc (test for excess errors) 27_io/basic_syncstream/requirements/types.cc (test for excess errors) because: libstdc++-v3/include/syncstream:142: error: 'lock_guard' does not name a type Christophe > Jonathan Wakely writes: > > > On 02/11/20 08:10 -0800, Thomas Rodgers wrote: > >>From: Thomas Rodgers <trodg...@redhat.com> > >> > >>IGNORE the previous patch. > >> > >>Changes implementation to use a private __mutex type as discussed on > >>IRC. > >> > >>libstdc++/ChangeLog: > >> libstdc++-v3/doc/doxygen/user.cfg.in (INPUT): Add new header. > >> libstdc++-v3/include/Makefile.am (std_headers): Add new header. > >> libstdc++-v3/include/Makefile.in: Regenerate. > >> libstdc++-v3/include/precompiled/stdc++.h: Include new header. > >> (basic_streambuf): Befriend __detail::__streambuf_core_access. > >> libstdc++-v3/include/std/syncstream: New header. > >> libstdc++-v3/include/std/version: Add __cpp_lib_syncbuf: > >> libstdc++-v3/testsuite/27_io/basic_syncbuf/1.cc: New test. > >> libstdc++-v3/testsuite/27_io/basic_syncbuf/2.cc: Likewise. > >> libstdc++-v3/testsuite/27_io/basic_syncbuf/basic_ops/1.cc: > >> Likewise. > >> libstdc++-v3/testsuite/27_io/basic_syncbuf/requirements/types.cc: > >> Likewise. > >> libstdc++-v3/testsuite/27_io/basic_syncbuf/sync_ops/1.cc: > >> Likewise. > >> libstdc++-v3/testsuite/27_io/basic_syncstream/1.cc: Likewise. > >> libstdc++-v3/testsuite/27_io/basic_syncstream/2.cc: Likewise. > >> libstdc++-v3/testsuite/27_io/basic_syncstream/basic_ops/1.cc: > >> Likewise. > >> libstdc++-v3/testsuite/27_io/basic_syncstream/requirements/types.cc: > >> Likewise. > >>--- > >> libstdc++-v3/doc/doxygen/user.cfg.in | 1 + > >> libstdc++-v3/include/Makefile.am | 1 + > >> libstdc++-v3/include/Makefile.in | 1 + > >> libstdc++-v3/include/precompiled/stdc++.h | 2 +- > >> libstdc++-v3/include/std/syncstream | 333 ++++++++++++++++++ > >> libstdc++-v3/include/std/version | 4 + > >> .../testsuite/27_io/basic_syncbuf/1.cc | 28 ++ > >> .../testsuite/27_io/basic_syncbuf/2.cc | 28 ++ > >> .../27_io/basic_syncbuf/basic_ops/1.cc | 137 +++++++ > >> .../27_io/basic_syncbuf/requirements/types.cc | 42 +++ > >> .../27_io/basic_syncbuf/sync_ops/1.cc | 130 +++++++ > >> .../testsuite/27_io/basic_syncstream/1.cc | 28 ++ > >> .../testsuite/27_io/basic_syncstream/2.cc | 28 ++ > >> .../27_io/basic_syncstream/basic_ops/1.cc | 134 +++++++ > >> .../basic_syncstream/requirements/types.cc | 43 +++ > >> 15 files changed, 939 insertions(+), 1 deletion(-) > >> create mode 100644 libstdc++-v3/include/std/syncstream > >> create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/1.cc > >> create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/2.cc > >> create mode 100644 > >> libstdc++-v3/testsuite/27_io/basic_syncbuf/basic_ops/1.cc > >> create mode 100644 > >> libstdc++-v3/testsuite/27_io/basic_syncbuf/requirements/types.cc > >> create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/sync_ops/1.cc > >> create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncstream/1.cc > >> create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncstream/2.cc > >> create mode 100644 > >> libstdc++-v3/testsuite/27_io/basic_syncstream/basic_ops/1.cc > >> create mode 100644 > >> libstdc++-v3/testsuite/27_io/basic_syncstream/requirements/types.cc > >> > >>diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in > >>b/libstdc++-v3/doc/doxygen/user.cfg.in > >>index 9b49a15d31b..320f6dea688 100644 > >>--- a/libstdc++-v3/doc/doxygen/user.cfg.in > >>+++ b/libstdc++-v3/doc/doxygen/user.cfg.in > >>@@ -897,6 +897,7 @@ INPUT = > >>@srcdir@/doc/doxygen/doxygroups.cc \ > >> include/streambuf \ > >> include/string \ > >> include/string_view \ > >>+ include/syncstream \ > >> include/system_error \ > >> include/thread \ > >> include/tuple \ > >>diff --git a/libstdc++-v3/include/Makefile.am > >>b/libstdc++-v3/include/Makefile.am > >>index c90ac555e15..8652b921274 100644 > >>--- a/libstdc++-v3/include/Makefile.am > >>+++ b/libstdc++-v3/include/Makefile.am > >>@@ -73,6 +73,7 @@ std_headers = \ > >> ${std_srcdir}/shared_mutex \ > >> ${std_srcdir}/span \ > >> ${std_srcdir}/sstream \ > >>+ ${std_srcdir}/syncstream \ > >> ${std_srcdir}/stack \ > >> ${std_srcdir}/stdexcept \ > >> ${std_srcdir}/stop_token \ > >>diff --git a/libstdc++-v3/include/precompiled/stdc++.h > >>b/libstdc++-v3/include/precompiled/stdc++.h > >>index 7518a98c25a..8899c323a28 100644 > >>--- a/libstdc++-v3/include/precompiled/stdc++.h > >>+++ b/libstdc++-v3/include/precompiled/stdc++.h > >>@@ -141,6 +141,6 @@ > >> #include <ranges> > >> #include <span> > >> #include <stop_token> > >>-// #include <syncstream> > >>+#include <syncstream> > >> #include <version> > >> #endif > >>diff --git a/libstdc++-v3/include/std/syncstream > >>b/libstdc++-v3/include/std/syncstream > >>new file mode 100644 > >>index 00000000000..ff96ca6cf59 > >>--- /dev/null > >>+++ b/libstdc++-v3/include/std/syncstream > >>@@ -0,0 +1,333 @@ > >>+// <syncstream> -*- C++ -*- > >>+ > >>+// 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. > >>+ > >>+// 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/>. > >>+ > >>+/** @file include/syncstream > >>+ * This is a Standard C++ Library header. > >>+ */ > >>+ > >>+#ifndef _GLIBCXX_SYNCSTREAM > >>+#define _GLIBCXX_SYNCSTREAM 1 > >>+ > >>+#if __cplusplus > 201703L > >>+ > >>+#include <bits/c++config.h> > >>+#if _GLIBCXX_USE_CXX11_ABI > >>+ > >>+#define __cpp_lib_syncbuf 201803L > >>+ > >>+#pragma GCC system_header > >>+ > >>+#include <sstream> > >>+ > >>+#include <bits/alloc_traits.h> > >>+#include <bits/allocator.h> > >>+#include <bits/functexcept.h> > >>+#include <bits/functional_hash.h> > >>+ > >>+#if _GLIBCXX_HAS_GTHREADS > >>+# include <bits/std_mutex.h> > >>+#endif > >>+ > >>+namespace std _GLIBCXX_VISIBILITY(default) > >>+{ > >>+_GLIBCXX_BEGIN_NAMESPACE_VERSION > >>+ > >>+ template<typename _CharT, typename _Traits = char_traits<_CharT>, > >>+ typename _Alloc = allocator<_CharT>> > >>+ class basic_syncbuf : public basic_streambuf<_CharT, _Traits> > >>+ { > >>+ public: > >>+ using char_type = _CharT; > >>+ using int_type = typename _Traits::int_type; > >>+ using pos_type = typename _Traits::pos_type; > >>+ using off_type = typename _Traits::off_type; > >>+ using traits_type = _Traits; > >>+ using allocator_type = _Alloc; > >>+ using streambuf_type = basic_streambuf<_CharT, _Traits>; > >>+ > >>+ basic_syncbuf() > >>+ : basic_syncbuf(nullptr, allocator_type{}) > >>+ { } > >>+ > >>+ explicit > >>+ basic_syncbuf(streambuf_type* __obuf) > >>+ : basic_syncbuf(__obuf, allocator_type{}) > >>+ { } > >>+ > >>+ basic_syncbuf(streambuf_type* __obuf, const allocator_type& __alloc) > >>+ : _M_wrapped(__obuf) > >>+ , _M_impl(__alloc) > >>+ , _M_mtx(__obuf) > >>+ { } > >>+ > >>+ basic_syncbuf(basic_syncbuf&& __other) > >>+ : _M_wrapped(__other._M_wrapped) > >>+ , _M_impl(std::move(__other._M_impl)) > >>+ , _M_mtx(std::move(__other._M_mtx)) > >>+ , _M_emit_on_sync(__other._M_emit_on_sync) > >>+ , _M_needs_sync(__other._M_needs_sync) > >>+ { > >>+ __other._M_wrapped = nullptr; > >>+ } > >>+ > >>+ ~basic_syncbuf() > >>+ { > >>+ __try > >>+ { > >>+ emit(); > >>+ } > >>+ __catch (...) > >>+ { } > >>+ } > >>+ > >>+ basic_syncbuf& operator=(basic_syncbuf&& __other) > >>+ { > >>+ if (std::__addressof(__other) != this) > >>+ { > >>+ emit(); > >>+ > >>+ _M_impl = std::move(__other._M_impl); > >>+ _M_wrapped = __other._M_wrapped; __other._M_wrapped = nullptr; > >>+ _M_mtx = std::move(__other._M_mtx); > >>+ _M_emit_on_sync = __other._M_emit_on_sync; > >>+ _M_needs_sync = __other._M_needs_sync; > >>+ } > >>+ return *this; > >>+ } > >>+ > >>+ void > >>+ swap(basic_syncbuf& __other) > >>+ { > >>+ if (std::__addressof(__other) != this) > >>+ { > >>+ std::swap(_M_impl, __other._M_impl); > >>+ std::swap(_M_wrapped, __other._M_wrapped); > >>+ std::swap(_M_mtx, __other._M_mtx); > >>+ std::swap(_M_emit_on_sync, __other._M_emit_on_sync); > >>+ std::swap(_M_needs_sync, __other._M_needs_sync); > >>+ } > >>+ } > >>+ > >>+ bool > >>+ emit() > >>+ { > >>+ if (!_M_wrapped) > >>+ return false; > >>+ > >>+ auto __s = _M_impl.view(); > >>+ if (__s.empty()) > >>+ return true; > >>+ > >>+ const lock_guard<__mutex> __l(_M_mtx); > >>+ if (_M_wrapped->sputn(__s.data(), __s.size()) != __s.size()) > >>+ return false; > >>+ > >>+ if (_M_needs_sync) > >>+ { > >>+ _M_needs_sync = false; > >>+ if (_M_wrapped->pubsync() != 0) > >>+ return false; > >>+ } > >>+ > >>+ _M_impl.str(""); > >>+ return true; > >>+ } > >>+ > >>+ streambuf_type* > >>+ get_wrapped() const noexcept > >>+ { return _M_wrapped; } > >>+ > >>+ allocator_type get_allocator() const noexcept > >>+ { return _M_impl.get_allocator(); } > >>+ > >>+ void > >>+ set_emit_on_sync(bool __b) noexcept > >>+ { _M_emit_on_sync = __b; } > >>+ > >>+ protected: > >>+ int > >>+ sync() override > >>+ { > >>+ auto __res = _M_impl.pubsync(); > >>+ if (__res == 0) > >>+ { > >>+ _M_needs_sync = true; > >>+ if (_M_emit_on_sync) > >>+ return emit() ? 0 : -1; > >>+ } > >>+ return __res; > >>+ } > >>+ > >>+ streamsize > >>+ xsputn(const char_type* __s, streamsize __n) override > >>+ { return _M_impl.sputn(__s, __n); } > >>+ > >>+ private: > >>+ streambuf_type* _M_wrapped; > >>+ > >>+ using __impl_type = basic_stringbuf<char_type, traits_type, > >>+ allocator_type>; > >>+ __impl_type _M_impl; > >>+ > >>+ struct __mutex > >>+ { > >>+#if _GLIBCXX_HAS_GTHREADS > >>+ mutex* _M_mtx; > >>+ > >>+ __mutex(void* __t) > > > > Make this 'explicit' please. > > > >>+ : _M_mtx(__t ? &_S_get_mutex(__t) : nullptr) > >>+ { } > >>+ > >>+ void > >>+ swap(__mutex& __other) noexcept > >>+ { std::swap(_M_mtx, __other._M_mtx); } > >>+ > >>+ void > >>+ lock() > >>+ { > >>+ if (_M_mtx) > >>+ _M_mtx->lock(); > >>+ } > >>+ > >>+ void > >>+ unlock() > >>+ { > >>+ if (_M_mtx) > >>+ _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*) > > > > And 'explicit' here too. > > > >>+ { } > >>+ > >>+ void > >>+ swap(__mutex&&) noexcept > > > > This needs to be an lvalue reference, or it won't compile. > > > >>+ { } > >>+ > >>+ void > >>+ lock() > >>+ { } > >>+ > >>+ void > >>+ unlock() > >>+ { } > > > > All these completely empty functions can be put on one line: > > > > void unlock() { } > > > > There's no need for these no-op members take up so many lines. > > > >>+#endif > >>+ __mutex(const __mutex&) = delete; > >>+ __mutex& operator=(const __mutex&) = delete; > > > > These are redundant (the user-declared moves below cause the copies to > > be deleted) but harmless. > > > >>+ > >>+ __mutex(__mutex&&) = default; > >>+ __mutex& operator=(__mutex&&) = default; > >>+ }; > >>+ __mutex _M_mtx; > >>+ > >>+ bool _M_emit_on_sync = false; > >>+ bool _M_needs_sync = false; > >>+ }; > > > > > > OK for trunk, thanks. >