memory.cpp revision 278724
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#ifndef _LIBCPP_HAS_NO_THREADS 13#include "mutex" 14#include "thread" 15#endif 16 17_LIBCPP_BEGIN_NAMESPACE_STD 18 19namespace 20{ 21 22template <class T> 23inline T 24increment(T& t) _NOEXCEPT 25{ 26 return __sync_add_and_fetch(&t, 1); 27} 28 29template <class T> 30inline T 31decrement(T& t) _NOEXCEPT 32{ 33 return __sync_add_and_fetch(&t, -1); 34} 35 36} // namespace 37 38const allocator_arg_t allocator_arg = allocator_arg_t(); 39 40bad_weak_ptr::~bad_weak_ptr() _NOEXCEPT {} 41 42const char* 43bad_weak_ptr::what() const _NOEXCEPT 44{ 45 return "bad_weak_ptr"; 46} 47 48__shared_count::~__shared_count() 49{ 50} 51 52void 53__shared_count::__add_shared() _NOEXCEPT 54{ 55 increment(__shared_owners_); 56} 57 58bool 59__shared_count::__release_shared() _NOEXCEPT 60{ 61 if (decrement(__shared_owners_) == -1) 62 { 63 __on_zero_shared(); 64 return true; 65 } 66 return false; 67} 68 69__shared_weak_count::~__shared_weak_count() 70{ 71} 72 73void 74__shared_weak_count::__add_shared() _NOEXCEPT 75{ 76 __shared_count::__add_shared(); 77} 78 79void 80__shared_weak_count::__add_weak() _NOEXCEPT 81{ 82 increment(__shared_weak_owners_); 83} 84 85void 86__shared_weak_count::__release_shared() _NOEXCEPT 87{ 88 if (__shared_count::__release_shared()) 89 __release_weak(); 90} 91 92void 93__shared_weak_count::__release_weak() _NOEXCEPT 94{ 95 if (decrement(__shared_weak_owners_) == -1) 96 __on_zero_shared_weak(); 97} 98 99__shared_weak_count* 100__shared_weak_count::lock() _NOEXCEPT 101{ 102 long object_owners = __shared_owners_; 103 while (object_owners != -1) 104 { 105 if (__sync_bool_compare_and_swap(&__shared_owners_, 106 object_owners, 107 object_owners+1)) 108 return this; 109 object_owners = __shared_owners_; 110 } 111 return 0; 112} 113 114#if !defined(_LIBCPP_NO_RTTI) || !defined(_LIBCPP_BUILD_STATIC) 115 116const void* 117__shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT 118{ 119 return 0; 120} 121 122#endif // _LIBCPP_NO_RTTI 123 124#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS) 125 126static const std::size_t __sp_mut_count = 16; 127static 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); 136 137_LIBCPP_CONSTEXPR __sp_mut::__sp_mut(void* p) _NOEXCEPT 138 : __lx(p) 139{ 140} 141 142void 143__sp_mut::lock() _NOEXCEPT 144{ 145 mutex& m = *static_cast<mutex*>(__lx); 146 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 } 156} 157 158void 159__sp_mut::unlock() _NOEXCEPT 160{ 161 static_cast<mutex*>(__lx)->unlock(); 162} 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 177#endif // __has_feature(cxx_atomic) && !_LIBCPP_HAS_NO_THREADS 178 179void 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 195get_pointer_safety() _NOEXCEPT 196{ 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); 213 char* p2 = reinterpret_cast<char*>(reinterpret_cast<size_t>(p1 + (alignment - 1)) & -alignment); 214 size_t d = static_cast<size_t>(p2 - p1); 215 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 226