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