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