1169691Skan// Bitmap Allocator. Out of line function definitions. -*- C++ -*- 2169691Skan 3169691Skan// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. 4169691Skan// 5169691Skan// This file is part of the GNU ISO C++ Library. This library is free 6169691Skan// software; you can redistribute it and/or modify it under the 7169691Skan// terms of the GNU General Public License as published by the 8169691Skan// Free Software Foundation; either version 2, or (at your option) 9169691Skan// any later version. 10169691Skan 11169691Skan// This library is distributed in the hope that it will be useful, 12169691Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of 13169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14169691Skan// GNU General Public License for more details. 15169691Skan 16169691Skan// You should have received a copy of the GNU General Public License along 17169691Skan// with this library; see the file COPYING. If not, write to the Free 18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19169691Skan// USA. 20169691Skan 21169691Skan// As a special exception, you may use this file as part of a free software 22169691Skan// library without restriction. Specifically, if other files instantiate 23169691Skan// templates or use macros or inline functions from this file, or you compile 24169691Skan// this file and link it with other files to produce an executable, this 25169691Skan// file does not by itself cause the resulting executable to be covered by 26169691Skan// the GNU General Public License. This exception does not however 27169691Skan// invalidate any other reasons why the executable file might be covered by 28169691Skan// the GNU General Public License. 29169691Skan 30169691Skan#include <ext/bitmap_allocator.h> 31169691Skan 32169691Skan_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 33169691Skan 34169691Skan namespace __detail 35169691Skan { 36169691Skan template class __mini_vector< 37169691Skan std::pair<bitmap_allocator<char>::_Alloc_block*, 38169691Skan bitmap_allocator<char>::_Alloc_block*> >; 39169691Skan 40169691Skan template class __mini_vector< 41169691Skan std::pair<bitmap_allocator<wchar_t>::_Alloc_block*, 42169691Skan bitmap_allocator<wchar_t>::_Alloc_block*> >; 43169691Skan 44169691Skan template class __mini_vector<size_t*>; 45169691Skan 46169691Skan template size_t** __lower_bound(size_t**, size_t**, size_t const&, 47169691Skan free_list::_LT_pointer_compare); 48169691Skan } 49169691Skan 50169691Skan size_t* 51169691Skan free_list:: 52169691Skan _M_get(size_t __sz) throw(std::bad_alloc) 53169691Skan { 54169691Skan#if defined __GTHREADS 55169691Skan __mutex_type& __bfl_mutex = _M_get_mutex(); 56169691Skan#endif 57169691Skan const vector_type& __free_list = _M_get_free_list(); 58169691Skan using __gnu_cxx::__detail::__lower_bound; 59169691Skan iterator __tmp = __lower_bound(__free_list.begin(), __free_list.end(), 60169691Skan __sz, _LT_pointer_compare()); 61169691Skan 62169691Skan if (__tmp == __free_list.end() || !_M_should_i_give(**__tmp, __sz)) 63169691Skan { 64169691Skan // We release the lock here, because operator new is 65169691Skan // guaranteed to be thread-safe by the underlying 66169691Skan // implementation. 67169691Skan#if defined __GTHREADS 68169691Skan __bfl_mutex.unlock(); 69169691Skan#endif 70169691Skan // Try twice to get the memory: once directly, and the 2nd 71169691Skan // time after clearing the free list. If both fail, then throw 72169691Skan // std::bad_alloc(). 73169691Skan int __ctr = 2; 74169691Skan while (__ctr) 75169691Skan { 76169691Skan size_t* __ret = 0; 77169691Skan --__ctr; 78169691Skan try 79169691Skan { 80169691Skan __ret = reinterpret_cast<size_t*> 81169691Skan (::operator new(__sz + sizeof(size_t))); 82169691Skan } 83169691Skan catch(...) 84169691Skan { 85169691Skan this->_M_clear(); 86169691Skan } 87169691Skan if (!__ret) 88169691Skan continue; 89169691Skan *__ret = __sz; 90169691Skan return __ret + 1; 91169691Skan } 92169691Skan std::__throw_bad_alloc(); 93169691Skan } 94169691Skan else 95169691Skan { 96169691Skan size_t* __ret = *__tmp; 97169691Skan _M_get_free_list().erase(__tmp); 98169691Skan#if defined __GTHREADS 99169691Skan __bfl_mutex.unlock(); 100169691Skan#endif 101169691Skan return __ret + 1; 102169691Skan } 103169691Skan } 104169691Skan 105169691Skan void 106169691Skan free_list:: 107169691Skan _M_clear() 108169691Skan { 109169691Skan#if defined __GTHREADS 110169691Skan __gnu_cxx::__scoped_lock __bfl_lock(_M_get_mutex()); 111169691Skan#endif 112169691Skan vector_type& __free_list = _M_get_free_list(); 113169691Skan iterator __iter = __free_list.begin(); 114169691Skan while (__iter != __free_list.end()) 115169691Skan { 116169691Skan ::operator delete((void*)*__iter); 117169691Skan ++__iter; 118169691Skan } 119169691Skan __free_list.clear(); 120169691Skan } 121169691Skan 122169691Skan // Instantiations. 123169691Skan template class bitmap_allocator<char>; 124169691Skan template class bitmap_allocator<wchar_t>; 125169691Skan 126169691Skan_GLIBCXX_END_NAMESPACE 127