blob: 8a4eb34811f2391ba155d9908331be7772d6f5ea [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001//===------------------------ memory.cpp ----------------------------------===//
2//
Howard Hinnantc566dc32010-05-11 21:36:01 +00003// The LLVM Compiler Infrastructure
Howard Hinnantc51e1022010-05-11 19:42:16 +00004//
Howard Hinnantee11c312010-11-16 22:09:02 +00005// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantc51e1022010-05-11 19:42:16 +00007//
8//===----------------------------------------------------------------------===//
9
Howard Hinnantb5fffe82012-07-07 20:56:04 +000010#define _LIBCPP_BUILDING_MEMORY
Howard Hinnantc51e1022010-05-11 19:42:16 +000011#include "memory"
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +000012#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant9fa30202012-07-30 01:40:57 +000013#include "mutex"
Howard Hinnant58380d52012-07-30 17:13:21 +000014#include "thread"
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +000015#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +000016
17_LIBCPP_BEGIN_NAMESPACE_STD
18
19namespace
20{
21
22template <class T>
Howard Hinnant155c2af2010-05-24 17:49:41 +000023inline T
Howard Hinnant719bda32011-05-28 14:41:13 +000024increment(T& t) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +000025{
Howard Hinnant155c2af2010-05-24 17:49:41 +000026 return __sync_add_and_fetch(&t, 1);
Howard Hinnantc51e1022010-05-11 19:42:16 +000027}
28
29template <class T>
Howard Hinnant155c2af2010-05-24 17:49:41 +000030inline T
Howard Hinnant719bda32011-05-28 14:41:13 +000031decrement(T& t) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +000032{
Howard Hinnant155c2af2010-05-24 17:49:41 +000033 return __sync_add_and_fetch(&t, -1);
Howard Hinnantc51e1022010-05-11 19:42:16 +000034}
35
Howard Hinnantc51e1022010-05-11 19:42:16 +000036} // namespace
37
Howard Hinnantc51e1022010-05-11 19:42:16 +000038const allocator_arg_t allocator_arg = allocator_arg_t();
39
Howard Hinnant719bda32011-05-28 14:41:13 +000040bad_weak_ptr::~bad_weak_ptr() _NOEXCEPT {}
Howard Hinnantc51e1022010-05-11 19:42:16 +000041
42const char*
Howard Hinnant719bda32011-05-28 14:41:13 +000043bad_weak_ptr::what() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +000044{
45 return "bad_weak_ptr";
46}
47
48__shared_count::~__shared_count()
49{
50}
51
52void
Howard Hinnant719bda32011-05-28 14:41:13 +000053__shared_count::__add_shared() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +000054{
55 increment(__shared_owners_);
56}
57
Howard Hinnantca3b32a2010-11-16 21:33:17 +000058bool
Howard Hinnant719bda32011-05-28 14:41:13 +000059__shared_count::__release_shared() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +000060{
61 if (decrement(__shared_owners_) == -1)
Howard Hinnantca3b32a2010-11-16 21:33:17 +000062 {
Howard Hinnantc51e1022010-05-11 19:42:16 +000063 __on_zero_shared();
Howard Hinnantca3b32a2010-11-16 21:33:17 +000064 return true;
65 }
66 return false;
Howard Hinnantc51e1022010-05-11 19:42:16 +000067}
68
69__shared_weak_count::~__shared_weak_count()
70{
71}
72
73void
Howard Hinnant719bda32011-05-28 14:41:13 +000074__shared_weak_count::__add_shared() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +000075{
76 __shared_count::__add_shared();
Howard Hinnantc51e1022010-05-11 19:42:16 +000077}
78
79void
Howard Hinnant719bda32011-05-28 14:41:13 +000080__shared_weak_count::__add_weak() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +000081{
82 increment(__shared_weak_owners_);
83}
84
85void
Howard Hinnant719bda32011-05-28 14:41:13 +000086__shared_weak_count::__release_shared() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +000087{
Howard Hinnantca3b32a2010-11-16 21:33:17 +000088 if (__shared_count::__release_shared())
89 __release_weak();
Howard Hinnantc51e1022010-05-11 19:42:16 +000090}
91
92void
Howard Hinnant719bda32011-05-28 14:41:13 +000093__shared_weak_count::__release_weak() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +000094{
95 if (decrement(__shared_weak_owners_) == -1)
96 __on_zero_shared_weak();
97}
98
99__shared_weak_count*
Howard Hinnant719bda32011-05-28 14:41:13 +0000100__shared_weak_count::lock() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000101{
102 long object_owners = __shared_owners_;
103 while (object_owners != -1)
104 {
Howard Hinnant155c2af2010-05-24 17:49:41 +0000105 if (__sync_bool_compare_and_swap(&__shared_owners_,
106 object_owners,
107 object_owners+1))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000108 return this;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000109 object_owners = __shared_owners_;
110 }
111 return 0;
112}
113
Eric Fiselierf5d00122014-12-12 02:36:23 +0000114#if !defined(_LIBCPP_NO_RTTI) || !defined(_LIBCPP_BUILD_STATIC)
Howard Hinnant72f73582010-08-11 17:04:31 +0000115
Howard Hinnantc51e1022010-05-11 19:42:16 +0000116const void*
Howard Hinnant719bda32011-05-28 14:41:13 +0000117__shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000118{
119 return 0;
120}
121
Howard Hinnantffb308e2010-08-22 00:03:27 +0000122#endif // _LIBCPP_NO_RTTI
Howard Hinnant72f73582010-08-11 17:04:31 +0000123
Jonathan Roelofs067218a2014-09-05 20:28:44 +0000124#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
Howard Hinnantd48ef422012-08-19 15:13:16 +0000125
Howard Hinnant9fa30202012-07-30 01:40:57 +0000126static const std::size_t __sp_mut_count = 16;
Howard Hinnant5f779792013-03-16 00:17:53 +0000127static 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 Hinnant9fa30202012-07-30 01:40:57 +0000136
137_LIBCPP_CONSTEXPR __sp_mut::__sp_mut(void* p) _NOEXCEPT
Howard Hinnant49e145e2012-10-30 19:06:59 +0000138 : __lx(p)
Howard Hinnant9fa30202012-07-30 01:40:57 +0000139{
140}
141
142void
143__sp_mut::lock() _NOEXCEPT
144{
Howard Hinnant49e145e2012-10-30 19:06:59 +0000145 mutex& m = *static_cast<mutex*>(__lx);
Howard Hinnant58380d52012-07-30 17:13:21 +0000146 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 Hinnant9fa30202012-07-30 01:40:57 +0000156}
157
158void
159__sp_mut::unlock() _NOEXCEPT
160{
Howard Hinnant49e145e2012-10-30 19:06:59 +0000161 static_cast<mutex*>(__lx)->unlock();
Howard Hinnant9fa30202012-07-30 01:40:57 +0000162}
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 Roelofs39cb6bf2014-09-05 19:45:05 +0000177#endif // __has_feature(cxx_atomic) && !_LIBCPP_HAS_NO_THREADS
Howard Hinnant9fa30202012-07-30 01:40:57 +0000178
Howard Hinnantc51e1022010-05-11 19:42:16 +0000179void
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 Hinnant719bda32011-05-28 14:41:13 +0000195get_pointer_safety() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000196{
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 Sonnenbergerc7655a22014-01-04 17:43:00 +0000213 char* p2 = reinterpret_cast<char*>(reinterpret_cast<size_t>(p1 + (alignment - 1)) & -alignment);
Howard Hinnant28b24882011-12-01 20:21:04 +0000214 size_t d = static_cast<size_t>(p2 - p1);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000215 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