memory.cpp revision 242945
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 17namespace 18{ 19 20template <class T> 21inline T 22increment(T& t) _NOEXCEPT 23{ 24 return __sync_add_and_fetch(&t, 1); 25} 26 27template <class T> 28inline T 29decrement(T& t) _NOEXCEPT 30{ 31 return __sync_add_and_fetch(&t, -1); 32} 33 34} // namespace 35 36const allocator_arg_t allocator_arg = allocator_arg_t(); 37 38bad_weak_ptr::~bad_weak_ptr() _NOEXCEPT {} 39 40const char* 41bad_weak_ptr::what() const _NOEXCEPT 42{ 43 return "bad_weak_ptr"; 44} 45 46__shared_count::~__shared_count() 47{ 48} 49 50void 51__shared_count::__add_shared() _NOEXCEPT 52{ 53 increment(__shared_owners_); 54} 55 56bool 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 71void 72__shared_weak_count::__add_shared() _NOEXCEPT 73{ 74 __shared_count::__add_shared(); 75} 76 77void 78__shared_weak_count::__add_weak() _NOEXCEPT 79{ 80 increment(__shared_weak_owners_); 81} 82 83void 84__shared_weak_count::__release_shared() _NOEXCEPT 85{ 86 if (__shared_count::__release_shared()) 87 __release_weak(); 88} 89 90void 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 114const 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 124static const std::size_t __sp_mut_count = 16; 125static mutex mut_back[__sp_mut_count]; 126 127_LIBCPP_CONSTEXPR __sp_mut::__sp_mut(void* p) _NOEXCEPT 128 : __lx(p) 129{ 130} 131 132void 133__sp_mut::lock() _NOEXCEPT 134{ 135 mutex& m = *static_cast<mutex*>(__lx); 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 148void 149__sp_mut::unlock() _NOEXCEPT 150{ 151 static_cast<mutex*>(__lx)->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 169void 170declare_reachable(void*) 171{ 172} 173 174void 175declare_no_pointers(char*, size_t) 176{ 177} 178 179void 180undeclare_no_pointers(char*, size_t) 181{ 182} 183 184pointer_safety 185get_pointer_safety() _NOEXCEPT 186{ 187 return pointer_safety::relaxed; 188} 189 190void* 191__undeclare_reachable(void* p) 192{ 193 return p; 194} 195 196void* 197align(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