29 #ifndef _BITMAP_ALLOCATOR_H    30 #define _BITMAP_ALLOCATOR_H 1    43 #define _BALLOC_ALIGN_BYTES 8    45 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
    52   _GLIBCXX_BEGIN_NAMESPACE_VERSION
    68     template<
typename _Tp>
    75         typedef _Tp value_type;
    77         typedef _Tp& reference;
    78         typedef const _Tp& const_reference;
    79         typedef size_t size_type;
    80         typedef ptrdiff_t difference_type;
    81         typedef pointer iterator;
    86         pointer _M_end_of_storage;
    89         _M_space_left() 
const throw()
    90         { 
return _M_end_of_storage - _M_finish; }
    93         allocate(size_type __n)
    94         { 
return static_cast<pointer
>(::operator 
new(__n * 
sizeof(_Tp))); }
    97         deallocate(pointer __p, size_type)
    98         { ::operator 
delete(__p); }
   106         : _M_start(0), _M_finish(0), _M_end_of_storage(0) { }
   110         { 
return _M_finish - _M_start; }
   113         begin() 
const throw()
   114         { 
return this->_M_start; }
   118         { 
return this->_M_finish; }
   122         { 
return *(this->end() - 1); }
   125         operator[](
const size_type __pos) 
const throw()
   126         { 
return this->_M_start[__pos]; }
   129         insert(iterator __pos, const_reference __x);
   132         push_back(const_reference __x)
   134           if (this->_M_space_left())
   140             this->insert(this->end(), __x);
   145         { --this->_M_finish; }
   148         erase(iterator __pos) 
throw();
   152         { this->_M_finish = this->_M_start; }
   156     template<
typename _Tp>
   158       insert(iterator __pos, const_reference __x)
   160         if (this->_M_space_left())
   162             size_type __to_move = this->_M_finish - __pos;
   163             iterator __dest = this->end();
   164             iterator __src = this->end() - 1;
   170                 --__dest; --__src; --__to_move;
   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)
   183                 ++__start; ++__first;
   187             while (__first != this->end())
   190                 ++__start; ++__first;
   193               this->deallocate(this->_M_start, this->size());
   195             this->_M_start = __new_start;
   196             this->_M_finish = __start;
   197             this->_M_end_of_storage = this->_M_start + __new_size;
   201     template<
typename _Tp>
   203       erase(iterator __pos) 
throw()
   205         while (__pos + 1 != this->end())
   214     template<
typename _Tp>
   215       struct __mv_iter_traits
   217         typedef typename _Tp::value_type value_type;
   218         typedef typename _Tp::difference_type difference_type;
   221     template<
typename _Tp>
   222       struct __mv_iter_traits<_Tp*>
   224         typedef _Tp value_type;
   225         typedef ptrdiff_t difference_type;
   231         bits_per_block = 
sizeof(size_t) * 
size_t(bits_per_byte) 
   234     template<
typename _ForwardIterator, 
typename _Tp, 
typename _Compare>
   236       __lower_bound(_ForwardIterator __first, _ForwardIterator __last,
   237                     const _Tp& __val, _Compare __comp)
   239         typedef typename __mv_iter_traits<_ForwardIterator>::difference_type
   242         _DistanceType __len = __last - __first;
   243         _DistanceType __half;
   244         _ForwardIterator __middle;
   251             if (__comp(*__middle, __val))
   255                 __len = __len - __half - 1;
   266     template<
typename _AddrPair>
   269       { 
return (__ap.second - __ap.first) + 1; }
   274     template<
typename _AddrPair>
   280     template<
typename _Tp>
   281       class _Inclusive_between 
   285         pointer _M_ptr_value;
   289         _Inclusive_between(pointer __ptr) : _M_ptr_value(__ptr) 
   293         operator()(_Block_pair __bp) 
const throw()
   304     template<
typename _Functor>
   307                                    typename _Functor::result_type>
   312         typedef typename _Functor::argument_type argument_type;
   313         typedef typename _Functor::result_type result_type;
   315         _Functor_Ref(_Functor& __fref) : _M_fref(__fref) 
   319         operator()(argument_type __arg) 
   320         { 
return _M_fref(__arg); }
   330     template<
typename _Tp>
   336         typedef typename _BPVector::difference_type _Counter_type;
   339         _Counter_type _M_data_offset;
   346         operator()(_Block_pair __bp) 
throw()
   360           if (*(reinterpret_cast<size_t*>
   364           size_t* __rover = 
reinterpret_cast<size_t*
>(__bp.
first) - 1;
   366           for (_Counter_type __i = 0; __i < __diff; ++__i)
   368               _M_data_offset = __i;
   371                   _M_pbitmap = __rover;
   380         _M_get() 
const throw()
   381         { 
return _M_pbitmap; }
   384         _M_offset() 
const throw()
   385         { 
return _M_data_offset * size_t(bits_per_block); }
   395     template<
typename _Tp>
   400         typedef typename _BPVector::size_type _Index_type;
   404         size_t* _M_curr_bmap;
   405         size_t* _M_last_bmap_in_block;
   406         _Index_type _M_curr_index;
   413         { this->_M_reset(__index); }
   416         _M_reset(
long __index = -1) 
throw()
   421               _M_curr_index = 
static_cast<_Index_type
>(-1);
   425           _M_curr_index = __index;
   426           _M_curr_bmap = 
reinterpret_cast<size_t*
>   427             (_M_vbp[_M_curr_index].first) - 1;
   429           _GLIBCXX_DEBUG_ASSERT(__index <= (
long)_M_vbp.size() - 1);
   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                / 
size_t(bits_per_block) - 1);
   441         _M_set_internal_bitmap(
size_t* __new_internal_marker) 
throw()
   442         { _M_curr_bmap = __new_internal_marker; }
   445         _M_finished() 
const throw()
   446         { 
return(_M_curr_bmap == 0); }
   451           if (_M_curr_bmap == _M_last_bmap_in_block)
   453               if (++_M_curr_index == _M_vbp.size())
   456                 this->_M_reset(_M_curr_index);
   464         _M_get() 
const throw()
   465         { 
return _M_curr_bmap; }
   468         _M_base() 
const throw()
   469         { 
return _M_vbp[_M_curr_index].first; }
   472         _M_offset() 
const throw()
   474           return size_t(bits_per_block)
   475             * ((
reinterpret_cast<size_t*
>(this->_M_base()) 
   476                 - _M_curr_bmap) - 1);
   480         _M_where() 
const throw()
   481         { 
return _M_curr_index; }
   490       size_t __mask = 1 << __pos;
   501       size_t __mask = 1 << __pos;
   505   _GLIBCXX_END_NAMESPACE_VERSION
   508 _GLIBCXX_BEGIN_NAMESPACE_VERSION
   514   { 
return static_cast<size_t>(__builtin_ctzl(__num)); }
   524     typedef size_t*                             value_type;
   526     typedef vector_type::iterator               iterator;
   527     typedef __mutex                             __mutex_type;
   530     struct _LT_pointer_compare
   533       operator()(
const size_t* __pui, 
   534                  const size_t __cui) 
const throw()
   535       { 
return *__pui < __cui; }
   538 #if defined __GTHREADS   542       static __mutex_type _S_mutex;
   550       static vector_type _S_free_list;
   565     _M_validate(
size_t* __addr) 
throw()
   567       vector_type& __free_list = _M_get_free_list();
   568       const vector_type::size_type __max_size = 64;
   569       if (__free_list.size() >= __max_size)
   573           if (*__addr >= *__free_list.back())
   578               ::operator 
delete(
static_cast<void*
>(__addr));
   585               ::operator 
delete(
static_cast<void*
>(__free_list.back()));
   586               __free_list.pop_back();
   591       iterator __temp = __detail::__lower_bound
   592         (__free_list.begin(), __free_list.end(), 
   593          *__addr, _LT_pointer_compare());
   596       __free_list.insert(__temp, __addr);
   611     _M_should_i_give(
size_t __block_size, 
   612                      size_t __required_size) 
throw()
   614       const size_t __max_wastage_percentage = 36;
   615       if (__block_size >= __required_size && 
   616           (((__block_size - __required_size) * 100 / __block_size)
   617            < __max_wastage_percentage))
   633 #if defined __GTHREADS   638       this->_M_validate(reinterpret_cast<size_t*>(__addr) - 1);
   662   template<
typename _Tp> 
   670       typedef void*       pointer;
   671       typedef const void* const_pointer;
   674       typedef void  value_type;
   675       template<
typename _Tp1>
   686   template<
typename _Tp>
   690       typedef size_t                    size_type;
   691       typedef ptrdiff_t                 difference_type;
   692       typedef _Tp*                      pointer;
   693       typedef const _Tp*                const_pointer;
   694       typedef _Tp&                      reference;
   695       typedef const _Tp&                const_reference;
   696       typedef _Tp                       value_type;
   697       typedef free_list::__mutex_type   __mutex_type;
   699       template<
typename _Tp1>
   705 #if __cplusplus >= 201103L   712       template<
size_t _BSize, 
size_t _AlignSize>
   717               modulus = _BSize % _AlignSize,
   718               value = _BSize + (modulus ? _AlignSize - (modulus) : 0)
   724         char __M_unused[aligned_size<
sizeof(value_type),
   732       typedef typename _BPVector::iterator _BPiter;
   734       template<
typename _Predicate>
   736         _S_find(_Predicate __p)
   738           _BPiter __first = _S_mem_blocks.begin();
   739           while (__first != _S_mem_blocks.end() && !__p(*__first))
   744 #if defined _GLIBCXX_DEBUG   748       _S_check_for_free_blocks() throw()
   751         _BPiter __bpi = _S_find(_FFF());
   753         _GLIBCXX_DEBUG_ASSERT(__bpi == _S_mem_blocks.end());
   769       _S_refill_pool() throw(
std::bad_alloc)
   771 #if defined _GLIBCXX_DEBUG   772         _S_check_for_free_blocks();
   776                                       / size_t(__detail::bits_per_block));
   777         const size_t __size_to_allocate = 
sizeof(size_t) 
   778           + _S_block_size * 
sizeof(_Alloc_block) 
   779           + __num_bitmaps * 
sizeof(size_t);
   782           reinterpret_cast<size_t*
>(this->_M_get(__size_to_allocate));
   789                          (__temp + __num_bitmaps), 
   790                          reinterpret_cast<_Alloc_block*>
   791                          (__temp + __num_bitmaps) 
   792                          + _S_block_size - 1);
   795         _S_mem_blocks.push_back(__bp);
   798           __temp[__i] = ~static_cast<size_t>(0); 
   803       static _BPVector _S_mem_blocks;
   804       static size_t _S_block_size;
   806       static typename _BPVector::size_type _S_last_dealloc_index;
   807 #if defined __GTHREADS   808       static __mutex_type _S_mut;
   829 #if defined __GTHREADS   846         while (_S_last_request._M_finished() == 
false   847                && (*(_S_last_request._M_get()) == 0))
   848           _S_last_request.operator++();
   850         if (__builtin_expect(_S_last_request._M_finished() == 
true, 
false))
   855             _BPiter __bpi = _S_find(__detail::_Functor_Ref<_FFF>(__fff));
   857             if (__bpi != _S_mem_blocks.end())
   865                 _S_last_request._M_reset(__bpi - _S_mem_blocks.begin());
   868                 pointer __ret = 
reinterpret_cast<pointer
>   869                   (__bpi->first + __fff._M_offset() + __nz_bit);
   870                 size_t* __puse_count = 
   871                   reinterpret_cast<size_t*
>   885                 _S_last_request._M_reset(_S_mem_blocks.size() - 1);
   896         pointer __ret = 
reinterpret_cast<pointer
>   897           (_S_last_request._M_base() + _S_last_request._M_offset() + __nz_bit);
   899         size_t* __puse_count = 
reinterpret_cast<size_t*
>   900           (_S_mem_blocks[_S_last_request._M_where()].first)
   902              __num_bitmaps(_S_mem_blocks[_S_last_request._M_where()]) + 1);
   919 #if defined __GTHREADS   922         _Alloc_block* __real_p = 
reinterpret_cast<_Alloc_block*
>(__p);
   924         typedef typename _BPVector::iterator _Iterator;
   925         typedef typename _BPVector::difference_type _Difference_type;
   927         _Difference_type __diff;
   930         _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0);
   932         __detail::_Inclusive_between<_Alloc_block*> __ibt(__real_p);
   933         if (__ibt(_S_mem_blocks[_S_last_dealloc_index]))
   935             _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index
   936                                   <= _S_mem_blocks.size() - 1);
   939             __diff = _S_last_dealloc_index;
   940             __displacement = __real_p - _S_mem_blocks[__diff].first;
   944             _Iterator _iter = _S_find(__ibt);
   946             _GLIBCXX_DEBUG_ASSERT(_iter != _S_mem_blocks.end());
   948             __diff = _iter - _S_mem_blocks.begin();
   949             __displacement = __real_p - _S_mem_blocks[__diff].first;
   950             _S_last_dealloc_index = __diff;
   954         const size_t __rotate = (__displacement
   955                                  % size_t(__detail::bits_per_block));
   957           reinterpret_cast<size_t*
>   958           (_S_mem_blocks[__diff].first) - 1;
   959         __bitmapC -= (__displacement / size_t(__detail::bits_per_block));
   962         size_t* __puse_count = 
reinterpret_cast<size_t*
>   963           (_S_mem_blocks[__diff].first)
   966         _GLIBCXX_DEBUG_ASSERT(*__puse_count != 0);
   970         if (__builtin_expect(*__puse_count == 0, 
false))
   976             this->_M_insert(__puse_count);
   977             _S_mem_blocks.erase(_S_mem_blocks.begin() + __diff);
   985             if ((_Difference_type)_S_last_request._M_where() >= __diff--)
   986               _S_last_request._M_reset(__diff); 
   993             if (_S_last_dealloc_index >= _S_mem_blocks.size())
   995                 _S_last_dealloc_index =(__diff != -1 ? __diff : 0);
   996                 _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0);
  1008       template<
typename _Tp1>
  1016       allocate(size_type __n)
  1018         if (__n > this->max_size())
  1019           std::__throw_bad_alloc();
  1021         if (__builtin_expect(__n == 1, 
true))
  1022           return this->_M_allocate_single_object();
  1025             const size_type __b = __n * 
sizeof(value_type);
  1026             return reinterpret_cast<pointer
>(::operator 
new(__b));
  1031       allocate(size_type __n, 
typename bitmap_allocator<void>::const_pointer)
  1032       { 
return allocate(__n); }
  1035       deallocate(pointer __p, size_type __n) 
throw()
  1037         if (__builtin_expect(__p != 0, 
true))
  1039             if (__builtin_expect(__n == 1, 
true))
  1040               this->_M_deallocate_single_object(__p);
  1042               ::operator 
delete(__p);
  1047       address(reference __r) 
const _GLIBCXX_NOEXCEPT
  1051       address(const_reference __r) 
const _GLIBCXX_NOEXCEPT
  1055       max_size() 
const _GLIBCXX_USE_NOEXCEPT
  1056       { 
return size_type(-1) / 
sizeof(value_type); }
  1058 #if __cplusplus >= 201103L  1059       template<
typename _Up, 
typename... _Args>
  1061         construct(_Up* __p, _Args&&... __args)
  1062         { ::new((
void *)__p) _Up(std::forward<_Args>(__args)...); }
  1064       template<
typename _Up>
  1070       construct(pointer __p, const_reference __data)
  1071       { ::new((
void *)__p) value_type(__data); }
  1074       destroy(pointer __p)
  1075       { __p->~value_type(); }
  1079   template<
typename _Tp1, 
typename _Tp2>
  1085   template<
typename _Tp1, 
typename _Tp2>
  1092   template<
typename _Tp>
  1096   template<
typename _Tp>
  1098     2 * size_t(__detail::bits_per_block);
  1100   template<
typename _Tp>
  1101     typename bitmap_allocator<_Tp>::_BPVector::size_type 
  1104   template<
typename _Tp>
  1109 #if defined __GTHREADS  1110   template<
typename _Tp>
  1111     typename bitmap_allocator<_Tp>::__mutex_type
  1115 _GLIBCXX_END_NAMESPACE_VERSION
 
__mini_vector<> is a stripped down version of the full-fledged std::vector<>. 
size_t _Bit_scan_forward(size_t __num)
Generic Version of the bsf instruction. 
size_t __num_blocks(_AddrPair __ap)
The number of Blocks pointed to by the address pair passed to the function. 
One of the comparison functors. 
The free list class for managing chunks of memory to be given to and returned by the bitmap_allocator...
GNU extensions for public use. 
void _M_insert(size_t *__addr)
This function returns the block of memory to the internal free list. 
_T1 first
second_type is the second bound type 
pointer _M_allocate_single_object()
Allocates memory for a single object of size sizeof(_Tp). 
void _M_deallocate_single_object(pointer __p)
Deallocates memory that belongs to a single object of size sizeof(_Tp). 
#define _BALLOC_ALIGN_BYTES
The constant in the expression below is the alignment required in bytes. 
Bitmap Allocator, primary template. 
_Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof. 
size_t __num_bitmaps(_AddrPair __ap)
The number of Bit-maps pointed to by the address pair passed to the function. 
The class which acts as a predicate for applying the first-fit memory allocation policy for the bitma...
void __bit_allocate(size_t *__pbmap, size_t __pos)
Mark a memory address as allocated by re-setting the corresponding bit in the bit-map. 
Exception possibly thrown by new.bad_alloc (or classes derived from it) is used to report allocation ...
Struct holding two objects of arbitrary type. 
One of the comparison functors. 
void __bit_free(size_t *__pbmap, size_t __pos)
Mark a memory address as free by setting the corresponding bit in the bit-map. 
The bitmap counter which acts as the bitmap manipulator, and manages the bit-manipulation functions a...
constexpr pair< typename __decay_and_strip< _T1 >::__type, typename __decay_and_strip< _T2 >::__type > make_pair(_T1 &&__x, _T2 &&__y)
A convenience wrapper for creating a pair from two objects. 
ISO C++ entities toplevel namespace is std.