1 // Bitmap Allocator. Out of line function definitions. -*- C++ -*- 2 3 // Copyright (C) 2004-2018 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 3, 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 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 #include <ext/bitmap_allocator.h> 26 27 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 28 { 29 _GLIBCXX_BEGIN_NAMESPACE_VERSION 30 31 namespace __detail 32 { 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 } 46 47 size_t* 48 free_list:: 49 _M_get(size_t __sz) throw(std::bad_alloc) 50 { 51 #if defined __GTHREADS 52 __mutex_type& __bfl_mutex = _M_get_mutex(); 53 __bfl_mutex.lock(); 54 #endif 55 const vector_type& __free_list = _M_get_free_list(); 56 using __gnu_cxx::__detail::__lower_bound; 57 iterator __tmp = __lower_bound(__free_list.begin(), __free_list.end(), 58 __sz, _LT_pointer_compare()); 59 60 if (__tmp == __free_list.end() || !_M_should_i_give(**__tmp, __sz)) 61 { 62 // We release the lock here, because operator new is 63 // guaranteed to be thread-safe by the underlying 64 // implementation. 65 #if defined __GTHREADS 66 __bfl_mutex.unlock(); 67 #endif 68 // Try twice to get the memory: once directly, and the 2nd 69 // time after clearing the free list. If both fail, then throw 70 // std::bad_alloc(). 71 int __ctr = 2; 72 while (__ctr) 73 { 74 size_t* __ret = 0; 75 --__ctr; 76 __try 77 { 78 __ret = reinterpret_cast<size_t*> 79 (::operator new(__sz + sizeof(size_t))); 80 } 81 __catch(const std::bad_alloc&) 82 { 83 this->_M_clear(); 84 } 85 if (!__ret) 86 continue; 87 *__ret = __sz; 88 return __ret + 1; 89 } 90 std::__throw_bad_alloc(); 91 } 92 else 93 { 94 size_t* __ret = *__tmp; 95 _M_get_free_list().erase(__tmp); 96 #if defined __GTHREADS 97 __bfl_mutex.unlock(); 98 #endif 99 return __ret + 1; 100 } 101 } 102 103 void 104 free_list:: 105 _M_clear() 106 { 107 #if defined __GTHREADS 108 __gnu_cxx::__scoped_lock __bfl_lock(_M_get_mutex()); 109 #endif 110 vector_type& __free_list = _M_get_free_list(); 111 iterator __iter = __free_list.begin(); 112 while (__iter != __free_list.end()) 113 { 114 ::operator delete((void*)*__iter); 115 ++__iter; 116 } 117 __free_list.clear(); 118 } 119 120 // Instantiations. 121 template class bitmap_allocator<char>; 122 template class bitmap_allocator<wchar_t>; 123 124 _GLIBCXX_END_NAMESPACE_VERSION 125 } // namespace 126