1  // Bitmap Allocator. -*- C++ -*-
       2  
       3  // Copyright (C) 2004-2023 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  /** @file ext/bitmap_allocator.h
      26   *  This file is a GNU extension to the Standard C++ Library.
      27   */
      28  
      29  #ifndef _BITMAP_ALLOCATOR_H
      30  #define _BITMAP_ALLOCATOR_H 1
      31  
      32  #include <bits/requires_hosted.h> // GNU extensions are currently omitted
      33  
      34  #include <utility> // For std::pair.
      35  #include <bits/functexcept.h> // For __throw_bad_alloc().
      36  #include <bits/stl_function.h> // For greater_equal, and less_equal.
      37  #include <new> // For operator new.
      38  #include <debug/debug.h> // _GLIBCXX_DEBUG_ASSERT
      39  #include <ext/concurrence.h>
      40  #include <bits/move.h>
      41  
      42  /** @brief The constant in the expression below is the alignment
      43   * required in bytes.
      44   */
      45  #define _BALLOC_ALIGN_BYTES 8
      46  
      47  namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
      48  {
      49  _GLIBCXX_BEGIN_NAMESPACE_VERSION
      50  
      51    namespace __detail
      52    {
      53      /** @class  __mini_vector bitmap_allocator.h bitmap_allocator.h
      54       *
      55       *  @brief  __mini_vector<> is a stripped down version of the
      56       *  full-fledged std::vector<>.
      57       *
      58       *  It is to be used only for built-in types or PODs. Notable
      59       *  differences are:
      60       * 
      61       *  1. Not all accessor functions are present.
      62       *  2. Used ONLY for PODs.
      63       *  3. No Allocator template argument. Uses ::operator new() to get
      64       *  memory, and ::operator delete() to free it.
      65       *  Caveat: The dtor does NOT free the memory allocated, so this a
      66       *  memory-leaking vector!
      67       */
      68      template<typename _Tp>
      69        class __mini_vector
      70        {
      71  	__mini_vector(const __mini_vector&);
      72  	__mini_vector& operator=(const __mini_vector&);
      73  
      74        public:
      75  	typedef _Tp value_type;
      76  	typedef _Tp* pointer;
      77  	typedef _Tp& reference;
      78  	typedef const _Tp& const_reference;
      79  	typedef std::size_t size_type;
      80  	typedef std::ptrdiff_t difference_type;
      81  	typedef pointer iterator;
      82  
      83        private:
      84  	pointer _M_start;
      85  	pointer _M_finish;
      86  	pointer _M_end_of_storage;
      87  
      88  	size_type
      89  	_M_space_left() const throw()
      90  	{ return _M_end_of_storage - _M_finish; }
      91  
      92  	_GLIBCXX_NODISCARD pointer
      93  	allocate(size_type __n)
      94  	{ return static_cast<pointer>(::operator new(__n * sizeof(_Tp))); }
      95  
      96  	void
      97  	deallocate(pointer __p, size_type)
      98  	{ ::operator delete(__p); }
      99  
     100        public:
     101  	// Members used: size(), push_back(), pop_back(),
     102  	// insert(iterator, const_reference), erase(iterator),
     103  	// begin(), end(), back(), operator[].
     104  
     105  	__mini_vector()
     106          : _M_start(0), _M_finish(0), _M_end_of_storage(0) { }
     107  
     108  	size_type
     109  	size() const throw()
     110  	{ return _M_finish - _M_start; }
     111  
     112  	iterator
     113  	begin() const throw()
     114  	{ return this->_M_start; }
     115  
     116  	iterator
     117  	end() const throw()
     118  	{ return this->_M_finish; }
     119  
     120  	reference
     121  	back() const throw()
     122  	{ return *(this->end() - 1); }
     123  
     124  	reference
     125  	operator[](const size_type __pos) const throw()
     126  	{ return this->_M_start[__pos]; }
     127  
     128  	void
     129  	insert(iterator __pos, const_reference __x);
     130  
     131  	void
     132  	push_back(const_reference __x)
     133  	{
     134  	  if (this->_M_space_left())
     135  	    {
     136  	      *this->end() = __x;
     137  	      ++this->_M_finish;
     138  	    }
     139  	  else
     140  	    this->insert(this->end(), __x);
     141  	}
     142  
     143  	void
     144  	pop_back() throw()
     145  	{ --this->_M_finish; }
     146  
     147  	void
     148  	erase(iterator __pos) throw();
     149  
     150  	void
     151  	clear() throw()
     152  	{ this->_M_finish = this->_M_start; }
     153        };
     154  
     155      // Out of line function definitions.
     156      template<typename _Tp>
     157        void __mini_vector<_Tp>::
     158        insert(iterator __pos, const_reference __x)
     159        {
     160  	if (this->_M_space_left())
     161  	  {
     162  	    size_type __to_move = this->_M_finish - __pos;
     163  	    iterator __dest = this->end();
     164  	    iterator __src = this->end() - 1;
     165  
     166  	    ++this->_M_finish;
     167  	    while (__to_move)
     168  	      {
     169  		*__dest = *__src;
     170  		--__dest; --__src; --__to_move;
     171  	      }
     172  	    *__pos = __x;
     173  	  }
     174  	else
     175  	  {
     176  	    size_type __new_size = this->size() ? this->size() * 2 : 1;
     177  	    iterator __new_start = this->allocate(__new_size);
     178  	    iterator __first = this->begin();
     179  	    iterator __start = __new_start;
     180  	    while (__first != __pos)
     181  	      {
     182  		*__start = *__first;
     183  		++__start; ++__first;
     184  	      }
     185  	    *__start = __x;
     186  	    ++__start;
     187  	    while (__first != this->end())
     188  	      {
     189  		*__start = *__first;
     190  		++__start; ++__first;
     191  	      }
     192  	    if (this->_M_start)
     193  	      this->deallocate(this->_M_start, this->size());
     194  
     195  	    this->_M_start = __new_start;
     196  	    this->_M_finish = __start;
     197  	    this->_M_end_of_storage = this->_M_start + __new_size;
     198  	  }
     199        }
     200  
     201      template<typename _Tp>
     202        void __mini_vector<_Tp>::
     203        erase(iterator __pos) throw()
     204        {
     205  	while (__pos + 1 != this->end())
     206  	  {
     207  	    *__pos = __pos[1];
     208  	    ++__pos;
     209  	  }
     210  	--this->_M_finish;
     211        }
     212  
     213  
     214      template<typename _Tp>
     215        struct __mv_iter_traits
     216        {
     217  	typedef typename _Tp::value_type value_type;
     218  	typedef typename _Tp::difference_type difference_type;
     219        };
     220  
     221      template<typename _Tp>
     222        struct __mv_iter_traits<_Tp*>
     223        {
     224  	typedef _Tp value_type;
     225  	typedef std::ptrdiff_t difference_type;
     226        };
     227  
     228      enum 
     229        { 
     230  	bits_per_byte = 8,
     231  	bits_per_block = sizeof(std::size_t) * std::size_t(bits_per_byte)
     232        };
     233  
     234      template<typename _ForwardIterator, typename _Tp, typename _Compare>
     235        _ForwardIterator
     236        __lower_bound(_ForwardIterator __first, _ForwardIterator __last,
     237  		    const _Tp& __val, _Compare __comp)
     238        {
     239  	typedef typename __mv_iter_traits<_ForwardIterator>::difference_type
     240  	  _DistanceType;
     241  
     242  	_DistanceType __len = __last - __first;
     243  	_DistanceType __half;
     244  	_ForwardIterator __middle;
     245  
     246  	while (__len > 0)
     247  	  {
     248  	    __half = __len >> 1;
     249  	    __middle = __first;
     250  	    __middle += __half;
     251  	    if (__comp(*__middle, __val))
     252  	      {
     253  		__first = __middle;
     254  		++__first;
     255  		__len = __len - __half - 1;
     256  	      }
     257  	    else
     258  	      __len = __half;
     259  	  }
     260  	return __first;
     261        }
     262  
     263      /** @brief The number of Blocks pointed to by the address pair
     264       *  passed to the function.
     265       */
     266      template<typename _AddrPair>
     267        inline std::size_t
     268        __num_blocks(_AddrPair __ap)
     269        { return (__ap.second - __ap.first) + 1; }
     270  
     271      /** @brief The number of Bit-maps pointed to by the address pair
     272       *  passed to the function.
     273       */
     274      template<typename _AddrPair>
     275        inline std::size_t
     276        __num_bitmaps(_AddrPair __ap)
     277        { return __num_blocks(__ap) / std::size_t(bits_per_block); }
     278  
     279      // _Tp should be a pointer type.
     280      template<typename _Tp>
     281        class _Inclusive_between 
     282        {
     283  	typedef _Tp pointer;
     284  	pointer _M_ptr_value;
     285  	typedef typename std::pair<_Tp, _Tp> _Block_pair;
     286  	
     287        public:
     288  	_Inclusive_between(pointer __ptr) : _M_ptr_value(__ptr) 
     289  	{ }
     290  	
     291  	bool 
     292  	operator()(_Block_pair __bp) const throw()
     293  	{
     294  	  if (std::less_equal<pointer>()(_M_ptr_value, __bp.second) 
     295  	      && std::greater_equal<pointer>()(_M_ptr_value, __bp.first))
     296  	    return true;
     297  	  else
     298  	    return false;
     299  	}
     300        };
     301    
     302      // Used to pass a Functor to functions by reference.
     303      template<typename _Functor>
     304        class _Functor_Ref 
     305        {
     306  	_Functor& _M_fref;
     307  	
     308        public:
     309  	typedef typename _Functor::argument_type argument_type;
     310  	typedef typename _Functor::result_type result_type;
     311  
     312  	_Functor_Ref(_Functor& __fref) : _M_fref(__fref) 
     313  	{ }
     314  
     315  	result_type 
     316  	operator()(argument_type __arg) 
     317  	{ return _M_fref(__arg); }
     318        };
     319  
     320      /** @class  _Ffit_finder bitmap_allocator.h bitmap_allocator.h
     321       *
     322       *  @brief  The class which acts as a predicate for applying the
     323       *  first-fit memory allocation policy for the bitmap allocator.
     324       */
     325      // _Tp should be a pointer type, and _Alloc is the Allocator for
     326      // the vector.
     327      template<typename _Tp>
     328        class _Ffit_finder 
     329        {
     330  	typedef std::pair<_Tp, _Tp> _Block_pair;
     331  	typedef __detail::__mini_vector<_Block_pair> _BPVector;
     332  	typedef typename _BPVector::difference_type _Counter_type;
     333  
     334  	std::size_t* _M_pbitmap;
     335  	_Counter_type _M_data_offset;
     336  
     337        public:
     338  	typedef bool result_type;
     339  	typedef _Block_pair argument_type;
     340  
     341  	_Ffit_finder() : _M_pbitmap(0), _M_data_offset(0)
     342  	{ }
     343  
     344  	bool 
     345  	operator()(_Block_pair __bp) throw()
     346  	{
     347  	  using std::size_t;
     348  	  // Set the _rover to the last physical location bitmap,
     349  	  // which is the bitmap which belongs to the first free
     350  	  // block. Thus, the bitmaps are in exact reverse order of
     351  	  // the actual memory layout. So, we count down the bitmaps,
     352  	  // which is the same as moving up the memory.
     353  
     354  	  // If the used count stored at the start of the Bit Map headers
     355  	  // is equal to the number of Objects that the current Block can
     356  	  // store, then there is definitely no space for another single
     357  	  // object, so just return false.
     358  	  _Counter_type __diff = __detail::__num_bitmaps(__bp);
     359  
     360  	  if (*(reinterpret_cast<size_t*>
     361  		(__bp.first) - (__diff + 1)) == __detail::__num_blocks(__bp))
     362  	    return false;
     363  
     364  	  size_t* __rover = reinterpret_cast<size_t*>(__bp.first) - 1;
     365  
     366  	  for (_Counter_type __i = 0; __i < __diff; ++__i)
     367  	    {
     368  	      _M_data_offset = __i;
     369  	      if (*__rover)
     370  		{
     371  		  _M_pbitmap = __rover;
     372  		  return true;
     373  		}
     374  	      --__rover;
     375  	    }
     376  	  return false;
     377  	}
     378      
     379  	std::size_t*
     380  	_M_get() const throw()
     381  	{ return _M_pbitmap; }
     382  
     383  	_Counter_type
     384  	_M_offset() const throw()
     385  	{ return _M_data_offset * std::size_t(bits_per_block); }
     386        };
     387  
     388      /** @class  _Bitmap_counter bitmap_allocator.h bitmap_allocator.h
     389       *
     390       *  @brief  The bitmap counter which acts as the bitmap
     391       *  manipulator, and manages the bit-manipulation functions and
     392       *  the searching and identification functions on the bit-map.
     393       */
     394      // _Tp should be a pointer type.
     395      template<typename _Tp>
     396        class _Bitmap_counter
     397        {
     398  	typedef typename
     399  	__detail::__mini_vector<typename std::pair<_Tp, _Tp> > _BPVector;
     400  	typedef typename _BPVector::size_type _Index_type;
     401  	typedef _Tp pointer;
     402  
     403  	_BPVector& _M_vbp;
     404  	std::size_t* _M_curr_bmap;
     405  	std::size_t* _M_last_bmap_in_block;
     406  	_Index_type _M_curr_index;
     407      
     408        public:
     409  	// Use the 2nd parameter with care. Make sure that such an
     410  	// entry exists in the vector before passing that particular
     411  	// index to this ctor.
     412  	_Bitmap_counter(_BPVector& Rvbp, long __index = -1) : _M_vbp(Rvbp)
     413  	{ this->_M_reset(__index); }
     414      
     415  	void 
     416  	_M_reset(long __index = -1) throw()
     417  	{
     418  	  if (__index == -1)
     419  	    {
     420  	      _M_curr_bmap = 0;
     421  	      _M_curr_index = static_cast<_Index_type>(-1);
     422  	      return;
     423  	    }
     424  
     425  	  _M_curr_index = __index;
     426  	  _M_curr_bmap = reinterpret_cast<std::size_t*>
     427  	    (_M_vbp[_M_curr_index].first) - 1;
     428  	  
     429  	  _GLIBCXX_DEBUG_ASSERT(__index <= (long)_M_vbp.size() - 1);
     430  	
     431  	  _M_last_bmap_in_block = _M_curr_bmap
     432  	    - ((_M_vbp[_M_curr_index].second 
     433  		- _M_vbp[_M_curr_index].first + 1) 
     434  	       / std::size_t(bits_per_block) - 1);
     435  	}
     436      
     437  	// Dangerous Function! Use with extreme care. Pass to this
     438  	// function ONLY those values that are known to be correct,
     439  	// otherwise this will mess up big time.
     440  	void
     441  	_M_set_internal_bitmap(std::size_t* __new_internal_marker) throw()
     442  	{ _M_curr_bmap = __new_internal_marker; }
     443      
     444  	bool
     445  	_M_finished() const throw()
     446  	{ return(_M_curr_bmap == 0); }
     447      
     448  	_Bitmap_counter&
     449  	operator++() throw()
     450  	{
     451  	  if (_M_curr_bmap == _M_last_bmap_in_block)
     452  	    {
     453  	      if (++_M_curr_index == _M_vbp.size())
     454  		_M_curr_bmap = 0;
     455  	      else
     456  		this->_M_reset(_M_curr_index);
     457  	    }
     458  	  else
     459  	    --_M_curr_bmap;
     460  	  return *this;
     461  	}
     462      
     463  	std::size_t*
     464  	_M_get() const throw()
     465  	{ return _M_curr_bmap; }
     466      
     467  	pointer 
     468  	_M_base() const throw()
     469  	{ return _M_vbp[_M_curr_index].first; }
     470  
     471  	_Index_type
     472  	_M_offset() const throw()
     473  	{
     474  	  return std::size_t(bits_per_block)
     475  	    * ((reinterpret_cast<std::size_t*>(this->_M_base())
     476  		- _M_curr_bmap) - 1);
     477  	}
     478      
     479  	_Index_type
     480  	_M_where() const throw()
     481  	{ return _M_curr_index; }
     482        };
     483  
     484      /** @brief  Mark a memory address as allocated by re-setting the
     485       *  corresponding bit in the bit-map.
     486       */
     487      inline void 
     488      __bit_allocate(std::size_t* __pbmap, std::size_t __pos) throw()
     489      {
     490        std::size_t __mask = 1 << __pos;
     491        __mask = ~__mask;
     492        *__pbmap &= __mask;
     493      }
     494    
     495      /** @brief  Mark a memory address as free by setting the
     496       *  corresponding bit in the bit-map.
     497       */
     498      inline void 
     499      __bit_free(std::size_t* __pbmap, std::size_t __pos) throw()
     500      {
     501        std::size_t __mask = 1 << __pos;
     502        *__pbmap |= __mask;
     503      }
     504    } // namespace __detail
     505  
     506    /** @brief  Generic Version of the bsf instruction.
     507     */
     508    inline std::size_t
     509    _Bit_scan_forward(std::size_t __num)
     510    { return static_cast<std::size_t>(__builtin_ctzl(__num)); }
     511  
     512    /** @class  free_list bitmap_allocator.h bitmap_allocator.h
     513     *
     514     *  @brief  The free list class for managing chunks of memory to be
     515     *  given to and returned by the bitmap_allocator.
     516     */
     517    class free_list
     518    {
     519    public:
     520      typedef std::size_t* 			value_type;
     521      typedef __detail::__mini_vector<value_type> vector_type;
     522      typedef vector_type::iterator 		iterator;
     523      typedef __mutex				__mutex_type;
     524  
     525    private:
     526      struct _LT_pointer_compare
     527      {
     528        bool
     529        operator()(const std::size_t* __pui,
     530  		 const std::size_t __cui) const throw()
     531        { return *__pui < __cui; }
     532      };
     533  
     534  #if defined __GTHREADS
     535      __mutex_type&
     536      _M_get_mutex()
     537      {
     538        static __mutex_type _S_mutex;
     539        return _S_mutex;
     540      }
     541  #endif
     542  
     543      vector_type&
     544      _M_get_free_list()
     545      {
     546        static vector_type _S_free_list;
     547        return _S_free_list;
     548      }
     549  
     550      /** @brief  Performs validation of memory based on their size.
     551       *
     552       *  @param  __addr The pointer to the memory block to be
     553       *  validated.
     554       *
     555       *  Validates the memory block passed to this function and
     556       *  appropriately performs the action of managing the free list of
     557       *  blocks by adding this block to the free list or deleting this
     558       *  or larger blocks from the free list.
     559       */
     560      void
     561      _M_validate(std::size_t* __addr) throw()
     562      {
     563        vector_type& __free_list = _M_get_free_list();
     564        const vector_type::size_type __max_size = 64;
     565        if (__free_list.size() >= __max_size)
     566  	{
     567  	  // Ok, the threshold value has been reached.  We determine
     568  	  // which block to remove from the list of free blocks.
     569  	  if (*__addr >= *__free_list.back())
     570  	    {
     571  	      // Ok, the new block is greater than or equal to the
     572  	      // last block in the list of free blocks. We just free
     573  	      // the new block.
     574  	      ::operator delete(static_cast<void*>(__addr));
     575  	      return;
     576  	    }
     577  	  else
     578  	    {
     579  	      // Deallocate the last block in the list of free lists,
     580  	      // and insert the new one in its correct position.
     581  	      ::operator delete(static_cast<void*>(__free_list.back()));
     582  	      __free_list.pop_back();
     583  	    }
     584  	}
     585  	  
     586        // Just add the block to the list of free lists unconditionally.
     587        iterator __temp = __detail::__lower_bound
     588  	(__free_list.begin(), __free_list.end(), 
     589  	 *__addr, _LT_pointer_compare());
     590  
     591        // We may insert the new free list before _temp;
     592        __free_list.insert(__temp, __addr);
     593      }
     594  
     595      /** @brief  Decides whether the wastage of memory is acceptable for
     596       *  the current memory request and returns accordingly.
     597       *
     598       *  @param __block_size The size of the block available in the free
     599       *  list.
     600       *
     601       *  @param __required_size The required size of the memory block.
     602       *
     603       *  @return true if the wastage incurred is acceptable, else returns
     604       *  false.
     605       */
     606      bool 
     607      _M_should_i_give(std::size_t __block_size,
     608  		     std::size_t __required_size) throw()
     609      {
     610        const std::size_t __max_wastage_percentage = 36;
     611        if (__block_size >= __required_size && 
     612  	  (((__block_size - __required_size) * 100 / __block_size)
     613  	   < __max_wastage_percentage))
     614  	return true;
     615        else
     616  	return false;
     617      }
     618  
     619    public:
     620      /** @brief This function returns the block of memory to the
     621       *  internal free list.
     622       *
     623       *  @param  __addr The pointer to the memory block that was given
     624       *  by a call to the _M_get function.
     625       */
     626      inline void 
     627      _M_insert(std::size_t* __addr) throw()
     628      {
     629  #if defined __GTHREADS
     630        __scoped_lock __bfl_lock(_M_get_mutex());
     631  #endif
     632        // Call _M_validate to decide what should be done with
     633        // this particular free list.
     634        this->_M_validate(reinterpret_cast<std::size_t*>(__addr) - 1);
     635        // See discussion as to why this is 1!
     636      }
     637      
     638      /** @brief  This function gets a block of memory of the specified
     639       *  size from the free list.
     640       *
     641       *  @param  __sz The size in bytes of the memory required.
     642       *
     643       *  @return  A pointer to the new memory block of size at least
     644       *  equal to that requested.
     645       */
     646      std::size_t*
     647      _M_get(std::size_t __sz) _GLIBCXX_THROW(std::bad_alloc);
     648  
     649      /** @brief  This function just clears the internal Free List, and
     650       *  gives back all the memory to the OS.
     651       */
     652      void 
     653      _M_clear();
     654    };
     655  
     656  
     657    // Forward declare the class.
     658    template<typename _Tp> 
     659      class bitmap_allocator;
     660  
     661    // Specialize for void:
     662    template<>
     663      class bitmap_allocator<void>
     664      {
     665      public:
     666        typedef void*       pointer;
     667        typedef const void* const_pointer;
     668  
     669        // Reference-to-void members are impossible.
     670        typedef void  value_type;
     671        template<typename _Tp1>
     672          struct rebind
     673  	{
     674  	  typedef bitmap_allocator<_Tp1> other;
     675  	};
     676      };
     677  
     678    /**
     679     * @brief Bitmap Allocator, primary template.
     680     * @ingroup allocators
     681     */
     682    template<typename _Tp>
     683      class bitmap_allocator : private free_list
     684      {
     685      public:
     686        typedef std::size_t    		size_type;
     687        typedef std::ptrdiff_t 		difference_type;
     688        typedef _Tp*        		pointer;
     689        typedef const _Tp*  		const_pointer;
     690        typedef _Tp&        		reference;
     691        typedef const _Tp&  		const_reference;
     692        typedef _Tp         		value_type;
     693        typedef free_list::__mutex_type 	__mutex_type;
     694  
     695        template<typename _Tp1>
     696          struct rebind
     697  	{
     698  	  typedef bitmap_allocator<_Tp1> other;
     699  	};
     700  
     701  #if __cplusplus >= 201103L
     702        // _GLIBCXX_RESOLVE_LIB_DEFECTS
     703        // 2103. propagate_on_container_move_assignment
     704        typedef std::true_type propagate_on_container_move_assignment;
     705  #endif
     706  
     707      private:
     708        template<std::size_t _BSize, std::size_t _AlignSize>
     709          struct aligned_size
     710  	{
     711  	  enum
     712  	    { 
     713  	      modulus = _BSize % _AlignSize,
     714  	      value = _BSize + (modulus ? _AlignSize - (modulus) : 0)
     715  	    };
     716  	};
     717  
     718        struct _Alloc_block
     719        {
     720  	char __M_unused[aligned_size<sizeof(value_type),
     721  			_BALLOC_ALIGN_BYTES>::value];
     722        };
     723  
     724  
     725        typedef typename std::pair<_Alloc_block*, _Alloc_block*> _Block_pair;
     726  
     727        typedef typename __detail::__mini_vector<_Block_pair> _BPVector;
     728        typedef typename _BPVector::iterator _BPiter;
     729  
     730        template<typename _Predicate>
     731          static _BPiter
     732          _S_find(_Predicate __p)
     733          {
     734  	  _BPiter __first = _S_mem_blocks.begin();
     735  	  while (__first != _S_mem_blocks.end() && !__p(*__first))
     736  	    ++__first;
     737  	  return __first;
     738  	}
     739  
     740  #if defined _GLIBCXX_DEBUG
     741        // Complexity: O(lg(N)). Where, N is the number of block of size
     742        // sizeof(value_type).
     743        void 
     744        _S_check_for_free_blocks() throw()
     745        {
     746  	typedef typename __detail::_Ffit_finder<_Alloc_block*> _FFF;
     747  	_BPiter __bpi = _S_find(_FFF());
     748  
     749  	_GLIBCXX_DEBUG_ASSERT(__bpi == _S_mem_blocks.end());
     750        }
     751  #endif
     752  
     753        /** @brief  Responsible for exponentially growing the internal
     754         *  memory pool.
     755         *
     756         *  @throw  std::bad_alloc. If memory cannot be allocated.
     757         *
     758         *  Complexity: O(1), but internally depends upon the
     759         *  complexity of the function free_list::_M_get. The part where
     760         *  the bitmap headers are written has complexity: O(X),where X
     761         *  is the number of blocks of size sizeof(value_type) within
     762         *  the newly acquired block. Having a tight bound.
     763         */
     764        void 
     765        _S_refill_pool() _GLIBCXX_THROW(std::bad_alloc)
     766        {
     767  	using std::size_t;
     768  #if defined _GLIBCXX_DEBUG
     769  	_S_check_for_free_blocks();
     770  #endif
     771  
     772  	const size_t __num_bitmaps = (_S_block_size
     773  				      / size_t(__detail::bits_per_block));
     774  	const size_t __size_to_allocate = sizeof(size_t) 
     775  	  + _S_block_size * sizeof(_Alloc_block) 
     776  	  + __num_bitmaps * sizeof(size_t);
     777  
     778  	size_t* __temp =
     779  	  reinterpret_cast<size_t*>(this->_M_get(__size_to_allocate));
     780  	*__temp = 0;
     781  	++__temp;
     782  
     783  	// The Header information goes at the Beginning of the Block.
     784  	_Block_pair __bp = 
     785  	  std::make_pair(reinterpret_cast<_Alloc_block*>
     786  			 (__temp + __num_bitmaps), 
     787  			 reinterpret_cast<_Alloc_block*>
     788  			 (__temp + __num_bitmaps) 
     789  			 + _S_block_size - 1);
     790  	
     791  	// Fill the Vector with this information.
     792  	_S_mem_blocks.push_back(__bp);
     793  
     794  	for (size_t __i = 0; __i < __num_bitmaps; ++__i)
     795  	  __temp[__i] = ~static_cast<size_t>(0); // 1 Indicates all Free.
     796  
     797  	_S_block_size *= 2;
     798        }
     799  
     800        static _BPVector _S_mem_blocks;
     801        static std::size_t _S_block_size;
     802        static __detail::_Bitmap_counter<_Alloc_block*> _S_last_request;
     803        static typename _BPVector::size_type _S_last_dealloc_index;
     804  #if defined __GTHREADS
     805        static __mutex_type _S_mut;
     806  #endif
     807  
     808      public:
     809  
     810        /** @brief  Allocates memory for a single object of size
     811         *  sizeof(_Tp).
     812         *
     813         *  @throw  std::bad_alloc. If memory cannot be allocated.
     814         *
     815         *  Complexity: Worst case complexity is O(N), but that
     816         *  is hardly ever hit. If and when this particular case is
     817         *  encountered, the next few cases are guaranteed to have a
     818         *  worst case complexity of O(1)!  That's why this function
     819         *  performs very well on average. You can consider this
     820         *  function to have a complexity referred to commonly as:
     821         *  Amortized Constant time.
     822         */
     823        pointer 
     824        _M_allocate_single_object() _GLIBCXX_THROW(std::bad_alloc)
     825        {
     826  	using std::size_t;
     827  #if defined __GTHREADS
     828  	__scoped_lock __bit_lock(_S_mut);
     829  #endif
     830  
     831  	// The algorithm is something like this: The last_request
     832  	// variable points to the last accessed Bit Map. When such a
     833  	// condition occurs, we try to find a free block in the
     834  	// current bitmap, or succeeding bitmaps until the last bitmap
     835  	// is reached. If no free block turns up, we resort to First
     836  	// Fit method.
     837  
     838  	// WARNING: Do not re-order the condition in the while
     839  	// statement below, because it relies on C++'s short-circuit
     840  	// evaluation. The return from _S_last_request->_M_get() will
     841  	// NOT be dereference able if _S_last_request->_M_finished()
     842  	// returns true. This would inevitably lead to a NULL pointer
     843  	// dereference if tinkered with.
     844  	while (_S_last_request._M_finished() == false
     845  	       && (*(_S_last_request._M_get()) == 0))
     846  	  _S_last_request.operator++();
     847  
     848  	if (__builtin_expect(_S_last_request._M_finished() == true, false))
     849  	  {
     850  	    // Fall Back to First Fit algorithm.
     851  	    typedef typename __detail::_Ffit_finder<_Alloc_block*> _FFF;
     852  	    _FFF __fff;
     853  	    _BPiter __bpi = _S_find(__detail::_Functor_Ref<_FFF>(__fff));
     854  
     855  	    if (__bpi != _S_mem_blocks.end())
     856  	      {
     857  		// Search was successful. Ok, now mark the first bit from
     858  		// the right as 0, meaning Allocated. This bit is obtained
     859  		// by calling _M_get() on __fff.
     860  		size_t __nz_bit = _Bit_scan_forward(*__fff._M_get());
     861  		__detail::__bit_allocate(__fff._M_get(), __nz_bit);
     862  
     863  		_S_last_request._M_reset(__bpi - _S_mem_blocks.begin());
     864  
     865  		// Now, get the address of the bit we marked as allocated.
     866  		pointer __ret = reinterpret_cast<pointer>
     867  		  (__bpi->first + __fff._M_offset() + __nz_bit);
     868  		size_t* __puse_count = 
     869  		  reinterpret_cast<size_t*>
     870  		  (__bpi->first) - (__detail::__num_bitmaps(*__bpi) + 1);
     871  		
     872  		++(*__puse_count);
     873  		return __ret;
     874  	      }
     875  	    else
     876  	      {
     877  		// Search was unsuccessful. We Add more memory to the
     878  		// pool by calling _S_refill_pool().
     879  		_S_refill_pool();
     880  
     881  		// _M_Reset the _S_last_request structure to the first
     882  		// free block's bit map.
     883  		_S_last_request._M_reset(_S_mem_blocks.size() - 1);
     884  
     885  		// Now, mark that bit as allocated.
     886  	      }
     887  	  }
     888  
     889  	// _S_last_request holds a pointer to a valid bit map, that
     890  	// points to a free block in memory.
     891  	size_t __nz_bit = _Bit_scan_forward(*_S_last_request._M_get());
     892  	__detail::__bit_allocate(_S_last_request._M_get(), __nz_bit);
     893  
     894  	pointer __ret = reinterpret_cast<pointer>
     895  	  (_S_last_request._M_base() + _S_last_request._M_offset() + __nz_bit);
     896  
     897  	size_t* __puse_count = reinterpret_cast<size_t*>
     898  	  (_S_mem_blocks[_S_last_request._M_where()].first)
     899  	  - (__detail::
     900  	     __num_bitmaps(_S_mem_blocks[_S_last_request._M_where()]) + 1);
     901  
     902  	++(*__puse_count);
     903  	return __ret;
     904        }
     905  
     906        /** @brief  Deallocates memory that belongs to a single object of
     907         *  size sizeof(_Tp).
     908         *
     909         *  Complexity: O(lg(N)), but the worst case is not hit
     910         *  often!  This is because containers usually deallocate memory
     911         *  close to each other and this case is handled in O(1) time by
     912         *  the deallocate function.
     913         */
     914        void 
     915        _M_deallocate_single_object(pointer __p) throw()
     916        {
     917  	using std::size_t;
     918  #if defined __GTHREADS
     919  	__scoped_lock __bit_lock(_S_mut);
     920  #endif
     921  	_Alloc_block* __real_p = reinterpret_cast<_Alloc_block*>(__p);
     922  
     923  	typedef typename _BPVector::iterator _Iterator;
     924  	typedef typename _BPVector::difference_type _Difference_type;
     925  
     926  	_Difference_type __diff;
     927  	long __displacement;
     928  
     929  	_GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0);
     930  
     931  	__detail::_Inclusive_between<_Alloc_block*> __ibt(__real_p);
     932  	if (__ibt(_S_mem_blocks[_S_last_dealloc_index]))
     933  	  {
     934  	    _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index
     935  				  <= _S_mem_blocks.size() - 1);
     936  
     937  	    // Initial Assumption was correct!
     938  	    __diff = _S_last_dealloc_index;
     939  	    __displacement = __real_p - _S_mem_blocks[__diff].first;
     940  	  }
     941  	else
     942  	  {
     943  	    _Iterator _iter = _S_find(__ibt);
     944  
     945  	    _GLIBCXX_DEBUG_ASSERT(_iter != _S_mem_blocks.end());
     946  
     947  	    __diff = _iter - _S_mem_blocks.begin();
     948  	    __displacement = __real_p - _S_mem_blocks[__diff].first;
     949  	    _S_last_dealloc_index = __diff;
     950  	  }
     951  
     952  	// Get the position of the iterator that has been found.
     953  	const size_t __rotate = (__displacement
     954  				 % size_t(__detail::bits_per_block));
     955  	size_t* __bitmapC = 
     956  	  reinterpret_cast<size_t*>
     957  	  (_S_mem_blocks[__diff].first) - 1;
     958  	__bitmapC -= (__displacement / size_t(__detail::bits_per_block));
     959        
     960  	__detail::__bit_free(__bitmapC, __rotate);
     961  	size_t* __puse_count = reinterpret_cast<size_t*>
     962  	  (_S_mem_blocks[__diff].first)
     963  	  - (__detail::__num_bitmaps(_S_mem_blocks[__diff]) + 1);
     964  	
     965  	_GLIBCXX_DEBUG_ASSERT(*__puse_count != 0);
     966  
     967  	--(*__puse_count);
     968  
     969  	if (__builtin_expect(*__puse_count == 0, false))
     970  	  {
     971  	    _S_block_size /= 2;
     972  	  
     973  	    // We can safely remove this block.
     974  	    // _Block_pair __bp = _S_mem_blocks[__diff];
     975  	    this->_M_insert(__puse_count);
     976  	    _S_mem_blocks.erase(_S_mem_blocks.begin() + __diff);
     977  
     978  	    // Reset the _S_last_request variable to reflect the
     979  	    // erased block. We do this to protect future requests
     980  	    // after the last block has been removed from a particular
     981  	    // memory Chunk, which in turn has been returned to the
     982  	    // free list, and hence had been erased from the vector,
     983  	    // so the size of the vector gets reduced by 1.
     984  	    if ((_Difference_type)_S_last_request._M_where() >= __diff--)
     985  	      _S_last_request._M_reset(__diff); 
     986  
     987  	    // If the Index into the vector of the region of memory
     988  	    // that might hold the next address that will be passed to
     989  	    // deallocated may have been invalidated due to the above
     990  	    // erase procedure being called on the vector, hence we
     991  	    // try to restore this invariant too.
     992  	    if (_S_last_dealloc_index >= _S_mem_blocks.size())
     993  	      {
     994  		_S_last_dealloc_index =(__diff != -1 ? __diff : 0);
     995  		_GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0);
     996  	      }
     997  	  }
     998        }
     999  
    1000      public:
    1001        bitmap_allocator() _GLIBCXX_USE_NOEXCEPT
    1002        { }
    1003  
    1004        bitmap_allocator(const bitmap_allocator&) _GLIBCXX_USE_NOEXCEPT
    1005        { }
    1006  
    1007        template<typename _Tp1>
    1008          bitmap_allocator(const bitmap_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT
    1009          { }
    1010  
    1011        ~bitmap_allocator() _GLIBCXX_USE_NOEXCEPT
    1012        { }
    1013  
    1014        _GLIBCXX_NODISCARD pointer 
    1015        allocate(size_type __n)
    1016        {
    1017  	if (__n > this->max_size())
    1018  	  std::__throw_bad_alloc();
    1019  
    1020  #if __cpp_aligned_new
    1021  	if (alignof(value_type) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
    1022  	  {
    1023  	    const size_type __b = __n * sizeof(value_type);
    1024  	    std::align_val_t __al = std::align_val_t(alignof(value_type));
    1025  	    return static_cast<pointer>(::operator new(__b, __al));
    1026  	  }
    1027  #endif
    1028  
    1029  	if (__builtin_expect(__n == 1, true))
    1030  	  return this->_M_allocate_single_object();
    1031  	else
    1032  	  { 
    1033  	    const size_type __b = __n * sizeof(value_type);
    1034  	    return reinterpret_cast<pointer>(::operator new(__b));
    1035  	  }
    1036        }
    1037  
    1038        _GLIBCXX_NODISCARD pointer 
    1039        allocate(size_type __n, typename bitmap_allocator<void>::const_pointer)
    1040        { return allocate(__n); }
    1041  
    1042        void 
    1043        deallocate(pointer __p, size_type __n) throw()
    1044        {
    1045  	if (__builtin_expect(__p != 0, true))
    1046  	  {
    1047  #if __cpp_aligned_new
    1048  	    // Types with extended alignment are handled by operator delete.
    1049  	    if (alignof(value_type) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
    1050  	      {
    1051  		::operator delete(__p, std::align_val_t(alignof(value_type)));
    1052  		return;
    1053  	      }
    1054  #endif
    1055  
    1056  	    if (__builtin_expect(__n == 1, true))
    1057  	      this->_M_deallocate_single_object(__p);
    1058  	    else
    1059  	      ::operator delete(__p);
    1060  	  }
    1061        }
    1062  
    1063        pointer 
    1064        address(reference __r) const _GLIBCXX_NOEXCEPT
    1065        { return std::__addressof(__r); }
    1066  
    1067        const_pointer 
    1068        address(const_reference __r) const _GLIBCXX_NOEXCEPT
    1069        { return std::__addressof(__r); }
    1070  
    1071        size_type 
    1072        max_size() const _GLIBCXX_USE_NOEXCEPT
    1073        { return size_type(-1) / sizeof(value_type); }
    1074  
    1075  #if __cplusplus >= 201103L
    1076        template<typename _Up, typename... _Args>
    1077          void
    1078          construct(_Up* __p, _Args&&... __args)
    1079  	{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
    1080  
    1081        template<typename _Up>
    1082          void 
    1083          destroy(_Up* __p)
    1084          { __p->~_Up(); }
    1085  #else
    1086        void 
    1087        construct(pointer __p, const_reference __data)
    1088        { ::new((void *)__p) value_type(__data); }
    1089  
    1090        void 
    1091        destroy(pointer __p)
    1092        { __p->~value_type(); }
    1093  #endif
    1094      };
    1095  
    1096    template<typename _Tp1, typename _Tp2>
    1097      bool 
    1098      operator==(const bitmap_allocator<_Tp1>&, 
    1099  	       const bitmap_allocator<_Tp2>&) throw()
    1100      { return true; }
    1101    
    1102  #if __cpp_impl_three_way_comparison < 201907L
    1103    template<typename _Tp1, typename _Tp2>
    1104      bool 
    1105      operator!=(const bitmap_allocator<_Tp1>&, 
    1106  	       const bitmap_allocator<_Tp2>&) throw() 
    1107      { return false; }
    1108  #endif
    1109  
    1110    // Static member definitions.
    1111    template<typename _Tp>
    1112      typename bitmap_allocator<_Tp>::_BPVector
    1113      bitmap_allocator<_Tp>::_S_mem_blocks;
    1114  
    1115    template<typename _Tp>
    1116      std::size_t bitmap_allocator<_Tp>::_S_block_size
    1117        = 2 * std::size_t(__detail::bits_per_block);
    1118  
    1119    template<typename _Tp>
    1120      typename bitmap_allocator<_Tp>::_BPVector::size_type 
    1121      bitmap_allocator<_Tp>::_S_last_dealloc_index = 0;
    1122  
    1123    template<typename _Tp>
    1124      __detail::_Bitmap_counter
    1125        <typename bitmap_allocator<_Tp>::_Alloc_block*>
    1126      bitmap_allocator<_Tp>::_S_last_request(_S_mem_blocks);
    1127  
    1128  #if defined __GTHREADS
    1129    template<typename _Tp>
    1130      typename bitmap_allocator<_Tp>::__mutex_type
    1131      bitmap_allocator<_Tp>::_S_mut;
    1132  #endif
    1133  
    1134  _GLIBCXX_END_NAMESPACE_VERSION
    1135  } // namespace __gnu_cxx
    1136  
    1137  #endif