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