1*38fd1498Szrj // Bitmap Allocator. Out of line function definitions. -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj // Copyright (C) 2004-2018 Free Software Foundation, Inc. 4*38fd1498Szrj // 5*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj // software; you can redistribute it and/or modify it under the 7*38fd1498Szrj // terms of the GNU General Public License as published by the 8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj // any later version. 10*38fd1498Szrj 11*38fd1498Szrj // This library is distributed in the hope that it will be useful, 12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj // GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj // 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj // You should have received a copy of the GNU General Public License and 21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj // <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj #include <ext/bitmap_allocator.h> 26*38fd1498Szrj 27*38fd1498Szrj namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 28*38fd1498Szrj { 29*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 30*38fd1498Szrj 31*38fd1498Szrj namespace __detail 32*38fd1498Szrj { 33*38fd1498Szrj template class __mini_vector< 34*38fd1498Szrj std::pair<bitmap_allocator<char>::_Alloc_block*, 35*38fd1498Szrj bitmap_allocator<char>::_Alloc_block*> >; 36*38fd1498Szrj 37*38fd1498Szrj template class __mini_vector< 38*38fd1498Szrj std::pair<bitmap_allocator<wchar_t>::_Alloc_block*, 39*38fd1498Szrj bitmap_allocator<wchar_t>::_Alloc_block*> >; 40*38fd1498Szrj 41*38fd1498Szrj template class __mini_vector<size_t*>; 42*38fd1498Szrj 43*38fd1498Szrj template size_t** __lower_bound(size_t**, size_t**, size_t const&, 44*38fd1498Szrj free_list::_LT_pointer_compare); 45*38fd1498Szrj } 46*38fd1498Szrj 47*38fd1498Szrj size_t* 48*38fd1498Szrj free_list:: _M_get(size_t __sz)49*38fd1498Szrj _M_get(size_t __sz) throw(std::bad_alloc) 50*38fd1498Szrj { 51*38fd1498Szrj #if defined __GTHREADS 52*38fd1498Szrj __mutex_type& __bfl_mutex = _M_get_mutex(); 53*38fd1498Szrj __bfl_mutex.lock(); 54*38fd1498Szrj #endif 55*38fd1498Szrj const vector_type& __free_list = _M_get_free_list(); 56*38fd1498Szrj using __gnu_cxx::__detail::__lower_bound; 57*38fd1498Szrj iterator __tmp = __lower_bound(__free_list.begin(), __free_list.end(), 58*38fd1498Szrj __sz, _LT_pointer_compare()); 59*38fd1498Szrj 60*38fd1498Szrj if (__tmp == __free_list.end() || !_M_should_i_give(**__tmp, __sz)) 61*38fd1498Szrj { 62*38fd1498Szrj // We release the lock here, because operator new is 63*38fd1498Szrj // guaranteed to be thread-safe by the underlying 64*38fd1498Szrj // implementation. 65*38fd1498Szrj #if defined __GTHREADS 66*38fd1498Szrj __bfl_mutex.unlock(); 67*38fd1498Szrj #endif 68*38fd1498Szrj // Try twice to get the memory: once directly, and the 2nd 69*38fd1498Szrj // time after clearing the free list. If both fail, then throw 70*38fd1498Szrj // std::bad_alloc(). 71*38fd1498Szrj int __ctr = 2; 72*38fd1498Szrj while (__ctr) 73*38fd1498Szrj { 74*38fd1498Szrj size_t* __ret = 0; 75*38fd1498Szrj --__ctr; 76*38fd1498Szrj __try 77*38fd1498Szrj { 78*38fd1498Szrj __ret = reinterpret_cast<size_t*> 79*38fd1498Szrj (::operator new(__sz + sizeof(size_t))); 80*38fd1498Szrj } 81*38fd1498Szrj __catch(const std::bad_alloc&) 82*38fd1498Szrj { 83*38fd1498Szrj this->_M_clear(); 84*38fd1498Szrj } 85*38fd1498Szrj if (!__ret) 86*38fd1498Szrj continue; 87*38fd1498Szrj *__ret = __sz; 88*38fd1498Szrj return __ret + 1; 89*38fd1498Szrj } 90*38fd1498Szrj std::__throw_bad_alloc(); 91*38fd1498Szrj } 92*38fd1498Szrj else 93*38fd1498Szrj { 94*38fd1498Szrj size_t* __ret = *__tmp; 95*38fd1498Szrj _M_get_free_list().erase(__tmp); 96*38fd1498Szrj #if defined __GTHREADS 97*38fd1498Szrj __bfl_mutex.unlock(); 98*38fd1498Szrj #endif 99*38fd1498Szrj return __ret + 1; 100*38fd1498Szrj } 101*38fd1498Szrj } 102*38fd1498Szrj 103*38fd1498Szrj void 104*38fd1498Szrj free_list:: _M_clear()105*38fd1498Szrj _M_clear() 106*38fd1498Szrj { 107*38fd1498Szrj #if defined __GTHREADS 108*38fd1498Szrj __gnu_cxx::__scoped_lock __bfl_lock(_M_get_mutex()); 109*38fd1498Szrj #endif 110*38fd1498Szrj vector_type& __free_list = _M_get_free_list(); 111*38fd1498Szrj iterator __iter = __free_list.begin(); 112*38fd1498Szrj while (__iter != __free_list.end()) 113*38fd1498Szrj { 114*38fd1498Szrj ::operator delete((void*)*__iter); 115*38fd1498Szrj ++__iter; 116*38fd1498Szrj } 117*38fd1498Szrj __free_list.clear(); 118*38fd1498Szrj } 119*38fd1498Szrj 120*38fd1498Szrj // Instantiations. 121*38fd1498Szrj template class bitmap_allocator<char>; 122*38fd1498Szrj template class bitmap_allocator<wchar_t>; 123*38fd1498Szrj 124*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 125*38fd1498Szrj } // namespace 126