/ src / bitmap_allocator.cc
bitmap_allocator.cc
  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