29 #ifndef _BITMAP_ALLOCATOR_H 30 #define _BITMAP_ALLOCATOR_H 1 43 #define _BALLOC_ALIGN_BYTES 8 45 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
47 _GLIBCXX_BEGIN_NAMESPACE_VERSION
69 template<
typename _Tp>
76 typedef _Tp value_type;
78 typedef _Tp& reference;
79 typedef const _Tp& const_reference;
80 typedef size_t size_type;
81 typedef ptrdiff_t difference_type;
82 typedef pointer iterator;
87 pointer _M_end_of_storage;
90 _M_space_left()
const throw()
91 {
return _M_end_of_storage - _M_finish; }
93 _GLIBCXX_NODISCARD pointer
94 allocate(size_type __n)
95 {
return static_cast<pointer
>(::operator
new(__n *
sizeof(_Tp))); }
98 deallocate(pointer __p, size_type)
99 { ::operator
delete(__p); }
107 : _M_start(0), _M_finish(0), _M_end_of_storage(0) { }
111 {
return _M_finish - _M_start; }
114 begin()
const throw()
115 {
return this->_M_start; }
119 {
return this->_M_finish; }
123 {
return *(this->end() - 1); }
126 operator[](
const size_type __pos)
const throw()
127 {
return this->_M_start[__pos]; }
130 insert(iterator __pos, const_reference __x);
133 push_back(const_reference __x)
135 if (this->_M_space_left())
141 this->insert(this->end(), __x);
146 { --this->_M_finish; }
149 erase(iterator __pos)
throw();
153 { this->_M_finish = this->_M_start; }
157 template<
typename _Tp>
161 if (this->_M_space_left())
163 size_type __to_move = this->_M_finish - __pos;
171 --__dest; --__src; --__to_move;
177 size_type __new_size = this->size() ? this->size() * 2 : 1;
178 iterator __new_start = this->allocate(__new_size);
179 iterator __first = this->
begin();
180 iterator __start = __new_start;
181 while (__first != __pos)
184 ++__start; ++__first;
188 while (__first != this->
end())
191 ++__start; ++__first;
194 this->deallocate(this->_M_start, this->size());
196 this->_M_start = __new_start;
197 this->_M_finish = __start;
198 this->_M_end_of_storage = this->_M_start + __new_size;
202 template<
typename _Tp>
203 void __mini_vector<_Tp>::
204 erase(iterator __pos)
throw()
206 while (__pos + 1 != this->
end())
215 template<
typename _Tp>
216 struct __mv_iter_traits
218 typedef typename _Tp::value_type value_type;
219 typedef typename _Tp::difference_type difference_type;
222 template<
typename _Tp>
223 struct __mv_iter_traits<_Tp*>
225 typedef _Tp value_type;
226 typedef ptrdiff_t difference_type;
232 bits_per_block =
sizeof(size_t) *
size_t(bits_per_byte)
235 template<
typename _ForwardIterator,
typename _Tp,
typename _Compare>
237 __lower_bound(_ForwardIterator __first, _ForwardIterator __last,
238 const _Tp& __val, _Compare __comp)
240 typedef typename __mv_iter_traits<_ForwardIterator>::difference_type
243 _DistanceType __len = __last - __first;
244 _DistanceType __half;
245 _ForwardIterator __middle;
252 if (__comp(*__middle, __val))
256 __len = __len - __half - 1;
267 template<
typename _AddrPair>
270 {
return (__ap.second - __ap.first) + 1; }
275 template<
typename _AddrPair>
281 template<
typename _Tp>
282 class _Inclusive_between
286 pointer _M_ptr_value;
290 _Inclusive_between(pointer __ptr) : _M_ptr_value(__ptr)
294 operator()(_Block_pair __bp)
const throw()
305 template<
typename _Functor>
308 typename _Functor::result_type>
313 typedef typename _Functor::argument_type argument_type;
314 typedef typename _Functor::result_type result_type;
316 _Functor_Ref(_Functor& __fref) : _M_fref(__fref)
320 operator()(argument_type __arg)
321 {
return _M_fref(__arg); }
331 template<
typename _Tp>
337 typedef typename _BPVector::difference_type _Counter_type;
340 _Counter_type _M_data_offset;
361 if (*(reinterpret_cast<size_t*>
365 size_t* __rover =
reinterpret_cast<size_t*
>(__bp.
first) - 1;
367 for (_Counter_type __i = 0; __i < __diff; ++__i)
369 _M_data_offset = __i;
372 _M_pbitmap = __rover;
381 _M_get()
const throw()
382 {
return _M_pbitmap; }
385 _M_offset()
const throw()
386 {
return _M_data_offset * size_t(bits_per_block); }
396 template<
typename _Tp>
401 typedef typename _BPVector::size_type _Index_type;
405 size_t* _M_curr_bmap;
406 size_t* _M_last_bmap_in_block;
407 _Index_type _M_curr_index;
414 { this->_M_reset(__index); }
417 _M_reset(
long __index = -1)
throw()
422 _M_curr_index =
static_cast<_Index_type
>(-1);
426 _M_curr_index = __index;
427 _M_curr_bmap =
reinterpret_cast<size_t*
> 428 (_M_vbp[_M_curr_index].first) - 1;
430 _GLIBCXX_DEBUG_ASSERT(__index <= (
long)_M_vbp.size() - 1);
432 _M_last_bmap_in_block = _M_curr_bmap
433 - ((_M_vbp[_M_curr_index].second
434 - _M_vbp[_M_curr_index].first + 1)
435 /
size_t(bits_per_block) - 1);
442 _M_set_internal_bitmap(
size_t* __new_internal_marker)
throw()
443 { _M_curr_bmap = __new_internal_marker; }
446 _M_finished()
const throw()
447 {
return(_M_curr_bmap == 0); }
452 if (_M_curr_bmap == _M_last_bmap_in_block)
454 if (++_M_curr_index == _M_vbp.size())
457 this->_M_reset(_M_curr_index);
465 _M_get()
const throw()
466 {
return _M_curr_bmap; }
469 _M_base()
const throw()
470 {
return _M_vbp[_M_curr_index].first; }
473 _M_offset()
const throw()
475 return size_t(bits_per_block)
476 * ((
reinterpret_cast<size_t*
>(this->_M_base())
477 - _M_curr_bmap) - 1);
481 _M_where()
const throw()
482 {
return _M_curr_index; }
491 size_t __mask = 1 << __pos;
502 size_t __mask = 1 << __pos;
511 {
return static_cast<size_t>(__builtin_ctzl(__num)); }
521 typedef size_t* value_type;
523 typedef vector_type::iterator iterator;
524 typedef __mutex __mutex_type;
527 struct _LT_pointer_compare
530 operator()(
const size_t* __pui,
531 const size_t __cui)
const throw()
532 {
return *__pui < __cui; }
535 #if defined __GTHREADS 539 static __mutex_type _S_mutex;
562 _M_validate(
size_t* __addr)
throw()
565 const vector_type::size_type __max_size = 64;
566 if (__free_list.size() >= __max_size)
570 if (*__addr >= *__free_list.back())
575 ::operator
delete(
static_cast<void*
>(__addr));
582 ::operator
delete(
static_cast<void*
>(__free_list.back()));
583 __free_list.pop_back();
588 iterator __temp = __detail::__lower_bound
589 (__free_list.begin(), __free_list.end(),
590 *__addr, _LT_pointer_compare());
593 __free_list.insert(__temp, __addr);
608 _M_should_i_give(
size_t __block_size,
609 size_t __required_size)
throw()
611 const size_t __max_wastage_percentage = 36;
612 if (__block_size >= __required_size &&
613 (((__block_size - __required_size) * 100 / __block_size)
614 < __max_wastage_percentage))
630 #if defined __GTHREADS 635 this->_M_validate(reinterpret_cast<size_t*>(__addr) - 1);
659 template<
typename _Tp>
667 typedef void* pointer;
668 typedef const void* const_pointer;
671 typedef void value_type;
672 template<
typename _Tp1>
683 template<
typename _Tp>
684 class bitmap_allocator :
private free_list
687 typedef size_t size_type;
688 typedef ptrdiff_t difference_type;
689 typedef _Tp* pointer;
690 typedef const _Tp* const_pointer;
691 typedef _Tp& reference;
692 typedef const _Tp& const_reference;
693 typedef _Tp value_type;
694 typedef free_list::__mutex_type __mutex_type;
696 template<
typename _Tp1>
699 typedef bitmap_allocator<_Tp1> other;
702 #if __cplusplus >= 201103L 709 template<
size_t _BSize,
size_t _AlignSize>
714 modulus = _BSize % _AlignSize,
715 value = _BSize + (modulus ? _AlignSize - (modulus) : 0)
721 char __M_unused[aligned_size<
sizeof(value_type),
728 typedef typename __detail::__mini_vector<_Block_pair> _BPVector;
729 typedef typename _BPVector::iterator _BPiter;
731 template<
typename _Predicate>
733 _S_find(_Predicate __p)
735 _BPiter __first = _S_mem_blocks.begin();
736 while (__first != _S_mem_blocks.end() && !__p(*__first))
741 #if defined _GLIBCXX_DEBUG 745 _S_check_for_free_blocks() throw()
747 typedef typename __detail::_Ffit_finder<_Alloc_block*> _FFF;
748 _BPiter __bpi = _S_find(_FFF());
750 _GLIBCXX_DEBUG_ASSERT(__bpi == _S_mem_blocks.end());
766 _S_refill_pool() _GLIBCXX_THROW(
std::bad_alloc)
768 #if defined _GLIBCXX_DEBUG 769 _S_check_for_free_blocks();
773 / size_t(__detail::bits_per_block));
774 const size_t __size_to_allocate =
sizeof(size_t)
775 + _S_block_size *
sizeof(_Alloc_block)
779 reinterpret_cast<size_t*
>(this->
_M_get(__size_to_allocate));
787 reinterpret_cast<_Alloc_block*>
789 + _S_block_size - 1);
792 _S_mem_blocks.push_back(__bp);
795 __temp[__i] = ~static_cast<size_t>(0);
800 static _BPVector _S_mem_blocks;
801 static 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;
826 #if defined __GTHREADS 843 while (_S_last_request._M_finished() ==
false 844 && (*(_S_last_request._M_get()) == 0))
845 _S_last_request.operator++();
847 if (__builtin_expect(_S_last_request._M_finished() ==
true,
false))
852 _BPiter __bpi = _S_find(__detail::_Functor_Ref<_FFF>(__fff));
854 if (__bpi != _S_mem_blocks.end())
862 _S_last_request._M_reset(__bpi - _S_mem_blocks.begin());
865 pointer __ret =
reinterpret_cast<pointer
> 866 (__bpi->first + __fff._M_offset() + __nz_bit);
867 size_t* __puse_count =
868 reinterpret_cast<size_t*
> 882 _S_last_request._M_reset(_S_mem_blocks.size() - 1);
893 pointer __ret =
reinterpret_cast<pointer
> 894 (_S_last_request._M_base() + _S_last_request._M_offset() + __nz_bit);
896 size_t* __puse_count =
reinterpret_cast<size_t*
> 897 (_S_mem_blocks[_S_last_request._M_where()].first)
899 __num_bitmaps(_S_mem_blocks[_S_last_request._M_where()]) + 1);
916 #if defined __GTHREADS 919 _Alloc_block* __real_p =
reinterpret_cast<_Alloc_block*
>(__p);
921 typedef typename _BPVector::iterator _Iterator;
922 typedef typename _BPVector::difference_type _Difference_type;
924 _Difference_type __diff;
927 _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0);
929 __detail::_Inclusive_between<_Alloc_block*> __ibt(__real_p);
930 if (__ibt(_S_mem_blocks[_S_last_dealloc_index]))
932 _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index
933 <= _S_mem_blocks.size() - 1);
936 __diff = _S_last_dealloc_index;
937 __displacement = __real_p - _S_mem_blocks[__diff].first;
941 _Iterator _iter = _S_find(__ibt);
943 _GLIBCXX_DEBUG_ASSERT(_iter != _S_mem_blocks.end());
945 __diff = _iter - _S_mem_blocks.begin();
946 __displacement = __real_p - _S_mem_blocks[__diff].first;
947 _S_last_dealloc_index = __diff;
951 const size_t __rotate = (__displacement
952 % size_t(__detail::bits_per_block));
954 reinterpret_cast<size_t*
> 955 (_S_mem_blocks[__diff].first) - 1;
956 __bitmapC -= (__displacement / size_t(__detail::bits_per_block));
959 size_t* __puse_count =
reinterpret_cast<size_t*
> 960 (_S_mem_blocks[__diff].first)
963 _GLIBCXX_DEBUG_ASSERT(*__puse_count != 0);
967 if (__builtin_expect(*__puse_count == 0,
false))
974 _S_mem_blocks.erase(_S_mem_blocks.begin() + __diff);
982 if ((_Difference_type)_S_last_request._M_where() >= __diff--)
983 _S_last_request._M_reset(__diff);
990 if (_S_last_dealloc_index >= _S_mem_blocks.size())
992 _S_last_dealloc_index =(__diff != -1 ? __diff : 0);
993 _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0);
1002 bitmap_allocator(
const bitmap_allocator&) _GLIBCXX_USE_NOEXCEPT
1005 template<
typename _Tp1>
1006 bitmap_allocator(
const bitmap_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT
1009 ~bitmap_allocator() _GLIBCXX_USE_NOEXCEPT
1012 _GLIBCXX_NODISCARD pointer
1013 allocate(size_type __n)
1015 if (__n > this->max_size())
1016 std::__throw_bad_alloc();
1018 #if __cpp_aligned_new 1019 if (
alignof(value_type) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
1021 const size_type __b = __n *
sizeof(value_type);
1022 std::align_val_t __al = std::align_val_t(
alignof(value_type));
1023 return static_cast<pointer
>(::operator
new(__b, __al));
1027 if (__builtin_expect(__n == 1,
true))
1031 const size_type __b = __n *
sizeof(value_type);
1032 return reinterpret_cast<pointer
>(::operator
new(__b));
1036 _GLIBCXX_NODISCARD pointer
1037 allocate(size_type __n,
typename bitmap_allocator<void>::const_pointer)
1038 {
return allocate(__n); }
1041 deallocate(pointer __p, size_type __n)
throw()
1043 if (__builtin_expect(__p != 0,
true))
1045 #if __cpp_aligned_new 1047 if (
alignof(value_type) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
1049 ::operator
delete(__p, std::align_val_t(
alignof(value_type)));
1054 if (__builtin_expect(__n == 1,
true))
1057 ::operator
delete(__p);
1062 address(reference __r)
const _GLIBCXX_NOEXCEPT
1066 address(const_reference __r)
const _GLIBCXX_NOEXCEPT
1070 max_size() const _GLIBCXX_USE_NOEXCEPT
1071 {
return size_type(-1) /
sizeof(value_type); }
1073 #if __cplusplus >= 201103L 1074 template<
typename _Up,
typename... _Args>
1076 construct(_Up* __p, _Args&&... __args)
1077 { ::new((
void *)__p) _Up(std::forward<_Args>(__args)...); }
1079 template<
typename _Up>
1085 construct(pointer __p, const_reference __data)
1086 { ::new((
void *)__p) value_type(__data); }
1089 destroy(pointer __p)
1090 { __p->~value_type(); }
1094 template<
typename _Tp1,
typename _Tp2>
1096 operator==(
const bitmap_allocator<_Tp1>&,
1097 const bitmap_allocator<_Tp2>&)
throw()
1100 template<
typename _Tp1,
typename _Tp2>
1102 operator!=(
const bitmap_allocator<_Tp1>&,
1103 const bitmap_allocator<_Tp2>&)
throw()
1107 template<
typename _Tp>
1108 typename bitmap_allocator<_Tp>::_BPVector
1109 bitmap_allocator<_Tp>::_S_mem_blocks;
1111 template<
typename _Tp>
1112 size_t bitmap_allocator<_Tp>::_S_block_size =
1113 2 * size_t(__detail::bits_per_block);
1115 template<
typename _Tp>
1116 typename bitmap_allocator<_Tp>::_BPVector::size_type
1117 bitmap_allocator<_Tp>::_S_last_dealloc_index = 0;
1119 template<
typename _Tp>
1120 __detail::_Bitmap_counter
1121 <
typename bitmap_allocator<_Tp>::_Alloc_block*>
1122 bitmap_allocator<_Tp>::_S_last_request(_S_mem_blocks);
1124 #if defined __GTHREADS 1125 template<
typename _Tp>
1126 typename bitmap_allocator<_Tp>::__mutex_type
1127 bitmap_allocator<_Tp>::_S_mut;
1130 _GLIBCXX_END_NAMESPACE_VERSION
constexpr const _Tp * end(initializer_list< _Tp > __ils) noexcept
Return an iterator pointing to one past the last element of the initializer_list. ...
Bitmap Allocator, primary template.
The bitmap counter which acts as the bitmap manipulator, and manages the bit-manipulation functions a...
ISO C++ entities toplevel namespace is std.
void _M_clear()
This function just clears the internal Free List, and gives back all the memory to the OS...
size_t * _M_get(size_t __sz)
This function gets a block of memory of the specified size from the free list.
void _M_deallocate_single_object(pointer __p)
Deallocates memory that belongs to a single object of size sizeof(_Tp).
_T1 first
second_type is the second bound type
constexpr const _Tp * begin(initializer_list< _Tp > __ils) noexcept
Return an iterator pointing to the first element of the initializer_list.
Exception possibly thrown by new.bad_alloc (or classes derived from it) is used to report allocation ...
size_t _Bit_scan_forward(size_t __num)
Generic Version of the bsf instruction.
pointer _M_allocate_single_object()
Allocates memory for a single object of size sizeof(_Tp).
void _M_insert(size_t *__addr)
This function returns the block of memory to the internal free list.
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.
One of the comparison functors.
__mini_vector<> is a stripped down version of the full-fledged std::vector<>.
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
GNU extensions for public use.
void __bit_free(size_t *__pbmap, size_t __pos)
Mark a memory address as free by setting the corresponding bit in the bit-map.
#define _BALLOC_ALIGN_BYTES
The constant in the expression below is the alignment required in bytes.
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.
size_t __num_blocks(_AddrPair __ap)
The number of Blocks 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...
Struct holding two objects of arbitrary type.
The free list class for managing chunks of memory to be given to and returned by the bitmap_allocator...
size_t __num_bitmaps(_AddrPair __ap)
The number of Bit-maps pointed to by the address pair passed to the function.
One of the comparison functors.