[libcxx-commits] [PATCH] D67086: Implement syncstream (p0053)
Mark de Wever via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Sep 12 12:36:36 PDT 2023
Mordante added inline comments.
================
Comment at: libcxx/include/syncstream:206
+
+ [[nodiscard]] static _LIBCPP_HIDE_FROM_ABI __wrapped_streambuf_mutex& __instance() noexcept {
+ static __wrapped_streambuf_mutex __result;
----------------
ldionne wrote:
> It *might* be possible to use a bit in the `locale` to implement a lock for all streambufs. Something like
>
> ```
> diff --git a/libcxx/include/__locale b/libcxx/include/__locale
> index ccac748c44e4..4942808ac2bc 100644
> --- a/libcxx/include/__locale
> +++ b/libcxx/include/__locale
> @@ -131,9 +131,11 @@ private:
> static locale& __global();
> bool has_facet(id&) const;
> const facet* use_facet(id&) const;
> +};
>
> - template <class _Facet> friend bool has_facet(const locale&) _NOEXCEPT;
> - template <class _Facet> friend const _Facet& use_facet(const locale&);
> +template <>
> +struct __free_bit_traits<locale> {
> + // expose the free bit in `__imp*`
> };
>
> class _LIBCPP_EXPORTED_FROM_ABI locale::facet
> diff --git a/libcxx/include/streambuf b/libcxx/include/streambuf
> index 095ac7d3ad83..b42fae608a5a 100644
> --- a/libcxx/include/streambuf
> +++ b/libcxx/include/streambuf
> @@ -296,7 +296,9 @@ protected:
> virtual int_type overflow(int_type __c = traits_type::eof());
>
> private:
> - locale __loc_;
> + static_assert(__has_free_bits<locale>);
> + __free_bit_pair<locale, 1> __loc_;
> + // Now implement a lock using that single free bit.
> char_type* __binp_;
> char_type* __ninp_;
> char_type* __einp_;
> diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp
> index 59c7ce4d43d6..ade1aa688c4d 100644
> --- a/libcxx/src/locale.cpp
> +++ b/libcxx/src/locale.cpp
> @@ -543,7 +543,7 @@ locale::__imp::make_classic()
> // only one thread can get in here and it only gets in once
> static aligned_storage<sizeof(locale)>::type buf;
> locale* c = reinterpret_cast<locale*>(&buf);
> - c->__locale_ = &make<__imp>(1u);
> + c->__get_locale() = &make<__imp>(1u);
> return *c;
> }
>
> ```
>
> Do you know what other implementations have done? Have they gone through the trouble of finding a lock inside streambufs or do they use a global map?
They use "global" maps. As discussed I think it makes more sense not to do this and mark the feature as experimental. Then investigate whether this alternative approach is worth the hassle. I still think we should finish it before LLVM 18.
================
Comment at: libcxx/include/syncstream:386
+
+ basic_string<_CharT, _Traits, _Allocator> __str_;
+ bool __emit_on_sync_{false};
----------------
ldionne wrote:
> Do we take advantage of what `std::string` provides (i.e. growth characteristics, SBO, etc..). If we do take advantage of those, then it might be worth using `std::string`, otherwise I think we might as well use a character buffer we manually manage to save on the duplication of begin/end information.
No basically the SBO is "killed" by "__str_.resize(__str_.capacity() + 1);" This could be smarter and keep the SBO. I'm not sure how useful SBO is. It only helps if all data flushed fits in the SBO area.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D67086/new/
https://reviews.llvm.org/D67086
More information about the libcxx-commits
mailing list