blob: 7caab26c42eb29d8421a23807d338a4200185b56 [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"
Howard Hinnantd77851e2012-07-30 01:40:5712#include "mutex"
Howard Hinnant3e519522010-05-11 19:42:1613
14_LIBCPP_BEGIN_NAMESPACE_STD
15
16namespace
17{
18
19template <class T>
Howard Hinnant128ba712010-05-24 17:49:4120inline T
Howard Hinnant3739fe72011-05-28 14:41:1321increment(T& t) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1622{
Howard Hinnant128ba712010-05-24 17:49:4123 return __sync_add_and_fetch(&t, 1);
Howard Hinnant3e519522010-05-11 19:42:1624}
25
26template <class T>
Howard Hinnant128ba712010-05-24 17:49:4127inline T
Howard Hinnant3739fe72011-05-28 14:41:1328decrement(T& t) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1629{
Howard Hinnant128ba712010-05-24 17:49:4130 return __sync_add_and_fetch(&t, -1);
Howard Hinnant3e519522010-05-11 19:42:1631}
32
Howard Hinnant3e519522010-05-11 19:42:1633} // namespace
34
Howard Hinnant3e519522010-05-11 19:42:1635const allocator_arg_t allocator_arg = allocator_arg_t();
36
Howard Hinnant3739fe72011-05-28 14:41:1337bad_weak_ptr::~bad_weak_ptr() _NOEXCEPT {}
Howard Hinnant3e519522010-05-11 19:42:1638
39const char*
Howard Hinnant3739fe72011-05-28 14:41:1340bad_weak_ptr::what() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1641{
42 return "bad_weak_ptr";
43}
44
45__shared_count::~__shared_count()
46{
47}
48
49void
Howard Hinnant3739fe72011-05-28 14:41:1350__shared_count::__add_shared() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1651{
52 increment(__shared_owners_);
53}
54
Howard Hinnant9b35c822010-11-16 21:33:1755bool
Howard Hinnant3739fe72011-05-28 14:41:1356__shared_count::__release_shared() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1657{
58 if (decrement(__shared_owners_) == -1)
Howard Hinnant9b35c822010-11-16 21:33:1759 {
Howard Hinnant3e519522010-05-11 19:42:1660 __on_zero_shared();
Howard Hinnant9b35c822010-11-16 21:33:1761 return true;
62 }
63 return false;
Howard Hinnant3e519522010-05-11 19:42:1664}
65
66__shared_weak_count::~__shared_weak_count()
67{
68}
69
70void
Howard Hinnant3739fe72011-05-28 14:41:1371__shared_weak_count::__add_shared() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1672{
73 __shared_count::__add_shared();
Howard Hinnant3e519522010-05-11 19:42:1674}
75
76void
Howard Hinnant3739fe72011-05-28 14:41:1377__shared_weak_count::__add_weak() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1678{
79 increment(__shared_weak_owners_);
80}
81
82void
Howard Hinnant3739fe72011-05-28 14:41:1383__shared_weak_count::__release_shared() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1684{
Howard Hinnant9b35c822010-11-16 21:33:1785 if (__shared_count::__release_shared())
86 __release_weak();
Howard Hinnant3e519522010-05-11 19:42:1687}
88
89void
Howard Hinnant3739fe72011-05-28 14:41:1390__shared_weak_count::__release_weak() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1691{
92 if (decrement(__shared_weak_owners_) == -1)
93 __on_zero_shared_weak();
94}
95
96__shared_weak_count*
Howard Hinnant3739fe72011-05-28 14:41:1397__shared_weak_count::lock() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1698{
99 long object_owners = __shared_owners_;
100 while (object_owners != -1)
101 {
Howard Hinnant128ba712010-05-24 17:49:41102 if (__sync_bool_compare_and_swap(&__shared_owners_,
103 object_owners,
104 object_owners+1))
Howard Hinnant3e519522010-05-11 19:42:16105 return this;
Howard Hinnant3e519522010-05-11 19:42:16106 object_owners = __shared_owners_;
107 }
108 return 0;
109}
110
Howard Hinnant54b409f2010-08-11 17:04:31111#ifndef _LIBCPP_NO_RTTI
112
Howard Hinnant3e519522010-05-11 19:42:16113const void*
Howard Hinnant3739fe72011-05-28 14:41:13114__shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16115{
116 return 0;
117}
118
Howard Hinnant940e2112010-08-22 00:03:27119#endif // _LIBCPP_NO_RTTI
Howard Hinnant54b409f2010-08-11 17:04:31120
Howard Hinnantd77851e2012-07-30 01:40:57121static const std::size_t __sp_mut_count = 16;
122static mutex mut_back[__sp_mut_count];
123
124_LIBCPP_CONSTEXPR __sp_mut::__sp_mut(void* p) _NOEXCEPT
125 : _(p)
126{
127}
128
129void
130__sp_mut::lock() _NOEXCEPT
131{
132 reinterpret_cast<mutex*>(_)->lock();
133}
134
135void
136__sp_mut::unlock() _NOEXCEPT
137{
138 reinterpret_cast<mutex*>(_)->unlock();
139}
140
141__sp_mut&
142__get_sp_mut(const void* p)
143{
144 static __sp_mut muts[__sp_mut_count]
145 {
146 &mut_back[ 0], &mut_back[ 1], &mut_back[ 2], &mut_back[ 3],
147 &mut_back[ 4], &mut_back[ 5], &mut_back[ 6], &mut_back[ 7],
148 &mut_back[ 8], &mut_back[ 9], &mut_back[10], &mut_back[11],
149 &mut_back[12], &mut_back[13], &mut_back[14], &mut_back[15]
150 };
151 return muts[hash<const void*>()(p) & (__sp_mut_count-1)];
152}
153
154
Howard Hinnant3e519522010-05-11 19:42:16155void
156declare_reachable(void*)
157{
158}
159
160void
161declare_no_pointers(char*, size_t)
162{
163}
164
165void
166undeclare_no_pointers(char*, size_t)
167{
168}
169
170pointer_safety
Howard Hinnant3739fe72011-05-28 14:41:13171get_pointer_safety() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16172{
173 return pointer_safety::relaxed;
174}
175
176void*
177__undeclare_reachable(void* p)
178{
179 return p;
180}
181
182void*
183align(size_t alignment, size_t size, void*& ptr, size_t& space)
184{
185 void* r = nullptr;
186 if (size <= space)
187 {
188 char* p1 = static_cast<char*>(ptr);
189 char* p2 = (char*)((size_t)(p1 + (alignment - 1)) & -alignment);
Howard Hinnantc2063662011-12-01 20:21:04190 size_t d = static_cast<size_t>(p2 - p1);
Howard Hinnant3e519522010-05-11 19:42:16191 if (d <= space - size)
192 {
193 r = p2;
194 ptr = r;
195 space -= d;
196 }
197 }
198 return r;
199}
200
201_LIBCPP_END_NAMESPACE_STD