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 17 namespace 18 { 19 20 template <class T> 21 inline T 22 increment(T& t) _NOEXCEPT 23 { 24 return __sync_add_and_fetch(&t, 1); 25 } 26 27 template <class T> 28 inline T 29 decrement(T& t) _NOEXCEPT 30 { 31 return __sync_add_and_fetch(&t, -1); 32 } 33 34 } // namespace 35 36 const allocator_arg_t allocator_arg = allocator_arg_t(); 37 38 bad_weak_ptr::~bad_weak_ptr() _NOEXCEPT {} 39 40 const char* 41 bad_weak_ptr::what() const _NOEXCEPT 42 { 43 return "bad_weak_ptr"; 44 } 45 46 __shared_count::~__shared_count() 47 { 48 } 49 50 void 51 __shared_count::__add_shared() _NOEXCEPT 52 { 53 increment(__shared_owners_); 54 } 55 56 bool 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 71 void 72 __shared_weak_count::__add_shared() _NOEXCEPT 73 { 74 __shared_count::__add_shared(); 75 } 76 77 void 78 __shared_weak_count::__add_weak() _NOEXCEPT 79 { 80 increment(__shared_weak_owners_); 81 } 82 83 void 84 __shared_weak_count::__release_shared() _NOEXCEPT 85 { 86 if (__shared_count::__release_shared()) 87 __release_weak(); 88 } 89 90 void 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 114 const 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 static const std::size_t __sp_mut_count = 16; 123 static mutex mut_back[__sp_mut_count]; 124 125 _LIBCPP_CONSTEXPR __sp_mut::__sp_mut(void* p) _NOEXCEPT 126 : _(p) 127 { 128 } 129 130 void 131 __sp_mut::lock() _NOEXCEPT 132 { 133 mutex& m = *static_cast<mutex*>(_); 134 unsigned count = 0; 135 while (!m.try_lock()) 136 { 137 if (++count > 16) 138 { 139 m.lock(); 140 break; 141 } 142 this_thread::yield(); 143 } 144 } 145 146 void 147 __sp_mut::unlock() _NOEXCEPT 148 { 149 static_cast<mutex*>(_)->unlock(); 150 } 151 152 __sp_mut& 153 __get_sp_mut(const void* p) 154 { 155 static __sp_mut muts[__sp_mut_count] 156 { 157 &mut_back[ 0], &mut_back[ 1], &mut_back[ 2], &mut_back[ 3], 158 &mut_back[ 4], &mut_back[ 5], &mut_back[ 6], &mut_back[ 7], 159 &mut_back[ 8], &mut_back[ 9], &mut_back[10], &mut_back[11], 160 &mut_back[12], &mut_back[13], &mut_back[14], &mut_back[15] 161 }; 162 return muts[hash<const void*>()(p) & (__sp_mut_count-1)]; 163 } 164 165 166 void 167 declare_reachable(void*) 168 { 169 } 170 171 void 172 declare_no_pointers(char*, size_t) 173 { 174 } 175 176 void 177 undeclare_no_pointers(char*, size_t) 178 { 179 } 180 181 pointer_safety 182 get_pointer_safety() _NOEXCEPT 183 { 184 return pointer_safety::relaxed; 185 } 186 187 void* 188 __undeclare_reachable(void* p) 189 { 190 return p; 191 } 192 193 void* 194 align(size_t alignment, size_t size, void*& ptr, size_t& space) 195 { 196 void* r = nullptr; 197 if (size <= space) 198 { 199 char* p1 = static_cast<char*>(ptr); 200 char* p2 = (char*)((size_t)(p1 + (alignment - 1)) & -alignment); 201 size_t d = static_cast<size_t>(p2 - p1); 202 if (d <= space - size) 203 { 204 r = p2; 205 ptr = r; 206 space -= d; 207 } 208 } 209 return r; 210 } 211 212 _LIBCPP_END_NAMESPACE_STD 213