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