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 10241903Sdim#define _LIBCPP_BUILDING_MEMORY 11227825Stheraven#include "memory" 12278724Sdim#ifndef _LIBCPP_HAS_NO_THREADS 13241903Sdim#include "mutex" 14241903Sdim#include "thread" 15278724Sdim#endif 16227825Stheraven 17227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD 18227825Stheraven 19227825Stheravennamespace 20227825Stheraven{ 21227825Stheraven 22227825Stheraventemplate <class T> 23227825Stheraveninline T 24227825Stheravenincrement(T& t) _NOEXCEPT 25227825Stheraven{ 26227825Stheraven return __sync_add_and_fetch(&t, 1); 27227825Stheraven} 28227825Stheraven 29227825Stheraventemplate <class T> 30227825Stheraveninline T 31227825Stheravendecrement(T& t) _NOEXCEPT 32227825Stheraven{ 33227825Stheraven return __sync_add_and_fetch(&t, -1); 34227825Stheraven} 35227825Stheraven 36227825Stheraven} // namespace 37227825Stheraven 38227825Stheravenconst allocator_arg_t allocator_arg = allocator_arg_t(); 39227825Stheraven 40227825Stheravenbad_weak_ptr::~bad_weak_ptr() _NOEXCEPT {} 41227825Stheraven 42227825Stheravenconst char* 43227825Stheravenbad_weak_ptr::what() const _NOEXCEPT 44227825Stheraven{ 45227825Stheraven return "bad_weak_ptr"; 46227825Stheraven} 47227825Stheraven 48227825Stheraven__shared_count::~__shared_count() 49227825Stheraven{ 50227825Stheraven} 51227825Stheraven 52227825Stheravenvoid 53227825Stheraven__shared_count::__add_shared() _NOEXCEPT 54227825Stheraven{ 55227825Stheraven increment(__shared_owners_); 56227825Stheraven} 57227825Stheraven 58227825Stheravenbool 59227825Stheraven__shared_count::__release_shared() _NOEXCEPT 60227825Stheraven{ 61227825Stheraven if (decrement(__shared_owners_) == -1) 62227825Stheraven { 63227825Stheraven __on_zero_shared(); 64227825Stheraven return true; 65227825Stheraven } 66227825Stheraven return false; 67227825Stheraven} 68227825Stheraven 69227825Stheraven__shared_weak_count::~__shared_weak_count() 70227825Stheraven{ 71227825Stheraven} 72227825Stheraven 73227825Stheravenvoid 74227825Stheraven__shared_weak_count::__add_shared() _NOEXCEPT 75227825Stheraven{ 76227825Stheraven __shared_count::__add_shared(); 77227825Stheraven} 78227825Stheraven 79227825Stheravenvoid 80227825Stheraven__shared_weak_count::__add_weak() _NOEXCEPT 81227825Stheraven{ 82227825Stheraven increment(__shared_weak_owners_); 83227825Stheraven} 84227825Stheraven 85227825Stheravenvoid 86227825Stheraven__shared_weak_count::__release_shared() _NOEXCEPT 87227825Stheraven{ 88227825Stheraven if (__shared_count::__release_shared()) 89227825Stheraven __release_weak(); 90227825Stheraven} 91227825Stheraven 92227825Stheravenvoid 93227825Stheraven__shared_weak_count::__release_weak() _NOEXCEPT 94227825Stheraven{ 95227825Stheraven if (decrement(__shared_weak_owners_) == -1) 96227825Stheraven __on_zero_shared_weak(); 97227825Stheraven} 98227825Stheraven 99227825Stheraven__shared_weak_count* 100227825Stheraven__shared_weak_count::lock() _NOEXCEPT 101227825Stheraven{ 102227825Stheraven long object_owners = __shared_owners_; 103227825Stheraven while (object_owners != -1) 104227825Stheraven { 105227825Stheraven if (__sync_bool_compare_and_swap(&__shared_owners_, 106227825Stheraven object_owners, 107227825Stheraven object_owners+1)) 108227825Stheraven return this; 109227825Stheraven object_owners = __shared_owners_; 110227825Stheraven } 111227825Stheraven return 0; 112227825Stheraven} 113227825Stheraven 114278724Sdim#if !defined(_LIBCPP_NO_RTTI) || !defined(_LIBCPP_BUILD_STATIC) 115227825Stheraven 116227825Stheravenconst void* 117227825Stheraven__shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT 118227825Stheraven{ 119227825Stheraven return 0; 120227825Stheraven} 121227825Stheraven 122227825Stheraven#endif // _LIBCPP_NO_RTTI 123227825Stheraven 124278724Sdim#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS) 125241903Sdim 126241903Sdimstatic const std::size_t __sp_mut_count = 16; 127249998Sdimstatic pthread_mutex_t mut_back_imp[__sp_mut_count] = 128249998Sdim{ 129249998Sdim PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 130249998Sdim PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 131249998Sdim PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 132249998Sdim PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER 133249998Sdim}; 134241903Sdim 135249998Sdimstatic mutex* mut_back = reinterpret_cast<std::mutex*>(mut_back_imp); 136249998Sdim 137241903Sdim_LIBCPP_CONSTEXPR __sp_mut::__sp_mut(void* p) _NOEXCEPT 138242945Stheraven : __lx(p) 139241903Sdim{ 140241903Sdim} 141241903Sdim 142227825Stheravenvoid 143241903Sdim__sp_mut::lock() _NOEXCEPT 144241903Sdim{ 145242945Stheraven mutex& m = *static_cast<mutex*>(__lx); 146241903Sdim unsigned count = 0; 147241903Sdim while (!m.try_lock()) 148241903Sdim { 149241903Sdim if (++count > 16) 150241903Sdim { 151241903Sdim m.lock(); 152241903Sdim break; 153241903Sdim } 154241903Sdim this_thread::yield(); 155241903Sdim } 156241903Sdim} 157241903Sdim 158241903Sdimvoid 159241903Sdim__sp_mut::unlock() _NOEXCEPT 160241903Sdim{ 161242945Stheraven static_cast<mutex*>(__lx)->unlock(); 162241903Sdim} 163241903Sdim 164241903Sdim__sp_mut& 165241903Sdim__get_sp_mut(const void* p) 166241903Sdim{ 167241903Sdim static __sp_mut muts[__sp_mut_count] 168241903Sdim { 169241903Sdim &mut_back[ 0], &mut_back[ 1], &mut_back[ 2], &mut_back[ 3], 170241903Sdim &mut_back[ 4], &mut_back[ 5], &mut_back[ 6], &mut_back[ 7], 171241903Sdim &mut_back[ 8], &mut_back[ 9], &mut_back[10], &mut_back[11], 172241903Sdim &mut_back[12], &mut_back[13], &mut_back[14], &mut_back[15] 173241903Sdim }; 174241903Sdim return muts[hash<const void*>()(p) & (__sp_mut_count-1)]; 175241903Sdim} 176241903Sdim 177278724Sdim#endif // __has_feature(cxx_atomic) && !_LIBCPP_HAS_NO_THREADS 178241903Sdim 179241903Sdimvoid 180227825Stheravendeclare_reachable(void*) 181227825Stheraven{ 182227825Stheraven} 183227825Stheraven 184227825Stheravenvoid 185227825Stheravendeclare_no_pointers(char*, size_t) 186227825Stheraven{ 187227825Stheraven} 188227825Stheraven 189227825Stheravenvoid 190227825Stheravenundeclare_no_pointers(char*, size_t) 191227825Stheraven{ 192227825Stheraven} 193227825Stheraven 194227825Stheravenpointer_safety 195227825Stheravenget_pointer_safety() _NOEXCEPT 196227825Stheraven{ 197227825Stheraven return pointer_safety::relaxed; 198227825Stheraven} 199227825Stheraven 200227825Stheravenvoid* 201227825Stheraven__undeclare_reachable(void* p) 202227825Stheraven{ 203227825Stheraven return p; 204227825Stheraven} 205227825Stheraven 206227825Stheravenvoid* 207227825Stheravenalign(size_t alignment, size_t size, void*& ptr, size_t& space) 208227825Stheraven{ 209227825Stheraven void* r = nullptr; 210227825Stheraven if (size <= space) 211227825Stheraven { 212227825Stheraven char* p1 = static_cast<char*>(ptr); 213278724Sdim char* p2 = reinterpret_cast<char*>(reinterpret_cast<size_t>(p1 + (alignment - 1)) & -alignment); 214232950Stheraven size_t d = static_cast<size_t>(p2 - p1); 215227825Stheraven if (d <= space - size) 216227825Stheraven { 217227825Stheraven r = p2; 218227825Stheraven ptr = r; 219227825Stheraven space -= d; 220227825Stheraven } 221227825Stheraven } 222227825Stheraven return r; 223227825Stheraven} 224227825Stheraven 225227825Stheraven_LIBCPP_END_NAMESPACE_STD 226