blob: 31e823cf41931db417d1ca646b7263f4e948e78d [file] [log] [blame]
Howard Hinnant3e519522010-05-11 19:42:161//===------------------------ memory.cpp ----------------------------------===//
2//
Howard Hinnant5b08a8a2010-05-11 21:36:013// The LLVM Compiler Infrastructure
Howard Hinnant3e519522010-05-11 19:42:164//
Howard Hinnant412dbeb2010-11-16 22:09:025// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
Howard Hinnant3e519522010-05-11 19:42:167//
8//===----------------------------------------------------------------------===//
9
Howard Hinnantc0937e82012-07-07 20:56:0410#define _LIBCPP_BUILDING_MEMORY
Howard Hinnant3e519522010-05-11 19:42:1611#include "memory"
Jonathan Roelofsb3fcc672014-09-05 19:45:0512#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnantd77851e2012-07-30 01:40:5713#include "mutex"
Howard Hinnant088e37c2012-07-30 17:13:2114#include "thread"
Jonathan Roelofsb3fcc672014-09-05 19:45:0515#endif
Howard Hinnant3e519522010-05-11 19:42:1616
17_LIBCPP_BEGIN_NAMESPACE_STD
18
19namespace
20{
21
22template <class T>
Howard Hinnant128ba712010-05-24 17:49:4123inline T
Howard Hinnant3739fe72011-05-28 14:41:1324increment(T& t) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1625{
Howard Hinnant128ba712010-05-24 17:49:4126 return __sync_add_and_fetch(&t, 1);
Howard Hinnant3e519522010-05-11 19:42:1627}
28
29template <class T>
Howard Hinnant128ba712010-05-24 17:49:4130inline T
Howard Hinnant3739fe72011-05-28 14:41:1331decrement(T& t) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1632{
Howard Hinnant128ba712010-05-24 17:49:4133 return __sync_add_and_fetch(&t, -1);
Howard Hinnant3e519522010-05-11 19:42:1634}
35
Howard Hinnant3e519522010-05-11 19:42:1636} // namespace
37
Howard Hinnant3e519522010-05-11 19:42:1638const allocator_arg_t allocator_arg = allocator_arg_t();
39
Howard Hinnant3739fe72011-05-28 14:41:1340bad_weak_ptr::~bad_weak_ptr() _NOEXCEPT {}
Howard Hinnant3e519522010-05-11 19:42:1641
42const char*
Howard Hinnant3739fe72011-05-28 14:41:1343bad_weak_ptr::what() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1644{
45 return "bad_weak_ptr";
46}
47
48__shared_count::~__shared_count()
49{
50}
51
52void
Howard Hinnant3739fe72011-05-28 14:41:1353__shared_count::__add_shared() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1654{
55 increment(__shared_owners_);
56}
57
Howard Hinnant9b35c822010-11-16 21:33:1758bool
Howard Hinnant3739fe72011-05-28 14:41:1359__shared_count::__release_shared() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1660{
61 if (decrement(__shared_owners_) == -1)
Howard Hinnant9b35c822010-11-16 21:33:1762 {
Howard Hinnant3e519522010-05-11 19:42:1663 __on_zero_shared();
Howard Hinnant9b35c822010-11-16 21:33:1764 return true;
65 }
66 return false;
Howard Hinnant3e519522010-05-11 19:42:1667}
68
69__shared_weak_count::~__shared_weak_count()
70{
71}
72
73void
Howard Hinnant3739fe72011-05-28 14:41:1374__shared_weak_count::__add_shared() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1675{
76 __shared_count::__add_shared();
Howard Hinnant3e519522010-05-11 19:42:1677}
78
79void
Howard Hinnant3739fe72011-05-28 14:41:1380__shared_weak_count::__add_weak() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1681{
82 increment(__shared_weak_owners_);
83}
84
85void
Howard Hinnant3739fe72011-05-28 14:41:1386__shared_weak_count::__release_shared() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1687{
Howard Hinnant9b35c822010-11-16 21:33:1788 if (__shared_count::__release_shared())
89 __release_weak();
Howard Hinnant3e519522010-05-11 19:42:1690}
91
92void
Howard Hinnant3739fe72011-05-28 14:41:1393__shared_weak_count::__release_weak() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1694{
95 if (decrement(__shared_weak_owners_) == -1)
96 __on_zero_shared_weak();
97}
98
99__shared_weak_count*
Howard Hinnant3739fe72011-05-28 14:41:13100__shared_weak_count::lock() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16101{
102 long object_owners = __shared_owners_;
103 while (object_owners != -1)
104 {
Howard Hinnant128ba712010-05-24 17:49:41105 if (__sync_bool_compare_and_swap(&__shared_owners_,
106 object_owners,
107 object_owners+1))
Howard Hinnant3e519522010-05-11 19:42:16108 return this;
Howard Hinnant3e519522010-05-11 19:42:16109 object_owners = __shared_owners_;
110 }
111 return 0;
112}
113
Howard Hinnant54b409f2010-08-11 17:04:31114#ifndef _LIBCPP_NO_RTTI
115
Howard Hinnant3e519522010-05-11 19:42:16116const void*
Howard Hinnant3739fe72011-05-28 14:41:13117__shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16118{
119 return 0;
120}
121
Howard Hinnant940e2112010-08-22 00:03:27122#endif // _LIBCPP_NO_RTTI
Howard Hinnant54b409f2010-08-11 17:04:31123
Jonathan Roelofsb3fcc672014-09-05 19:45:05124#if __has_feature(cxx_atomic) && !_LIBCPP_HAS_NO_THREADS
Howard Hinnante4b2a742012-08-19 15:13:16125
Howard Hinnantd77851e2012-07-30 01:40:57126static const std::size_t __sp_mut_count = 16;
Howard Hinnant5efca642013-03-16 00:17:53127static pthread_mutex_t mut_back_imp[__sp_mut_count] =
128{
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,
131 PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,
132 PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER
133};
134
135static mutex* mut_back = reinterpret_cast<std::mutex*>(mut_back_imp);
Howard Hinnantd77851e2012-07-30 01:40:57136
137_LIBCPP_CONSTEXPR __sp_mut::__sp_mut(void* p) _NOEXCEPT
Howard Hinnant54d333a2012-10-30 19:06:59138 : __lx(p)
Howard Hinnantd77851e2012-07-30 01:40:57139{
140}
141
142void
143__sp_mut::lock() _NOEXCEPT
144{
Howard Hinnant54d333a2012-10-30 19:06:59145 mutex& m = *static_cast<mutex*>(__lx);
Howard Hinnant088e37c2012-07-30 17:13:21146 unsigned count = 0;
147 while (!m.try_lock())
148 {
149 if (++count > 16)
150 {
151 m.lock();
152 break;
153 }
154 this_thread::yield();
155 }
Howard Hinnantd77851e2012-07-30 01:40:57156}
157
158void
159__sp_mut::unlock() _NOEXCEPT
160{
Howard Hinnant54d333a2012-10-30 19:06:59161 static_cast<mutex*>(__lx)->unlock();
Howard Hinnantd77851e2012-07-30 01:40:57162}
163
164__sp_mut&
165__get_sp_mut(const void* p)
166{
167 static __sp_mut muts[__sp_mut_count]
168 {
169 &mut_back[ 0], &mut_back[ 1], &mut_back[ 2], &mut_back[ 3],
170 &mut_back[ 4], &mut_back[ 5], &mut_back[ 6], &mut_back[ 7],
171 &mut_back[ 8], &mut_back[ 9], &mut_back[10], &mut_back[11],
172 &mut_back[12], &mut_back[13], &mut_back[14], &mut_back[15]
173 };
174 return muts[hash<const void*>()(p) & (__sp_mut_count-1)];
175}
176
Jonathan Roelofsb3fcc672014-09-05 19:45:05177#endif // __has_feature(cxx_atomic) && !_LIBCPP_HAS_NO_THREADS
Howard Hinnantd77851e2012-07-30 01:40:57178
Howard Hinnant3e519522010-05-11 19:42:16179void
180declare_reachable(void*)
181{
182}
183
184void
185declare_no_pointers(char*, size_t)
186{
187}
188
189void
190undeclare_no_pointers(char*, size_t)
191{
192}
193
194pointer_safety
Howard Hinnant3739fe72011-05-28 14:41:13195get_pointer_safety() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16196{
197 return pointer_safety::relaxed;
198}
199
200void*
201__undeclare_reachable(void* p)
202{
203 return p;
204}
205
206void*
207align(size_t alignment, size_t size, void*& ptr, size_t& space)
208{
209 void* r = nullptr;
210 if (size <= space)
211 {
212 char* p1 = static_cast<char*>(ptr);
Joerg Sonnenberger634b9dd2014-01-04 17:43:00213 char* p2 = reinterpret_cast<char*>(reinterpret_cast<size_t>(p1 + (alignment - 1)) & -alignment);
Howard Hinnantc2063662011-12-01 20:21:04214 size_t d = static_cast<size_t>(p2 - p1);
Howard Hinnant3e519522010-05-11 19:42:16215 if (d <= space - size)
216 {
217 r = p2;
218 ptr = r;
219 space -= d;
220 }
221 }
222 return r;
223}
224
225_LIBCPP_END_NAMESPACE_STD