148fb7bfaSmrg // Support for pointer abstractions -*- C++ -*- 248fb7bfaSmrg 3*b1e83836Smrg // Copyright (C) 2011-2022 Free Software Foundation, Inc. 448fb7bfaSmrg // 548fb7bfaSmrg // This file is part of the GNU ISO C++ Library. This library is free 648fb7bfaSmrg // software; you can redistribute it and/or modify it under the 748fb7bfaSmrg // terms of the GNU General Public License as published by the 848fb7bfaSmrg // Free Software Foundation; either version 3, or (at your option) 948fb7bfaSmrg // any later version. 1048fb7bfaSmrg 1148fb7bfaSmrg // This library is distributed in the hope that it will be useful, 1248fb7bfaSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 1348fb7bfaSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1448fb7bfaSmrg // GNU General Public License for more details. 1548fb7bfaSmrg 1648fb7bfaSmrg // Under Section 7 of GPL version 3, you are granted additional 1748fb7bfaSmrg // permissions described in the GCC Runtime Library Exception, version 1848fb7bfaSmrg // 3.1, as published by the Free Software Foundation. 1948fb7bfaSmrg 2048fb7bfaSmrg // You should have received a copy of the GNU General Public License and 2148fb7bfaSmrg // a copy of the GCC Runtime Library Exception along with this program; 2248fb7bfaSmrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2348fb7bfaSmrg // <http://www.gnu.org/licenses/>. 2448fb7bfaSmrg 2548fb7bfaSmrg #include <memory> 2648fb7bfaSmrg 27b17d1066Smrg #include "mutex_pool.h" 28b17d1066Smrg 29b17d1066Smrg namespace __gnu_internal _GLIBCXX_VISIBILITY(hidden) 30b17d1066Smrg { 31b17d1066Smrg /* Returns different instances of __mutex depending on the passed index 32b17d1066Smrg * in order to limit contention. 33b17d1066Smrg */ 34b17d1066Smrg __gnu_cxx::__mutex& get_mutex(unsigned char i)35b17d1066Smrg get_mutex(unsigned char i) 36b17d1066Smrg { 37fb8a8121Smrg // increase alignment to put each lock on a separate cache line 38fb8a8121Smrg struct alignas(64) M : __gnu_cxx::__mutex { }; 39fb8a8121Smrg static M m[mask + 1]; 40b17d1066Smrg return m[i]; 41b17d1066Smrg } 42b17d1066Smrg } 43b17d1066Smrg 4448fb7bfaSmrg namespace std _GLIBCXX_VISIBILITY(default) 4548fb7bfaSmrg { 4648fb7bfaSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION 4748fb7bfaSmrg 4848fb7bfaSmrg bad_weak_ptr::~bad_weak_ptr() noexcept = default; 4948fb7bfaSmrg 5048fb7bfaSmrg char const* what() const5148fb7bfaSmrg bad_weak_ptr::what() const noexcept 5248fb7bfaSmrg { return "bad_weak_ptr"; } 5348fb7bfaSmrg 544d5abbe8Smrg #ifdef __GTHREADS 554d5abbe8Smrg namespace 564d5abbe8Smrg { key(const void * addr)574d5abbe8Smrg inline unsigned char key(const void* addr) 58b17d1066Smrg { return _Hash_impl::hash(addr) & __gnu_internal::mask; } 594d5abbe8Smrg } 604d5abbe8Smrg _Sp_locker(const void * p)613f4ceed9Smrg _Sp_locker::_Sp_locker(const void* p) noexcept 624d5abbe8Smrg { 634d5abbe8Smrg if (__gthread_active_p()) 644d5abbe8Smrg { 654d5abbe8Smrg _M_key1 = _M_key2 = key(p); 66b17d1066Smrg __gnu_internal::get_mutex(_M_key1).lock(); 674d5abbe8Smrg } 684d5abbe8Smrg else 69b17d1066Smrg _M_key1 = _M_key2 = __gnu_internal::invalid; 704d5abbe8Smrg } 714d5abbe8Smrg _Sp_locker(const void * p1,const void * p2)723f4ceed9Smrg _Sp_locker::_Sp_locker(const void* p1, const void* p2) noexcept 734d5abbe8Smrg { 744d5abbe8Smrg if (__gthread_active_p()) 754d5abbe8Smrg { 764d5abbe8Smrg _M_key1 = key(p1); 774d5abbe8Smrg _M_key2 = key(p2); 784d5abbe8Smrg if (_M_key2 < _M_key1) 79b17d1066Smrg __gnu_internal::get_mutex(_M_key2).lock(); 80b17d1066Smrg __gnu_internal::get_mutex(_M_key1).lock(); 814d5abbe8Smrg if (_M_key2 > _M_key1) 82b17d1066Smrg __gnu_internal::get_mutex(_M_key2).lock(); 834d5abbe8Smrg } 844d5abbe8Smrg else 85b17d1066Smrg _M_key1 = _M_key2 = __gnu_internal::invalid; 864d5abbe8Smrg } 874d5abbe8Smrg ~_Sp_locker()884d5abbe8Smrg _Sp_locker::~_Sp_locker() 894d5abbe8Smrg { 90b17d1066Smrg if (_M_key1 != __gnu_internal::invalid) 914d5abbe8Smrg { 92b17d1066Smrg __gnu_internal::get_mutex(_M_key1).unlock(); 934d5abbe8Smrg if (_M_key2 != _M_key1) 94b17d1066Smrg __gnu_internal::get_mutex(_M_key2).unlock(); 954d5abbe8Smrg } 964d5abbe8Smrg } 974d5abbe8Smrg #endif 984d5abbe8Smrg 99181254a7Smrg bool _S_eq(const type_info & ti)100*b1e83836Smrg _Sp_make_shared_tag::_S_eq(const type_info& ti [[gnu::unused]]) noexcept 101181254a7Smrg { 102181254a7Smrg #if __cpp_rtti 103181254a7Smrg return ti == typeid(_Sp_make_shared_tag); 104181254a7Smrg #else 105181254a7Smrg // If libstdc++ itself is built with -fno-rtti then just assume that 106181254a7Smrg // make_shared and allocate_shared will never be used with -frtti. 107181254a7Smrg return false; 108181254a7Smrg #endif 109181254a7Smrg } 110181254a7Smrg 11148fb7bfaSmrg _GLIBCXX_END_NAMESPACE_VERSION 11248fb7bfaSmrg } // namespace 113