xref: /aosp_15_r20/external/libcxx/src/memory.cpp (revision 58b9f456b02922dfdb1fad8a988d5fd8765ecb80)
1*58b9f456SAndroid Build Coastguard Worker //===------------------------ memory.cpp ----------------------------------===//
2*58b9f456SAndroid Build Coastguard Worker //
3*58b9f456SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*58b9f456SAndroid Build Coastguard Worker //
5*58b9f456SAndroid Build Coastguard Worker // This file is dual licensed under the MIT and the University of Illinois Open
6*58b9f456SAndroid Build Coastguard Worker // Source Licenses. See LICENSE.TXT for details.
7*58b9f456SAndroid Build Coastguard Worker //
8*58b9f456SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*58b9f456SAndroid Build Coastguard Worker 
10*58b9f456SAndroid Build Coastguard Worker #include "memory"
11*58b9f456SAndroid Build Coastguard Worker #ifndef _LIBCPP_HAS_NO_THREADS
12*58b9f456SAndroid Build Coastguard Worker #include "mutex"
13*58b9f456SAndroid Build Coastguard Worker #include "thread"
14*58b9f456SAndroid Build Coastguard Worker #endif
15*58b9f456SAndroid Build Coastguard Worker #include "include/atomic_support.h"
16*58b9f456SAndroid Build Coastguard Worker 
17*58b9f456SAndroid Build Coastguard Worker _LIBCPP_BEGIN_NAMESPACE_STD
18*58b9f456SAndroid Build Coastguard Worker 
19*58b9f456SAndroid Build Coastguard Worker const allocator_arg_t allocator_arg = allocator_arg_t();
20*58b9f456SAndroid Build Coastguard Worker 
~bad_weak_ptr()21*58b9f456SAndroid Build Coastguard Worker bad_weak_ptr::~bad_weak_ptr() _NOEXCEPT {}
22*58b9f456SAndroid Build Coastguard Worker 
23*58b9f456SAndroid Build Coastguard Worker const char*
what() const24*58b9f456SAndroid Build Coastguard Worker bad_weak_ptr::what() const _NOEXCEPT
25*58b9f456SAndroid Build Coastguard Worker {
26*58b9f456SAndroid Build Coastguard Worker     return "bad_weak_ptr";
27*58b9f456SAndroid Build Coastguard Worker }
28*58b9f456SAndroid Build Coastguard Worker 
~__shared_count()29*58b9f456SAndroid Build Coastguard Worker __shared_count::~__shared_count()
30*58b9f456SAndroid Build Coastguard Worker {
31*58b9f456SAndroid Build Coastguard Worker }
32*58b9f456SAndroid Build Coastguard Worker 
~__shared_weak_count()33*58b9f456SAndroid Build Coastguard Worker __shared_weak_count::~__shared_weak_count()
34*58b9f456SAndroid Build Coastguard Worker {
35*58b9f456SAndroid Build Coastguard Worker }
36*58b9f456SAndroid Build Coastguard Worker 
37*58b9f456SAndroid Build Coastguard Worker #if defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
38*58b9f456SAndroid Build Coastguard Worker void
__add_shared()39*58b9f456SAndroid Build Coastguard Worker __shared_count::__add_shared() _NOEXCEPT
40*58b9f456SAndroid Build Coastguard Worker {
41*58b9f456SAndroid Build Coastguard Worker     __libcpp_atomic_refcount_increment(__shared_owners_);
42*58b9f456SAndroid Build Coastguard Worker }
43*58b9f456SAndroid Build Coastguard Worker 
44*58b9f456SAndroid Build Coastguard Worker bool
__release_shared()45*58b9f456SAndroid Build Coastguard Worker __shared_count::__release_shared() _NOEXCEPT
46*58b9f456SAndroid Build Coastguard Worker {
47*58b9f456SAndroid Build Coastguard Worker     if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1)
48*58b9f456SAndroid Build Coastguard Worker     {
49*58b9f456SAndroid Build Coastguard Worker         __on_zero_shared();
50*58b9f456SAndroid Build Coastguard Worker         return true;
51*58b9f456SAndroid Build Coastguard Worker     }
52*58b9f456SAndroid Build Coastguard Worker     return false;
53*58b9f456SAndroid Build Coastguard Worker }
54*58b9f456SAndroid Build Coastguard Worker 
55*58b9f456SAndroid Build Coastguard Worker void
__add_shared()56*58b9f456SAndroid Build Coastguard Worker __shared_weak_count::__add_shared() _NOEXCEPT
57*58b9f456SAndroid Build Coastguard Worker {
58*58b9f456SAndroid Build Coastguard Worker     __shared_count::__add_shared();
59*58b9f456SAndroid Build Coastguard Worker }
60*58b9f456SAndroid Build Coastguard Worker 
61*58b9f456SAndroid Build Coastguard Worker void
__add_weak()62*58b9f456SAndroid Build Coastguard Worker __shared_weak_count::__add_weak() _NOEXCEPT
63*58b9f456SAndroid Build Coastguard Worker {
64*58b9f456SAndroid Build Coastguard Worker     __libcpp_atomic_refcount_increment(__shared_weak_owners_);
65*58b9f456SAndroid Build Coastguard Worker }
66*58b9f456SAndroid Build Coastguard Worker 
67*58b9f456SAndroid Build Coastguard Worker void
__release_shared()68*58b9f456SAndroid Build Coastguard Worker __shared_weak_count::__release_shared() _NOEXCEPT
69*58b9f456SAndroid Build Coastguard Worker {
70*58b9f456SAndroid Build Coastguard Worker     if (__shared_count::__release_shared())
71*58b9f456SAndroid Build Coastguard Worker         __release_weak();
72*58b9f456SAndroid Build Coastguard Worker }
73*58b9f456SAndroid Build Coastguard Worker 
74*58b9f456SAndroid Build Coastguard Worker #endif // _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS
75*58b9f456SAndroid Build Coastguard Worker 
76*58b9f456SAndroid Build Coastguard Worker void
__release_weak()77*58b9f456SAndroid Build Coastguard Worker __shared_weak_count::__release_weak() _NOEXCEPT
78*58b9f456SAndroid Build Coastguard Worker {
79*58b9f456SAndroid Build Coastguard Worker     // NOTE: The acquire load here is an optimization of the very
80*58b9f456SAndroid Build Coastguard Worker     // common case where a shared pointer is being destructed while
81*58b9f456SAndroid Build Coastguard Worker     // having no other contended references.
82*58b9f456SAndroid Build Coastguard Worker     //
83*58b9f456SAndroid Build Coastguard Worker     // BENEFIT: We avoid expensive atomic stores like XADD and STREX
84*58b9f456SAndroid Build Coastguard Worker     // in a common case.  Those instructions are slow and do nasty
85*58b9f456SAndroid Build Coastguard Worker     // things to caches.
86*58b9f456SAndroid Build Coastguard Worker     //
87*58b9f456SAndroid Build Coastguard Worker     // IS THIS SAFE?  Yes.  During weak destruction, if we see that we
88*58b9f456SAndroid Build Coastguard Worker     // are the last reference, we know that no-one else is accessing
89*58b9f456SAndroid Build Coastguard Worker     // us. If someone were accessing us, then they would be doing so
90*58b9f456SAndroid Build Coastguard Worker     // while the last shared / weak_ptr was being destructed, and
91*58b9f456SAndroid Build Coastguard Worker     // that's undefined anyway.
92*58b9f456SAndroid Build Coastguard Worker     //
93*58b9f456SAndroid Build Coastguard Worker     // If we see anything other than a 0, then we have possible
94*58b9f456SAndroid Build Coastguard Worker     // contention, and need to use an atomicrmw primitive.
95*58b9f456SAndroid Build Coastguard Worker     // The same arguments don't apply for increment, where it is legal
96*58b9f456SAndroid Build Coastguard Worker     // (though inadvisable) to share shared_ptr references between
97*58b9f456SAndroid Build Coastguard Worker     // threads, and have them all get copied at once.  The argument
98*58b9f456SAndroid Build Coastguard Worker     // also doesn't apply for __release_shared, because an outstanding
99*58b9f456SAndroid Build Coastguard Worker     // weak_ptr::lock() could read / modify the shared count.
100*58b9f456SAndroid Build Coastguard Worker     if (__libcpp_atomic_load(&__shared_weak_owners_, _AO_Acquire) == 0)
101*58b9f456SAndroid Build Coastguard Worker     {
102*58b9f456SAndroid Build Coastguard Worker         // no need to do this store, because we are about
103*58b9f456SAndroid Build Coastguard Worker         // to destroy everything.
104*58b9f456SAndroid Build Coastguard Worker         //__libcpp_atomic_store(&__shared_weak_owners_, -1, _AO_Release);
105*58b9f456SAndroid Build Coastguard Worker         __on_zero_shared_weak();
106*58b9f456SAndroid Build Coastguard Worker     }
107*58b9f456SAndroid Build Coastguard Worker     else if (__libcpp_atomic_refcount_decrement(__shared_weak_owners_) == -1)
108*58b9f456SAndroid Build Coastguard Worker         __on_zero_shared_weak();
109*58b9f456SAndroid Build Coastguard Worker }
110*58b9f456SAndroid Build Coastguard Worker 
111*58b9f456SAndroid Build Coastguard Worker __shared_weak_count*
lock()112*58b9f456SAndroid Build Coastguard Worker __shared_weak_count::lock() _NOEXCEPT
113*58b9f456SAndroid Build Coastguard Worker {
114*58b9f456SAndroid Build Coastguard Worker     long object_owners = __libcpp_atomic_load(&__shared_owners_);
115*58b9f456SAndroid Build Coastguard Worker     while (object_owners != -1)
116*58b9f456SAndroid Build Coastguard Worker     {
117*58b9f456SAndroid Build Coastguard Worker         if (__libcpp_atomic_compare_exchange(&__shared_owners_,
118*58b9f456SAndroid Build Coastguard Worker                                              &object_owners,
119*58b9f456SAndroid Build Coastguard Worker                                              object_owners+1))
120*58b9f456SAndroid Build Coastguard Worker             return this;
121*58b9f456SAndroid Build Coastguard Worker     }
122*58b9f456SAndroid Build Coastguard Worker     return nullptr;
123*58b9f456SAndroid Build Coastguard Worker }
124*58b9f456SAndroid Build Coastguard Worker 
125*58b9f456SAndroid Build Coastguard Worker #if !defined(_LIBCPP_NO_RTTI) || !defined(_LIBCPP_BUILD_STATIC)
126*58b9f456SAndroid Build Coastguard Worker 
127*58b9f456SAndroid Build Coastguard Worker const void*
__get_deleter(const type_info &) const128*58b9f456SAndroid Build Coastguard Worker __shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT
129*58b9f456SAndroid Build Coastguard Worker {
130*58b9f456SAndroid Build Coastguard Worker     return nullptr;
131*58b9f456SAndroid Build Coastguard Worker }
132*58b9f456SAndroid Build Coastguard Worker 
133*58b9f456SAndroid Build Coastguard Worker #endif  // _LIBCPP_NO_RTTI
134*58b9f456SAndroid Build Coastguard Worker 
135*58b9f456SAndroid Build Coastguard Worker #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
136*58b9f456SAndroid Build Coastguard Worker 
137*58b9f456SAndroid Build Coastguard Worker _LIBCPP_SAFE_STATIC static const std::size_t __sp_mut_count = 16;
138*58b9f456SAndroid Build Coastguard Worker _LIBCPP_SAFE_STATIC static __libcpp_mutex_t mut_back[__sp_mut_count] =
139*58b9f456SAndroid Build Coastguard Worker {
140*58b9f456SAndroid Build Coastguard Worker     _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER,
141*58b9f456SAndroid Build Coastguard Worker     _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER,
142*58b9f456SAndroid Build Coastguard Worker     _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER,
143*58b9f456SAndroid Build Coastguard Worker     _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER
144*58b9f456SAndroid Build Coastguard Worker };
145*58b9f456SAndroid Build Coastguard Worker 
__sp_mut(void * p)146*58b9f456SAndroid Build Coastguard Worker _LIBCPP_CONSTEXPR __sp_mut::__sp_mut(void* p) _NOEXCEPT
147*58b9f456SAndroid Build Coastguard Worker    : __lx(p)
148*58b9f456SAndroid Build Coastguard Worker {
149*58b9f456SAndroid Build Coastguard Worker }
150*58b9f456SAndroid Build Coastguard Worker 
151*58b9f456SAndroid Build Coastguard Worker void
lock()152*58b9f456SAndroid Build Coastguard Worker __sp_mut::lock() _NOEXCEPT
153*58b9f456SAndroid Build Coastguard Worker {
154*58b9f456SAndroid Build Coastguard Worker     auto m = static_cast<__libcpp_mutex_t*>(__lx);
155*58b9f456SAndroid Build Coastguard Worker     unsigned count = 0;
156*58b9f456SAndroid Build Coastguard Worker     while (!__libcpp_mutex_trylock(m))
157*58b9f456SAndroid Build Coastguard Worker     {
158*58b9f456SAndroid Build Coastguard Worker         if (++count > 16)
159*58b9f456SAndroid Build Coastguard Worker         {
160*58b9f456SAndroid Build Coastguard Worker             __libcpp_mutex_lock(m);
161*58b9f456SAndroid Build Coastguard Worker             break;
162*58b9f456SAndroid Build Coastguard Worker         }
163*58b9f456SAndroid Build Coastguard Worker         this_thread::yield();
164*58b9f456SAndroid Build Coastguard Worker     }
165*58b9f456SAndroid Build Coastguard Worker }
166*58b9f456SAndroid Build Coastguard Worker 
167*58b9f456SAndroid Build Coastguard Worker void
unlock()168*58b9f456SAndroid Build Coastguard Worker __sp_mut::unlock() _NOEXCEPT
169*58b9f456SAndroid Build Coastguard Worker {
170*58b9f456SAndroid Build Coastguard Worker     __libcpp_mutex_unlock(static_cast<__libcpp_mutex_t*>(__lx));
171*58b9f456SAndroid Build Coastguard Worker }
172*58b9f456SAndroid Build Coastguard Worker 
173*58b9f456SAndroid Build Coastguard Worker __sp_mut&
__get_sp_mut(const void * p)174*58b9f456SAndroid Build Coastguard Worker __get_sp_mut(const void* p)
175*58b9f456SAndroid Build Coastguard Worker {
176*58b9f456SAndroid Build Coastguard Worker     static __sp_mut muts[__sp_mut_count]
177*58b9f456SAndroid Build Coastguard Worker     {
178*58b9f456SAndroid Build Coastguard Worker         &mut_back[ 0], &mut_back[ 1], &mut_back[ 2], &mut_back[ 3],
179*58b9f456SAndroid Build Coastguard Worker         &mut_back[ 4], &mut_back[ 5], &mut_back[ 6], &mut_back[ 7],
180*58b9f456SAndroid Build Coastguard Worker         &mut_back[ 8], &mut_back[ 9], &mut_back[10], &mut_back[11],
181*58b9f456SAndroid Build Coastguard Worker         &mut_back[12], &mut_back[13], &mut_back[14], &mut_back[15]
182*58b9f456SAndroid Build Coastguard Worker     };
183*58b9f456SAndroid Build Coastguard Worker     return muts[hash<const void*>()(p) & (__sp_mut_count-1)];
184*58b9f456SAndroid Build Coastguard Worker }
185*58b9f456SAndroid Build Coastguard Worker 
186*58b9f456SAndroid Build Coastguard Worker #endif // !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
187*58b9f456SAndroid Build Coastguard Worker 
188*58b9f456SAndroid Build Coastguard Worker void
declare_reachable(void *)189*58b9f456SAndroid Build Coastguard Worker declare_reachable(void*)
190*58b9f456SAndroid Build Coastguard Worker {
191*58b9f456SAndroid Build Coastguard Worker }
192*58b9f456SAndroid Build Coastguard Worker 
193*58b9f456SAndroid Build Coastguard Worker void
declare_no_pointers(char *,size_t)194*58b9f456SAndroid Build Coastguard Worker declare_no_pointers(char*, size_t)
195*58b9f456SAndroid Build Coastguard Worker {
196*58b9f456SAndroid Build Coastguard Worker }
197*58b9f456SAndroid Build Coastguard Worker 
198*58b9f456SAndroid Build Coastguard Worker void
undeclare_no_pointers(char *,size_t)199*58b9f456SAndroid Build Coastguard Worker undeclare_no_pointers(char*, size_t)
200*58b9f456SAndroid Build Coastguard Worker {
201*58b9f456SAndroid Build Coastguard Worker }
202*58b9f456SAndroid Build Coastguard Worker 
203*58b9f456SAndroid Build Coastguard Worker #if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE)
get_pointer_safety()204*58b9f456SAndroid Build Coastguard Worker pointer_safety get_pointer_safety() _NOEXCEPT
205*58b9f456SAndroid Build Coastguard Worker {
206*58b9f456SAndroid Build Coastguard Worker     return pointer_safety::relaxed;
207*58b9f456SAndroid Build Coastguard Worker }
208*58b9f456SAndroid Build Coastguard Worker #endif
209*58b9f456SAndroid Build Coastguard Worker 
210*58b9f456SAndroid Build Coastguard Worker void*
__undeclare_reachable(void * p)211*58b9f456SAndroid Build Coastguard Worker __undeclare_reachable(void* p)
212*58b9f456SAndroid Build Coastguard Worker {
213*58b9f456SAndroid Build Coastguard Worker     return p;
214*58b9f456SAndroid Build Coastguard Worker }
215*58b9f456SAndroid Build Coastguard Worker 
216*58b9f456SAndroid Build Coastguard Worker void*
align(size_t alignment,size_t size,void * & ptr,size_t & space)217*58b9f456SAndroid Build Coastguard Worker align(size_t alignment, size_t size, void*& ptr, size_t& space)
218*58b9f456SAndroid Build Coastguard Worker {
219*58b9f456SAndroid Build Coastguard Worker     void* r = nullptr;
220*58b9f456SAndroid Build Coastguard Worker     if (size <= space)
221*58b9f456SAndroid Build Coastguard Worker     {
222*58b9f456SAndroid Build Coastguard Worker         char* p1 = static_cast<char*>(ptr);
223*58b9f456SAndroid Build Coastguard Worker         char* p2 = reinterpret_cast<char*>(reinterpret_cast<size_t>(p1 + (alignment - 1)) & -alignment);
224*58b9f456SAndroid Build Coastguard Worker         size_t d = static_cast<size_t>(p2 - p1);
225*58b9f456SAndroid Build Coastguard Worker         if (d <= space - size)
226*58b9f456SAndroid Build Coastguard Worker         {
227*58b9f456SAndroid Build Coastguard Worker             r = p2;
228*58b9f456SAndroid Build Coastguard Worker             ptr = r;
229*58b9f456SAndroid Build Coastguard Worker             space -= d;
230*58b9f456SAndroid Build Coastguard Worker         }
231*58b9f456SAndroid Build Coastguard Worker     }
232*58b9f456SAndroid Build Coastguard Worker     return r;
233*58b9f456SAndroid Build Coastguard Worker }
234*58b9f456SAndroid Build Coastguard Worker 
235*58b9f456SAndroid Build Coastguard Worker _LIBCPP_END_NAMESPACE_STD
236