1227825Stheraven//===------------------------ memory.cpp ----------------------------------===// 2227825Stheraven// 3227825Stheraven// The LLVM Compiler Infrastructure 4227825Stheraven// 5227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open 6227825Stheraven// Source Licenses. See LICENSE.TXT for details. 7227825Stheraven// 8227825Stheraven//===----------------------------------------------------------------------===// 9227825Stheraven 10243376Sdim#define _LIBCPP_BUILDING_MEMORY 11227825Stheraven#include "memory" 12243376Sdim#include "mutex" 13243376Sdim#include "thread" 14227825Stheraven 15227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD 16227825Stheraven 17227825Stheravennamespace 18227825Stheraven{ 19227825Stheraven 20227825Stheraventemplate <class T> 21227825Stheraveninline T 22227825Stheravenincrement(T& t) _NOEXCEPT 23227825Stheraven{ 24227825Stheraven return __sync_add_and_fetch(&t, 1); 25227825Stheraven} 26227825Stheraven 27227825Stheraventemplate <class T> 28227825Stheraveninline T 29227825Stheravendecrement(T& t) _NOEXCEPT 30227825Stheraven{ 31227825Stheraven return __sync_add_and_fetch(&t, -1); 32227825Stheraven} 33227825Stheraven 34227825Stheraven} // namespace 35227825Stheraven 36227825Stheravenconst allocator_arg_t allocator_arg = allocator_arg_t(); 37227825Stheraven 38227825Stheravenbad_weak_ptr::~bad_weak_ptr() _NOEXCEPT {} 39227825Stheraven 40227825Stheravenconst char* 41227825Stheravenbad_weak_ptr::what() const _NOEXCEPT 42227825Stheraven{ 43227825Stheraven return "bad_weak_ptr"; 44227825Stheraven} 45227825Stheraven 46227825Stheraven__shared_count::~__shared_count() 47227825Stheraven{ 48227825Stheraven} 49227825Stheraven 50227825Stheravenvoid 51227825Stheraven__shared_count::__add_shared() _NOEXCEPT 52227825Stheraven{ 53227825Stheraven increment(__shared_owners_); 54227825Stheraven} 55227825Stheraven 56227825Stheravenbool 57227825Stheraven__shared_count::__release_shared() _NOEXCEPT 58227825Stheraven{ 59227825Stheraven if (decrement(__shared_owners_) == -1) 60227825Stheraven { 61227825Stheraven __on_zero_shared(); 62227825Stheraven return true; 63227825Stheraven } 64227825Stheraven return false; 65227825Stheraven} 66227825Stheraven 67227825Stheraven__shared_weak_count::~__shared_weak_count() 68227825Stheraven{ 69227825Stheraven} 70227825Stheraven 71227825Stheravenvoid 72227825Stheraven__shared_weak_count::__add_shared() _NOEXCEPT 73227825Stheraven{ 74227825Stheraven __shared_count::__add_shared(); 75227825Stheraven} 76227825Stheraven 77227825Stheravenvoid 78227825Stheraven__shared_weak_count::__add_weak() _NOEXCEPT 79227825Stheraven{ 80227825Stheraven increment(__shared_weak_owners_); 81227825Stheraven} 82227825Stheraven 83227825Stheravenvoid 84227825Stheraven__shared_weak_count::__release_shared() _NOEXCEPT 85227825Stheraven{ 86227825Stheraven if (__shared_count::__release_shared()) 87227825Stheraven __release_weak(); 88227825Stheraven} 89227825Stheraven 90227825Stheravenvoid 91227825Stheraven__shared_weak_count::__release_weak() _NOEXCEPT 92227825Stheraven{ 93227825Stheraven if (decrement(__shared_weak_owners_) == -1) 94227825Stheraven __on_zero_shared_weak(); 95227825Stheraven} 96227825Stheraven 97227825Stheraven__shared_weak_count* 98227825Stheraven__shared_weak_count::lock() _NOEXCEPT 99227825Stheraven{ 100227825Stheraven long object_owners = __shared_owners_; 101227825Stheraven while (object_owners != -1) 102227825Stheraven { 103227825Stheraven if (__sync_bool_compare_and_swap(&__shared_owners_, 104227825Stheraven object_owners, 105227825Stheraven object_owners+1)) 106227825Stheraven return this; 107227825Stheraven object_owners = __shared_owners_; 108227825Stheraven } 109227825Stheraven return 0; 110227825Stheraven} 111227825Stheraven 112227825Stheraven#ifndef _LIBCPP_NO_RTTI 113227825Stheraven 114227825Stheravenconst void* 115227825Stheraven__shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT 116227825Stheraven{ 117227825Stheraven return 0; 118227825Stheraven} 119227825Stheraven 120227825Stheraven#endif // _LIBCPP_NO_RTTI 121227825Stheraven 122243376Sdim#if __has_feature(cxx_atomic) 123243376Sdim 124243376Sdimstatic const std::size_t __sp_mut_count = 16; 125250514Sdimstatic pthread_mutex_t mut_back_imp[__sp_mut_count] = 126250514Sdim{ 127250514Sdim PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 128250514Sdim PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 129250514Sdim PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 130250514Sdim PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER 131250514Sdim}; 132243376Sdim 133250514Sdimstatic mutex* mut_back = reinterpret_cast<std::mutex*>(mut_back_imp); 134250514Sdim 135243376Sdim_LIBCPP_CONSTEXPR __sp_mut::__sp_mut(void* p) _NOEXCEPT 136243683Sdim : __lx(p) 137243376Sdim{ 138243376Sdim} 139243376Sdim 140227825Stheravenvoid 141243376Sdim__sp_mut::lock() _NOEXCEPT 142243376Sdim{ 143243683Sdim mutex& m = *static_cast<mutex*>(__lx); 144243376Sdim unsigned count = 0; 145243376Sdim while (!m.try_lock()) 146243376Sdim { 147243376Sdim if (++count > 16) 148243376Sdim { 149243376Sdim m.lock(); 150243376Sdim break; 151243376Sdim } 152243376Sdim this_thread::yield(); 153243376Sdim } 154243376Sdim} 155243376Sdim 156243376Sdimvoid 157243376Sdim__sp_mut::unlock() _NOEXCEPT 158243376Sdim{ 159243683Sdim static_cast<mutex*>(__lx)->unlock(); 160243376Sdim} 161243376Sdim 162243376Sdim__sp_mut& 163243376Sdim__get_sp_mut(const void* p) 164243376Sdim{ 165243376Sdim static __sp_mut muts[__sp_mut_count] 166243376Sdim { 167243376Sdim &mut_back[ 0], &mut_back[ 1], &mut_back[ 2], &mut_back[ 3], 168243376Sdim &mut_back[ 4], &mut_back[ 5], &mut_back[ 6], &mut_back[ 7], 169243376Sdim &mut_back[ 8], &mut_back[ 9], &mut_back[10], &mut_back[11], 170243376Sdim &mut_back[12], &mut_back[13], &mut_back[14], &mut_back[15] 171243376Sdim }; 172243376Sdim return muts[hash<const void*>()(p) & (__sp_mut_count-1)]; 173243376Sdim} 174243376Sdim 175243376Sdim#endif // __has_feature(cxx_atomic) 176243376Sdim 177243376Sdimvoid 178227825Stheravendeclare_reachable(void*) 179227825Stheraven{ 180227825Stheraven} 181227825Stheraven 182227825Stheravenvoid 183227825Stheravendeclare_no_pointers(char*, size_t) 184227825Stheraven{ 185227825Stheraven} 186227825Stheraven 187227825Stheravenvoid 188227825Stheravenundeclare_no_pointers(char*, size_t) 189227825Stheraven{ 190227825Stheraven} 191227825Stheraven 192227825Stheravenpointer_safety 193227825Stheravenget_pointer_safety() _NOEXCEPT 194227825Stheraven{ 195227825Stheraven return pointer_safety::relaxed; 196227825Stheraven} 197227825Stheraven 198227825Stheravenvoid* 199227825Stheraven__undeclare_reachable(void* p) 200227825Stheraven{ 201227825Stheraven return p; 202227825Stheraven} 203227825Stheraven 204227825Stheravenvoid* 205227825Stheravenalign(size_t alignment, size_t size, void*& ptr, size_t& space) 206227825Stheraven{ 207227825Stheraven void* r = nullptr; 208227825Stheraven if (size <= space) 209227825Stheraven { 210227825Stheraven char* p1 = static_cast<char*>(ptr); 211227825Stheraven char* p2 = (char*)((size_t)(p1 + (alignment - 1)) & -alignment); 212232950Stheraven size_t d = static_cast<size_t>(p2 - p1); 213227825Stheraven if (d <= space - size) 214227825Stheraven { 215227825Stheraven r = p2; 216227825Stheraven ptr = r; 217227825Stheraven space -= d; 218227825Stheraven } 219227825Stheraven } 220227825Stheraven return r; 221227825Stheraven} 222227825Stheraven 223227825Stheraven_LIBCPP_END_NAMESPACE_STD 224