1 //===------------------------ memory.cpp ----------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #define _LIBCPP_BUILDING_MEMORY
15 _LIBCPP_BEGIN_NAMESPACE_STD
22 increment(T
& t
) _NOEXCEPT
24 return __sync_add_and_fetch(&t
, 1);
29 decrement(T
& t
) _NOEXCEPT
31 return __sync_add_and_fetch(&t
, -1);
36 const allocator_arg_t allocator_arg
= allocator_arg_t();
38 bad_weak_ptr::~bad_weak_ptr() _NOEXCEPT
{}
41 bad_weak_ptr::what() const _NOEXCEPT
43 return "bad_weak_ptr";
46 __shared_count::~__shared_count()
51 __shared_count::__add_shared() _NOEXCEPT
53 increment(__shared_owners_
);
57 __shared_count::__release_shared() _NOEXCEPT
59 if (decrement(__shared_owners_
) == -1)
67 __shared_weak_count::~__shared_weak_count()
72 __shared_weak_count::__add_shared() _NOEXCEPT
74 __shared_count::__add_shared();
78 __shared_weak_count::__add_weak() _NOEXCEPT
80 increment(__shared_weak_owners_
);
84 __shared_weak_count::__release_shared() _NOEXCEPT
86 if (__shared_count::__release_shared())
91 __shared_weak_count::__release_weak() _NOEXCEPT
93 if (decrement(__shared_weak_owners_
) == -1)
94 __on_zero_shared_weak();
98 __shared_weak_count::lock() _NOEXCEPT
100 long object_owners
= __shared_owners_
;
101 while (object_owners
!= -1)
103 if (__sync_bool_compare_and_swap(&__shared_owners_
,
107 object_owners
= __shared_owners_
;
112 #ifndef _LIBCPP_NO_RTTI
115 __shared_weak_count::__get_deleter(const type_info
&) const _NOEXCEPT
120 #endif // _LIBCPP_NO_RTTI
122 #if __has_feature(cxx_atomic)
124 static const std::size_t __sp_mut_count
= 16;
125 static pthread_mutex_t mut_back_imp
[__sp_mut_count
] =
127 PTHREAD_MUTEX_INITIALIZER
, PTHREAD_MUTEX_INITIALIZER
, PTHREAD_MUTEX_INITIALIZER
, PTHREAD_MUTEX_INITIALIZER
,
128 PTHREAD_MUTEX_INITIALIZER
, PTHREAD_MUTEX_INITIALIZER
, PTHREAD_MUTEX_INITIALIZER
, PTHREAD_MUTEX_INITIALIZER
,
129 PTHREAD_MUTEX_INITIALIZER
, PTHREAD_MUTEX_INITIALIZER
, PTHREAD_MUTEX_INITIALIZER
, PTHREAD_MUTEX_INITIALIZER
,
130 PTHREAD_MUTEX_INITIALIZER
, PTHREAD_MUTEX_INITIALIZER
, PTHREAD_MUTEX_INITIALIZER
, PTHREAD_MUTEX_INITIALIZER
133 static mutex
* mut_back
= reinterpret_cast<std::mutex
*>(mut_back_imp
);
135 _LIBCPP_CONSTEXPR
__sp_mut::__sp_mut(void* p
) _NOEXCEPT
141 __sp_mut::lock() _NOEXCEPT
143 mutex
& m
= *static_cast<mutex
*>(__lx
);
145 while (!m
.try_lock())
152 this_thread::yield();
157 __sp_mut::unlock() _NOEXCEPT
159 static_cast<mutex
*>(__lx
)->unlock();
163 __get_sp_mut(const void* p
)
165 static __sp_mut muts
[__sp_mut_count
]
167 &mut_back
[ 0], &mut_back
[ 1], &mut_back
[ 2], &mut_back
[ 3],
168 &mut_back
[ 4], &mut_back
[ 5], &mut_back
[ 6], &mut_back
[ 7],
169 &mut_back
[ 8], &mut_back
[ 9], &mut_back
[10], &mut_back
[11],
170 &mut_back
[12], &mut_back
[13], &mut_back
[14], &mut_back
[15]
172 return muts
[hash
<const void*>()(p
) & (__sp_mut_count
-1)];
175 #endif // __has_feature(cxx_atomic)
178 declare_reachable(void*)
183 declare_no_pointers(char*, size_t)
188 undeclare_no_pointers(char*, size_t)
193 get_pointer_safety() _NOEXCEPT
195 return pointer_safety::relaxed
;
199 __undeclare_reachable(void* p
)
205 align(size_t alignment
, size_t size
, void*& ptr
, size_t& space
)
210 char* p1
= static_cast<char*>(ptr
);
211 char* p2
= (char*)((size_t)(p1
+ (alignment
- 1)) & -alignment
);
212 size_t d
= static_cast<size_t>(p2
- p1
);
213 if (d
<= space
- size
)
223 _LIBCPP_END_NAMESPACE_STD