1 //===------------------------ memory.cpp ----------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #define _LIBCPP_BUILDING_MEMORY 11 #include "memory" 12 #include "mutex" 13 #include "thread" 14 15 _LIBCPP_BEGIN_NAMESPACE_STD 16 17 namespace 18 { 19 20 template <class T> 21 inline T 22 increment(T& t) _NOEXCEPT 23 { 24 return __sync_add_and_fetch(&t, 1); 25 } 26 27 template <class T> 28 inline T 29 decrement(T& t) _NOEXCEPT 30 { 31 return __sync_add_and_fetch(&t, -1); 32 } 33 34 } // namespace 35 36 const allocator_arg_t allocator_arg = allocator_arg_t(); 37 38 bad_weak_ptr::~bad_weak_ptr() _NOEXCEPT {} 39 40 const char* 41 bad_weak_ptr::what() const _NOEXCEPT 42 { 43 return "bad_weak_ptr"; 44 } 45 46 __shared_count::~__shared_count() 47 { 48 } 49 50 void 51 __shared_count::__add_shared() _NOEXCEPT 52 { 53 increment(__shared_owners_); 54 } 55 56 bool 57 __shared_count::__release_shared() _NOEXCEPT 58 { 59 if (decrement(__shared_owners_) == -1) 60 { 61 __on_zero_shared(); 62 return true; 63 } 64 return false; 65 } 66 67 __shared_weak_count::~__shared_weak_count() 68 { 69 } 70 71 void 72 __shared_weak_count::__add_shared() _NOEXCEPT 73 { 74 __shared_count::__add_shared(); 75 } 76 77 void 78 __shared_weak_count::__add_weak() _NOEXCEPT 79 { 80 increment(__shared_weak_owners_); 81 } 82 83 void 84 __shared_weak_count::__release_shared() _NOEXCEPT 85 { 86 if (__shared_count::__release_shared()) 87 __release_weak(); 88 } 89 90 void 91 __shared_weak_count::__release_weak() _NOEXCEPT 92 { 93 if (decrement(__shared_weak_owners_) == -1) 94 __on_zero_shared_weak(); 95 } 96 97 __shared_weak_count* 98 __shared_weak_count::lock() _NOEXCEPT 99 { 100 long object_owners = __shared_owners_; 101 while (object_owners != -1) 102 { 103 if (__sync_bool_compare_and_swap(&__shared_owners_, 104 object_owners, 105 object_owners+1)) 106 return this; 107 object_owners = __shared_owners_; 108 } 109 return 0; 110 } 111 112 #ifndef _LIBCPP_NO_RTTI 113 114 const void* 115 __shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT 116 { 117 return 0; 118 } 119 120 #endif // _LIBCPP_NO_RTTI 121 122 #if __has_feature(cxx_atomic) 123 124 static const std::size_t __sp_mut_count = 16; 125 static mutex mut_back[__sp_mut_count]; 126 127 _LIBCPP_CONSTEXPR __sp_mut::__sp_mut(void* p) _NOEXCEPT 128 : _(p) 129 { 130 } 131 132 void 133 __sp_mut::lock() _NOEXCEPT 134 { 135 mutex& m = *static_cast<mutex*>(_); 136 unsigned count = 0; 137 while (!m.try_lock()) 138 { 139 if (++count > 16) 140 { 141 m.lock(); 142 break; 143 } 144 this_thread::yield(); 145 } 146 } 147 148 void 149 __sp_mut::unlock() _NOEXCEPT 150 { 151 static_cast<mutex*>(_)->unlock(); 152 } 153 154 __sp_mut& 155 __get_sp_mut(const void* p) 156 { 157 static __sp_mut muts[__sp_mut_count] 158 { 159 &mut_back[ 0], &mut_back[ 1], &mut_back[ 2], &mut_back[ 3], 160 &mut_back[ 4], &mut_back[ 5], &mut_back[ 6], &mut_back[ 7], 161 &mut_back[ 8], &mut_back[ 9], &mut_back[10], &mut_back[11], 162 &mut_back[12], &mut_back[13], &mut_back[14], &mut_back[15] 163 }; 164 return muts[hash<const void*>()(p) & (__sp_mut_count-1)]; 165 } 166 167 #endif // __has_feature(cxx_atomic) 168 169 void 170 declare_reachable(void*) 171 { 172 } 173 174 void 175 declare_no_pointers(char*, size_t) 176 { 177 } 178 179 void 180 undeclare_no_pointers(char*, size_t) 181 { 182 } 183 184 pointer_safety 185 get_pointer_safety() _NOEXCEPT 186 { 187 return pointer_safety::relaxed; 188 } 189 190 void* 191 __undeclare_reachable(void* p) 192 { 193 return p; 194 } 195 196 void* 197 align(size_t alignment, size_t size, void*& ptr, size_t& space) 198 { 199 void* r = nullptr; 200 if (size <= space) 201 { 202 char* p1 = static_cast<char*>(ptr); 203 char* p2 = (char*)((size_t)(p1 + (alignment - 1)) & -alignment); 204 size_t d = static_cast<size_t>(p2 - p1); 205 if (d <= space - size) 206 { 207 r = p2; 208 ptr = r; 209 space -= d; 210 } 211 } 212 return r; 213 } 214 215 _LIBCPP_END_NAMESPACE_STD 216