1 // Bitmap Allocator. Out of line function definitions. -*- C++ -*- 2 3 // Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011 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 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 29 { 30 namespace __detail 31 { 32 _GLIBCXX_BEGIN_NAMESPACE_VERSION 33 template class __mini_vector< 34 std::pair<bitmap_allocator<char>::_Alloc_block*, 35 bitmap_allocator<char>::_Alloc_block*> >; 36 37 template class __mini_vector< 38 std::pair<bitmap_allocator<wchar_t>::_Alloc_block*, 39 bitmap_allocator<wchar_t>::_Alloc_block*> >; 40 41 template class __mini_vector<size_t*>; 42 43 template size_t** __lower_bound(size_t**, size_t**, size_t const&, 44 free_list::_LT_pointer_compare); 45 _GLIBCXX_END_NAMESPACE_VERSION 46 } 47 48 _GLIBCXX_BEGIN_NAMESPACE_VERSION 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 __bfl_mutex.lock(); 57 #endif 58 const vector_type& __free_list = _M_get_free_list(); 59 using __gnu_cxx::__detail::__lower_bound; 60 iterator __tmp = __lower_bound(__free_list.begin(), __free_list.end(), 61 __sz, _LT_pointer_compare()); 62 63 if (__tmp == __free_list.end() || !_M_should_i_give(**__tmp, __sz)) 64 { 65 // We release the lock here, because operator new is 66 // guaranteed to be thread-safe by the underlying 67 // implementation. 68 #if defined __GTHREADS 69 __bfl_mutex.unlock(); 70 #endif 71 // Try twice to get the memory: once directly, and the 2nd 72 // time after clearing the free list. If both fail, then throw 73 // std::bad_alloc(). 74 int __ctr = 2; 75 while (__ctr) 76 { 77 size_t* __ret = 0; 78 --__ctr; 79 __try 80 { 81 __ret = reinterpret_cast<size_t*> 82 (::operator new(__sz + sizeof(size_t))); 83 } 84 __catch(const std::bad_alloc&) 85 { 86 this->_M_clear(); 87 } 88 if (!__ret) 89 continue; 90 *__ret = __sz; 91 return __ret + 1; 92 } 93 std::__throw_bad_alloc(); 94 } 95 else 96 { 97 size_t* __ret = *__tmp; 98 _M_get_free_list().erase(__tmp); 99 #if defined __GTHREADS 100 __bfl_mutex.unlock(); 101 #endif 102 return __ret + 1; 103 } 104 } 105 106 void 107 free_list:: 108 _M_clear() 109 { 110 #if defined __GTHREADS 111 __gnu_cxx::__scoped_lock __bfl_lock(_M_get_mutex()); 112 #endif 113 vector_type& __free_list = _M_get_free_list(); 114 iterator __iter = __free_list.begin(); 115 while (__iter != __free_list.end()) 116 { 117 ::operator delete((void*)*__iter); 118 ++__iter; 119 } 120 __free_list.clear(); 121 } 122 123 // Instantiations. 124 template class bitmap_allocator<char>; 125 template class bitmap_allocator<wchar_t>; 126 127 _GLIBCXX_END_NAMESPACE_VERSION 128 } // namespace 129