Skip to content

Commit 67b81e2

Browse files
authored
[libc++] Split __shared_count out of <__memory/shared_ptr.h> (#115943)
`__shared_count` is used in a few places where `shared_ptr` isn't. This avoids a bunch of transitive includes needed for the implementation of `shared_ptr` in these places.
1 parent b69ddbc commit 67b81e2

File tree

8 files changed

+142
-117
lines changed

8 files changed

+142
-117
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ set(files
557557
__memory/ranges_construct_at.h
558558
__memory/ranges_uninitialized_algorithms.h
559559
__memory/raw_storage_iterator.h
560+
__memory/shared_count.h
560561
__memory/shared_ptr.h
561562
__memory/swap_allocator.h
562563
__memory/temp_value.h

libcxx/include/__locale

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
#include <__config>
1414
#include <__locale_dir/locale_base_api.h>
15-
#include <__memory/shared_ptr.h> // __shared_count
15+
#include <__memory/shared_count.h>
1616
#include <__mutex/once_flag.h>
1717
#include <__type_traits/make_unsigned.h>
1818
#include <__utility/no_destroy.h>
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef _LIBCPP___MEMORY_SHARED_COUNT_H
10+
#define _LIBCPP___MEMORY_SHARED_COUNT_H
11+
12+
#include <__config>
13+
#include <typeinfo>
14+
15+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16+
# pragma GCC system_header
17+
#endif
18+
19+
_LIBCPP_BEGIN_NAMESPACE_STD
20+
21+
// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)
22+
// should be sufficient for thread safety.
23+
// See https://llvm.org/PR22803
24+
#if (defined(__clang__) && __has_builtin(__atomic_add_fetch) && defined(__ATOMIC_RELAXED) && \
25+
defined(__ATOMIC_ACQ_REL)) || \
26+
defined(_LIBCPP_COMPILER_GCC)
27+
# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT 1
28+
#else
29+
# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT 0
30+
#endif
31+
32+
template <class _ValueType>
33+
inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_relaxed_load(_ValueType const* __value) {
34+
#if _LIBCPP_HAS_THREADS && defined(__ATOMIC_RELAXED) && \
35+
(__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
36+
return __atomic_load_n(__value, __ATOMIC_RELAXED);
37+
#else
38+
return *__value;
39+
#endif
40+
}
41+
42+
template <class _ValueType>
43+
inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_acquire_load(_ValueType const* __value) {
44+
#if _LIBCPP_HAS_THREADS && defined(__ATOMIC_ACQUIRE) && \
45+
(__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
46+
return __atomic_load_n(__value, __ATOMIC_ACQUIRE);
47+
#else
48+
return *__value;
49+
#endif
50+
}
51+
52+
template <class _Tp>
53+
inline _LIBCPP_HIDE_FROM_ABI _Tp __libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT {
54+
#if _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT && _LIBCPP_HAS_THREADS
55+
return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED);
56+
#else
57+
return __t += 1;
58+
#endif
59+
}
60+
61+
template <class _Tp>
62+
inline _LIBCPP_HIDE_FROM_ABI _Tp __libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT {
63+
#if _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT && _LIBCPP_HAS_THREADS
64+
return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL);
65+
#else
66+
return __t -= 1;
67+
#endif
68+
}
69+
70+
class _LIBCPP_EXPORTED_FROM_ABI __shared_count {
71+
__shared_count(const __shared_count&);
72+
__shared_count& operator=(const __shared_count&);
73+
74+
protected:
75+
long __shared_owners_;
76+
virtual ~__shared_count();
77+
78+
private:
79+
virtual void __on_zero_shared() _NOEXCEPT = 0;
80+
81+
public:
82+
_LIBCPP_HIDE_FROM_ABI explicit __shared_count(long __refs = 0) _NOEXCEPT : __shared_owners_(__refs) {}
83+
84+
#if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS)
85+
void __add_shared() noexcept;
86+
bool __release_shared() noexcept;
87+
#else
88+
_LIBCPP_HIDE_FROM_ABI void __add_shared() _NOEXCEPT { __libcpp_atomic_refcount_increment(__shared_owners_); }
89+
_LIBCPP_HIDE_FROM_ABI bool __release_shared() _NOEXCEPT {
90+
if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) {
91+
__on_zero_shared();
92+
return true;
93+
}
94+
return false;
95+
}
96+
#endif
97+
_LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __libcpp_relaxed_load(&__shared_owners_) + 1; }
98+
};
99+
100+
class _LIBCPP_EXPORTED_FROM_ABI __shared_weak_count : private __shared_count {
101+
long __shared_weak_owners_;
102+
103+
public:
104+
_LIBCPP_HIDE_FROM_ABI explicit __shared_weak_count(long __refs = 0) _NOEXCEPT
105+
: __shared_count(__refs),
106+
__shared_weak_owners_(__refs) {}
107+
108+
protected:
109+
~__shared_weak_count() override;
110+
111+
public:
112+
#if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS)
113+
void __add_shared() noexcept;
114+
void __add_weak() noexcept;
115+
void __release_shared() noexcept;
116+
#else
117+
_LIBCPP_HIDE_FROM_ABI void __add_shared() _NOEXCEPT { __shared_count::__add_shared(); }
118+
_LIBCPP_HIDE_FROM_ABI void __add_weak() _NOEXCEPT { __libcpp_atomic_refcount_increment(__shared_weak_owners_); }
119+
_LIBCPP_HIDE_FROM_ABI void __release_shared() _NOEXCEPT {
120+
if (__shared_count::__release_shared())
121+
__release_weak();
122+
}
123+
#endif
124+
void __release_weak() _NOEXCEPT;
125+
_LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __shared_count::use_count(); }
126+
__shared_weak_count* lock() _NOEXCEPT;
127+
128+
virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
129+
130+
private:
131+
virtual void __on_zero_shared_weak() _NOEXCEPT = 0;
132+
};
133+
134+
_LIBCPP_END_NAMESPACE_STD
135+
136+
#endif // _LIBCPP___MEMORY_SHARED_COUNT_H

libcxx/include/__memory/shared_ptr.h

Lines changed: 1 addition & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <__memory/compressed_pair.h>
3131
#include <__memory/construct_at.h>
3232
#include <__memory/pointer_traits.h>
33+
#include <__memory/shared_count.h>
3334
#include <__memory/uninitialized_algorithms.h>
3435
#include <__memory/unique_ptr.h>
3536
#include <__type_traits/add_lvalue_reference.h>
@@ -70,55 +71,6 @@ _LIBCPP_PUSH_MACROS
7071

7172
_LIBCPP_BEGIN_NAMESPACE_STD
7273

73-
// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)
74-
// should be sufficient for thread safety.
75-
// See https://llvm.org/PR22803
76-
#if (defined(__clang__) && __has_builtin(__atomic_add_fetch) && defined(__ATOMIC_RELAXED) && \
77-
defined(__ATOMIC_ACQ_REL)) || \
78-
defined(_LIBCPP_COMPILER_GCC)
79-
# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT 1
80-
#else
81-
# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT 0
82-
#endif
83-
84-
template <class _ValueType>
85-
inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_relaxed_load(_ValueType const* __value) {
86-
#if _LIBCPP_HAS_THREADS && defined(__ATOMIC_RELAXED) && \
87-
(__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
88-
return __atomic_load_n(__value, __ATOMIC_RELAXED);
89-
#else
90-
return *__value;
91-
#endif
92-
}
93-
94-
template <class _ValueType>
95-
inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_acquire_load(_ValueType const* __value) {
96-
#if _LIBCPP_HAS_THREADS && defined(__ATOMIC_ACQUIRE) && \
97-
(__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
98-
return __atomic_load_n(__value, __ATOMIC_ACQUIRE);
99-
#else
100-
return *__value;
101-
#endif
102-
}
103-
104-
template <class _Tp>
105-
inline _LIBCPP_HIDE_FROM_ABI _Tp __libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT {
106-
#if _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT && _LIBCPP_HAS_THREADS
107-
return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED);
108-
#else
109-
return __t += 1;
110-
#endif
111-
}
112-
113-
template <class _Tp>
114-
inline _LIBCPP_HIDE_FROM_ABI _Tp __libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT {
115-
#if _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT && _LIBCPP_HAS_THREADS
116-
return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL);
117-
#else
118-
return __t -= 1;
119-
#endif
120-
}
121-
12274
class _LIBCPP_EXPORTED_FROM_ABI bad_weak_ptr : public std::exception {
12375
public:
12476
_LIBCPP_HIDE_FROM_ABI bad_weak_ptr() _NOEXCEPT = default;
@@ -139,70 +91,6 @@ class _LIBCPP_EXPORTED_FROM_ABI bad_weak_ptr : public std::exception {
13991
template <class _Tp>
14092
class _LIBCPP_TEMPLATE_VIS weak_ptr;
14193

142-
class _LIBCPP_EXPORTED_FROM_ABI __shared_count {
143-
__shared_count(const __shared_count&);
144-
__shared_count& operator=(const __shared_count&);
145-
146-
protected:
147-
long __shared_owners_;
148-
virtual ~__shared_count();
149-
150-
private:
151-
virtual void __on_zero_shared() _NOEXCEPT = 0;
152-
153-
public:
154-
_LIBCPP_HIDE_FROM_ABI explicit __shared_count(long __refs = 0) _NOEXCEPT : __shared_owners_(__refs) {}
155-
156-
#if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS)
157-
void __add_shared() noexcept;
158-
bool __release_shared() noexcept;
159-
#else
160-
_LIBCPP_HIDE_FROM_ABI void __add_shared() _NOEXCEPT { __libcpp_atomic_refcount_increment(__shared_owners_); }
161-
_LIBCPP_HIDE_FROM_ABI bool __release_shared() _NOEXCEPT {
162-
if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) {
163-
__on_zero_shared();
164-
return true;
165-
}
166-
return false;
167-
}
168-
#endif
169-
_LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __libcpp_relaxed_load(&__shared_owners_) + 1; }
170-
};
171-
172-
class _LIBCPP_EXPORTED_FROM_ABI __shared_weak_count : private __shared_count {
173-
long __shared_weak_owners_;
174-
175-
public:
176-
_LIBCPP_HIDE_FROM_ABI explicit __shared_weak_count(long __refs = 0) _NOEXCEPT
177-
: __shared_count(__refs),
178-
__shared_weak_owners_(__refs) {}
179-
180-
protected:
181-
~__shared_weak_count() override;
182-
183-
public:
184-
#if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS)
185-
void __add_shared() noexcept;
186-
void __add_weak() noexcept;
187-
void __release_shared() noexcept;
188-
#else
189-
_LIBCPP_HIDE_FROM_ABI void __add_shared() _NOEXCEPT { __shared_count::__add_shared(); }
190-
_LIBCPP_HIDE_FROM_ABI void __add_weak() _NOEXCEPT { __libcpp_atomic_refcount_increment(__shared_weak_owners_); }
191-
_LIBCPP_HIDE_FROM_ABI void __release_shared() _NOEXCEPT {
192-
if (__shared_count::__release_shared())
193-
__release_weak();
194-
}
195-
#endif
196-
void __release_weak() _NOEXCEPT;
197-
_LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __shared_count::use_count(); }
198-
__shared_weak_count* lock() _NOEXCEPT;
199-
200-
virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
201-
202-
private:
203-
virtual void __on_zero_shared_weak() _NOEXCEPT = 0;
204-
};
205-
20694
template <class _Tp, class _Dp, class _Alloc>
20795
class __shared_ptr_pointer : public __shared_weak_count {
20896
_LIBCPP_COMPRESSED_TRIPLE(_Tp, __ptr_, _Dp, __deleter_, _Alloc, __alloc_);

libcxx/include/__mutex/once_flag.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
#include <__config>
1313
#include <__functional/invoke.h>
14-
#include <__memory/shared_ptr.h> // __libcpp_acquire_load
14+
#include <__memory/shared_count.h> // __libcpp_acquire_load
1515
#include <__tuple/tuple_indices.h>
1616
#include <__tuple/tuple_size.h>
1717
#include <__utility/forward.h>

libcxx/include/future

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
378378
# include <__memory/allocator_traits.h>
379379
# include <__memory/compressed_pair.h>
380380
# include <__memory/pointer_traits.h>
381-
# include <__memory/shared_ptr.h>
381+
# include <__memory/shared_count.h>
382382
# include <__memory/unique_ptr.h>
383383
# include <__memory/uses_allocator.h>
384384
# include <__system_error/error_category.h>

libcxx/include/module.modulemap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,6 +1542,7 @@ module std [system] {
15421542
export std.algorithm.in_out_result
15431543
}
15441544
module raw_storage_iterator { header "__memory/raw_storage_iterator.h" }
1545+
module shared_count { header "__memory/shared_count.h" }
15451546
module shared_ptr { header "__memory/shared_ptr.h" }
15461547
module swap_allocator { header "__memory/swap_allocator.h" }
15471548
module temp_value { header "__memory/temp_value.h" }

libcxx/include/mutex

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,6 @@ template<class Callable, class ...Args>
190190
#include <__chrono/time_point.h>
191191
#include <__condition_variable/condition_variable.h>
192192
#include <__config>
193-
#include <__memory/shared_ptr.h>
194193
#include <__mutex/lock_guard.h>
195194
#include <__mutex/mutex.h>
196195
#include <__mutex/once_flag.h>

0 commit comments

Comments
 (0)