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