From 438765744bb511f97d34727f5404eca6e0320ba4 Mon Sep 17 00:00:00 2001 From: Nikolas Klauser Date: Tue, 12 Nov 2024 22:41:15 +0100 Subject: [PATCH] [libc++] Split __shared_count out of <__memory/shared_ptr.h> --- libcxx/include/CMakeLists.txt | 1 + libcxx/include/__locale | 2 +- libcxx/include/__memory/shared_count.h | 136 +++++++++++++++++++++++++ libcxx/include/__memory/shared_ptr.h | 114 +-------------------- libcxx/include/__mutex/once_flag.h | 2 +- libcxx/include/future | 2 +- libcxx/include/module.modulemap | 1 + libcxx/include/mutex | 1 - 8 files changed, 142 insertions(+), 117 deletions(-) create mode 100644 libcxx/include/__memory/shared_count.h diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index dd774b25a81eda..1610d1ee848a5f 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -557,6 +557,7 @@ set(files __memory/ranges_construct_at.h __memory/ranges_uninitialized_algorithms.h __memory/raw_storage_iterator.h + __memory/shared_count.h __memory/shared_ptr.h __memory/swap_allocator.h __memory/temp_value.h diff --git a/libcxx/include/__locale b/libcxx/include/__locale index b07b9f3329f42c..b675e01bac81e5 100644 --- a/libcxx/include/__locale +++ b/libcxx/include/__locale @@ -12,7 +12,7 @@ #include <__config> #include <__locale_dir/locale_base_api.h> -#include <__memory/shared_ptr.h> // __shared_count +#include <__memory/shared_count.h> #include <__mutex/once_flag.h> #include <__type_traits/make_unsigned.h> #include <__utility/no_destroy.h> diff --git a/libcxx/include/__memory/shared_count.h b/libcxx/include/__memory/shared_count.h new file mode 100644 index 00000000000000..1438c6ba5a6d29 --- /dev/null +++ b/libcxx/include/__memory/shared_count.h @@ -0,0 +1,136 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___MEMORY_SHARED_COUNT_H +#define _LIBCPP___MEMORY_SHARED_COUNT_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively) +// should be sufficient for thread safety. +// See https://llvm.org/PR22803 +#if (defined(__clang__) && __has_builtin(__atomic_add_fetch) && defined(__ATOMIC_RELAXED) && \ + defined(__ATOMIC_ACQ_REL)) || \ + defined(_LIBCPP_COMPILER_GCC) +# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT 1 +#else +# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT 0 +#endif + +template +inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_relaxed_load(_ValueType const* __value) { +#if _LIBCPP_HAS_THREADS && defined(__ATOMIC_RELAXED) && \ + (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC)) + return __atomic_load_n(__value, __ATOMIC_RELAXED); +#else + return *__value; +#endif +} + +template +inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_acquire_load(_ValueType const* __value) { +#if _LIBCPP_HAS_THREADS && defined(__ATOMIC_ACQUIRE) && \ + (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC)) + return __atomic_load_n(__value, __ATOMIC_ACQUIRE); +#else + return *__value; +#endif +} + +template +inline _LIBCPP_HIDE_FROM_ABI _Tp __libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT { +#if _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT && _LIBCPP_HAS_THREADS + return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED); +#else + return __t += 1; +#endif +} + +template +inline _LIBCPP_HIDE_FROM_ABI _Tp __libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT { +#if _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT && _LIBCPP_HAS_THREADS + return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL); +#else + return __t -= 1; +#endif +} + +class _LIBCPP_EXPORTED_FROM_ABI __shared_count { + __shared_count(const __shared_count&); + __shared_count& operator=(const __shared_count&); + +protected: + long __shared_owners_; + virtual ~__shared_count(); + +private: + virtual void __on_zero_shared() _NOEXCEPT = 0; + +public: + _LIBCPP_HIDE_FROM_ABI explicit __shared_count(long __refs = 0) _NOEXCEPT : __shared_owners_(__refs) {} + +#if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS) + void __add_shared() noexcept; + bool __release_shared() noexcept; +#else + _LIBCPP_HIDE_FROM_ABI void __add_shared() _NOEXCEPT { __libcpp_atomic_refcount_increment(__shared_owners_); } + _LIBCPP_HIDE_FROM_ABI bool __release_shared() _NOEXCEPT { + if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) { + __on_zero_shared(); + return true; + } + return false; + } +#endif + _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __libcpp_relaxed_load(&__shared_owners_) + 1; } +}; + +class _LIBCPP_EXPORTED_FROM_ABI __shared_weak_count : private __shared_count { + long __shared_weak_owners_; + +public: + _LIBCPP_HIDE_FROM_ABI explicit __shared_weak_count(long __refs = 0) _NOEXCEPT + : __shared_count(__refs), + __shared_weak_owners_(__refs) {} + +protected: + ~__shared_weak_count() override; + +public: +#if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS) + void __add_shared() noexcept; + void __add_weak() noexcept; + void __release_shared() noexcept; +#else + _LIBCPP_HIDE_FROM_ABI void __add_shared() _NOEXCEPT { __shared_count::__add_shared(); } + _LIBCPP_HIDE_FROM_ABI void __add_weak() _NOEXCEPT { __libcpp_atomic_refcount_increment(__shared_weak_owners_); } + _LIBCPP_HIDE_FROM_ABI void __release_shared() _NOEXCEPT { + if (__shared_count::__release_shared()) + __release_weak(); + } +#endif + void __release_weak() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __shared_count::use_count(); } + __shared_weak_count* lock() _NOEXCEPT; + + virtual const void* __get_deleter(const type_info&) const _NOEXCEPT; + +private: + virtual void __on_zero_shared_weak() _NOEXCEPT = 0; +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___MEMORY_SHARED_COUNT_H diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h index 5a84c2ce9bfe17..5c34f2efc5730e 100644 --- a/libcxx/include/__memory/shared_ptr.h +++ b/libcxx/include/__memory/shared_ptr.h @@ -30,6 +30,7 @@ #include <__memory/compressed_pair.h> #include <__memory/construct_at.h> #include <__memory/pointer_traits.h> +#include <__memory/shared_count.h> #include <__memory/uninitialized_algorithms.h> #include <__memory/unique_ptr.h> #include <__type_traits/add_lvalue_reference.h> @@ -70,55 +71,6 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively) -// should be sufficient for thread safety. -// See https://llvm.org/PR22803 -#if (defined(__clang__) && __has_builtin(__atomic_add_fetch) && defined(__ATOMIC_RELAXED) && \ - defined(__ATOMIC_ACQ_REL)) || \ - defined(_LIBCPP_COMPILER_GCC) -# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT 1 -#else -# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT 0 -#endif - -template -inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_relaxed_load(_ValueType const* __value) { -#if _LIBCPP_HAS_THREADS && defined(__ATOMIC_RELAXED) && \ - (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC)) - return __atomic_load_n(__value, __ATOMIC_RELAXED); -#else - return *__value; -#endif -} - -template -inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_acquire_load(_ValueType const* __value) { -#if _LIBCPP_HAS_THREADS && defined(__ATOMIC_ACQUIRE) && \ - (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC)) - return __atomic_load_n(__value, __ATOMIC_ACQUIRE); -#else - return *__value; -#endif -} - -template -inline _LIBCPP_HIDE_FROM_ABI _Tp __libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT { -#if _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT && _LIBCPP_HAS_THREADS - return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED); -#else - return __t += 1; -#endif -} - -template -inline _LIBCPP_HIDE_FROM_ABI _Tp __libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT { -#if _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT && _LIBCPP_HAS_THREADS - return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL); -#else - return __t -= 1; -#endif -} - class _LIBCPP_EXPORTED_FROM_ABI bad_weak_ptr : public std::exception { public: _LIBCPP_HIDE_FROM_ABI bad_weak_ptr() _NOEXCEPT = default; @@ -139,70 +91,6 @@ class _LIBCPP_EXPORTED_FROM_ABI bad_weak_ptr : public std::exception { template class _LIBCPP_TEMPLATE_VIS weak_ptr; -class _LIBCPP_EXPORTED_FROM_ABI __shared_count { - __shared_count(const __shared_count&); - __shared_count& operator=(const __shared_count&); - -protected: - long __shared_owners_; - virtual ~__shared_count(); - -private: - virtual void __on_zero_shared() _NOEXCEPT = 0; - -public: - _LIBCPP_HIDE_FROM_ABI explicit __shared_count(long __refs = 0) _NOEXCEPT : __shared_owners_(__refs) {} - -#if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS) - void __add_shared() noexcept; - bool __release_shared() noexcept; -#else - _LIBCPP_HIDE_FROM_ABI void __add_shared() _NOEXCEPT { __libcpp_atomic_refcount_increment(__shared_owners_); } - _LIBCPP_HIDE_FROM_ABI bool __release_shared() _NOEXCEPT { - if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) { - __on_zero_shared(); - return true; - } - return false; - } -#endif - _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __libcpp_relaxed_load(&__shared_owners_) + 1; } -}; - -class _LIBCPP_EXPORTED_FROM_ABI __shared_weak_count : private __shared_count { - long __shared_weak_owners_; - -public: - _LIBCPP_HIDE_FROM_ABI explicit __shared_weak_count(long __refs = 0) _NOEXCEPT - : __shared_count(__refs), - __shared_weak_owners_(__refs) {} - -protected: - ~__shared_weak_count() override; - -public: -#if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS) - void __add_shared() noexcept; - void __add_weak() noexcept; - void __release_shared() noexcept; -#else - _LIBCPP_HIDE_FROM_ABI void __add_shared() _NOEXCEPT { __shared_count::__add_shared(); } - _LIBCPP_HIDE_FROM_ABI void __add_weak() _NOEXCEPT { __libcpp_atomic_refcount_increment(__shared_weak_owners_); } - _LIBCPP_HIDE_FROM_ABI void __release_shared() _NOEXCEPT { - if (__shared_count::__release_shared()) - __release_weak(); - } -#endif - void __release_weak() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __shared_count::use_count(); } - __shared_weak_count* lock() _NOEXCEPT; - - virtual const void* __get_deleter(const type_info&) const _NOEXCEPT; - -private: - virtual void __on_zero_shared_weak() _NOEXCEPT = 0; -}; - template class __shared_ptr_pointer : public __shared_weak_count { _LIBCPP_COMPRESSED_TRIPLE(_Tp, __ptr_, _Dp, __deleter_, _Alloc, __alloc_); diff --git a/libcxx/include/__mutex/once_flag.h b/libcxx/include/__mutex/once_flag.h index 9d7baecbc70859..08ff54bf99265e 100644 --- a/libcxx/include/__mutex/once_flag.h +++ b/libcxx/include/__mutex/once_flag.h @@ -11,7 +11,7 @@ #include <__config> #include <__functional/invoke.h> -#include <__memory/shared_ptr.h> // __libcpp_acquire_load +#include <__memory/shared_count.h> // __libcpp_acquire_load #include <__tuple/tuple_indices.h> #include <__tuple/tuple_size.h> #include <__utility/forward.h> diff --git a/libcxx/include/future b/libcxx/include/future index 67d9b43ff22e32..9f7c95e542fd60 100644 --- a/libcxx/include/future +++ b/libcxx/include/future @@ -378,7 +378,7 @@ template struct uses_allocator, Alloc>; # include <__memory/allocator_traits.h> # include <__memory/compressed_pair.h> # include <__memory/pointer_traits.h> -# include <__memory/shared_ptr.h> +# include <__memory/shared_count.h> # include <__memory/unique_ptr.h> # include <__memory/uses_allocator.h> # include <__system_error/error_category.h> diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap index 9027c28632dcda..cd08b2810e437b 100644 --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -1542,6 +1542,7 @@ module std [system] { export std.algorithm.in_out_result } module raw_storage_iterator { header "__memory/raw_storage_iterator.h" } + module shared_count { header "__memory/shared_count.h" } module shared_ptr { header "__memory/shared_ptr.h" } module swap_allocator { header "__memory/swap_allocator.h" } module temp_value { header "__memory/temp_value.h" } diff --git a/libcxx/include/mutex b/libcxx/include/mutex index 60a7c9945909ce..ecbfc5607dcc78 100644 --- a/libcxx/include/mutex +++ b/libcxx/include/mutex @@ -190,7 +190,6 @@ template #include <__chrono/time_point.h> #include <__condition_variable/condition_variable.h> #include <__config> -#include <__memory/shared_ptr.h> #include <__mutex/lock_guard.h> #include <__mutex/mutex.h> #include <__mutex/once_flag.h>