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