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
66 template<
typename _Tp>
73 typedef _Tp value_type;
75 typedef _Tp& reference;
76 typedef const _Tp& const_reference;
77 typedef std::size_t size_type;
78 typedef std::ptrdiff_t difference_type;
79 typedef pointer iterator;
84 pointer _M_end_of_storage;
87 _M_space_left()
const throw()
88 {
return _M_end_of_storage - _M_finish; }
90 _GLIBCXX_NODISCARD pointer
91 allocate(size_type __n)
92 {
return static_cast<pointer
>(::operator
new(__n *
sizeof(_Tp))); }
95 deallocate(pointer __p, size_type)
96 { ::operator
delete(__p); }
104 : _M_start(0), _M_finish(0), _M_end_of_storage(0) { }
108 {
return _M_finish - _M_start; }
111 begin()
const throw()
112 {
return this->_M_start; }
116 {
return this->_M_finish; }
120 {
return *(this->end() - 1); }
123 operator[](
const size_type __pos)
const throw()
124 {
return this->_M_start[__pos]; }
127 insert(iterator __pos, const_reference __x);
130 push_back(const_reference __x)
132 if (this->_M_space_left())
138 this->insert(this->end(), __x);
143 { --this->_M_finish; }
146 erase(iterator __pos)
throw();
150 { this->_M_finish = this->_M_start; }
154 template<
typename _Tp>
156 insert(iterator __pos, const_reference __x)
158 if (this->_M_space_left())
160 size_type __to_move = this->_M_finish - __pos;
161 iterator __dest = this->
end();
162 iterator __src = this->
end() - 1;
168 --__dest; --__src; --__to_move;
174 size_type __new_size = this->size() ? this->size() * 2 : 1;
175 iterator __new_start = this->allocate(__new_size);
176 iterator __first = this->
begin();
177 iterator __start = __new_start;
178 while (__first != __pos)
181 ++__start; ++__first;
185 while (__first != this->
end())
188 ++__start; ++__first;
191 this->deallocate(this->_M_start, this->size());
193 this->_M_start = __new_start;
194 this->_M_finish = __start;
195 this->_M_end_of_storage = this->_M_start + __new_size;
199 template<
typename _Tp>
200 void __mini_vector<_Tp>::
201 erase(iterator __pos)
throw()
203 while (__pos + 1 != this->
end())
212 template<
typename _Tp>
213 struct __mv_iter_traits
215 typedef typename _Tp::value_type value_type;
216 typedef typename _Tp::difference_type difference_type;
219 template<
typename _Tp>
220 struct __mv_iter_traits<_Tp*>
222 typedef _Tp value_type;
223 typedef std::ptrdiff_t difference_type;
229 bits_per_block =
sizeof(std::size_t) * std::size_t(bits_per_byte)
232 template<
typename _ForwardIterator,
typename _Tp,
typename _Compare>
234 __lower_bound(_ForwardIterator __first, _ForwardIterator __last,
235 const _Tp& __val, _Compare __comp)
237 typedef typename __mv_iter_traits<_ForwardIterator>::difference_type
240 _DistanceType __len = __last - __first;
241 _DistanceType __half;
242 _ForwardIterator __middle;
249 if (__comp(*__middle, __val))
253 __len = __len - __half - 1;
264 template<
typename _AddrPair>
267 {
return (__ap.second - __ap.first) + 1; }
272 template<
typename _AddrPair>
275 {
return __num_blocks(__ap) / std::size_t(bits_per_block); }
278 template<
typename _Tp>
279 class _Inclusive_between
283 pointer _M_ptr_value;
287 _Inclusive_between(pointer __ptr) : _M_ptr_value(__ptr)
291 operator()(_Block_pair __bp)
const throw()
302 template<
typename _Functor>
305 typename _Functor::result_type>
310 typedef typename _Functor::argument_type argument_type;
311 typedef typename _Functor::result_type result_type;
313 _Functor_Ref(_Functor& __fref) : _M_fref(__fref)
317 operator()(argument_type __arg)
318 {
return _M_fref(__arg); }
328 template<
typename _Tp>
334 typedef typename _BPVector::difference_type _Counter_type;
336 std::size_t* _M_pbitmap;
337 _Counter_type _M_data_offset;
359 if (*(
reinterpret_cast<size_t*
>
363 size_t* __rover =
reinterpret_cast<size_t*
>(__bp.
first) - 1;
365 for (_Counter_type __i = 0; __i < __diff; ++__i)
367 _M_data_offset = __i;
370 _M_pbitmap = __rover;
379 _M_get()
const throw()
380 {
return _M_pbitmap; }
383 _M_offset()
const throw()
384 {
return _M_data_offset * std::size_t(bits_per_block); }
394 template<
typename _Tp>
399 typedef typename _BPVector::size_type _Index_type;
403 std::size_t* _M_curr_bmap;
404 std::size_t* _M_last_bmap_in_block;
405 _Index_type _M_curr_index;
412 { this->_M_reset(__index); }
415 _M_reset(
long __index = -1)
throw()
420 _M_curr_index =
static_cast<_Index_type
>(-1);
424 _M_curr_index = __index;
425 _M_curr_bmap =
reinterpret_cast<std::size_t*
>
426 (_M_vbp[_M_curr_index].first) - 1;
428 _GLIBCXX_DEBUG_ASSERT(__index <= (
long)_M_vbp.size() - 1);
430 _M_last_bmap_in_block = _M_curr_bmap
431 - ((_M_vbp[_M_curr_index].second
432 - _M_vbp[_M_curr_index].first + 1)
433 / std::size_t(bits_per_block) - 1);
440 _M_set_internal_bitmap(std::size_t* __new_internal_marker)
throw()
441 { _M_curr_bmap = __new_internal_marker; }
444 _M_finished()
const throw()
445 {
return(_M_curr_bmap == 0); }
450 if (_M_curr_bmap == _M_last_bmap_in_block)
452 if (++_M_curr_index == _M_vbp.size())
455 this->_M_reset(_M_curr_index);
463 _M_get()
const throw()
464 {
return _M_curr_bmap; }
467 _M_base()
const throw()
468 {
return _M_vbp[_M_curr_index].first; }
471 _M_offset()
const throw()
473 return std::size_t(bits_per_block)
474 * ((
reinterpret_cast<std::size_t*
>(this->_M_base())
475 - _M_curr_bmap) - 1);
479 _M_where()
const throw()
480 {
return _M_curr_index; }
489 std::size_t __mask = 1 << __pos;
500 std::size_t __mask = 1 << __pos;
509 {
return static_cast<std::size_t
>(__builtin_ctzl(__num)); }
519 typedef std::size_t* value_type;
521 typedef vector_type::iterator iterator;
522 typedef __mutex __mutex_type;
525 struct _LT_pointer_compare
528 operator()(
const std::size_t* __pui,
529 const std::size_t __cui)
const throw()
530 {
return *__pui < __cui; }
533 #if defined __GTHREADS
537 static __mutex_type _S_mutex;
560 _M_validate(std::size_t* __addr)
throw()
563 const vector_type::size_type __max_size = 64;
564 if (__free_list.size() >= __max_size)
568 if (*__addr >= *__free_list.back())
573 ::operator
delete(
static_cast<void*
>(__addr));
580 ::operator
delete(
static_cast<void*
>(__free_list.back()));
581 __free_list.pop_back();
586 iterator __temp = __detail::__lower_bound
587 (__free_list.begin(), __free_list.end(),
588 *__addr, _LT_pointer_compare());
591 __free_list.insert(__temp, __addr);
606 _M_should_i_give(std::size_t __block_size,
607 std::size_t __required_size)
throw()
609 const std::size_t __max_wastage_percentage = 36;
610 if (__block_size >= __required_size &&
611 (((__block_size - __required_size) * 100 / __block_size)
612 < __max_wastage_percentage))
628 #if defined __GTHREADS
633 this->_M_validate(
reinterpret_cast<std::size_t*
>(__addr) - 1);
657 template<
typename _Tp>
665 typedef void* pointer;
666 typedef const void* const_pointer;
669 typedef void value_type;
670 template<
typename _Tp1>
681 template<
typename _Tp>
682 class bitmap_allocator :
private free_list
685 typedef std::size_t size_type;
686 typedef std::ptrdiff_t difference_type;
687 typedef _Tp* pointer;
688 typedef const _Tp* const_pointer;
689 typedef _Tp& reference;
690 typedef const _Tp& const_reference;
691 typedef _Tp value_type;
692 typedef free_list::__mutex_type __mutex_type;
694 template<
typename _Tp1>
697 typedef bitmap_allocator<_Tp1> other;
700 #if __cplusplus >= 201103L
707 template<std::
size_t _BSize, std::
size_t _AlignSize>
712 modulus = _BSize % _AlignSize,
713 value = _BSize + (modulus ? _AlignSize - (modulus) : 0)
719 char __M_unused[aligned_size<
sizeof(value_type),
726 typedef typename __detail::__mini_vector<_Block_pair> _BPVector;
727 typedef typename _BPVector::iterator _BPiter;
729 template<
typename _Predicate>
731 _S_find(_Predicate __p)
733 _BPiter __first = _S_mem_blocks.begin();
734 while (__first != _S_mem_blocks.end() && !__p(*__first))
739 #if defined _GLIBCXX_DEBUG
743 _S_check_for_free_blocks() throw()
745 typedef typename __detail::_Ffit_finder<_Alloc_block*> _FFF;
746 _BPiter __bpi = _S_find(_FFF());
748 _GLIBCXX_DEBUG_ASSERT(__bpi == _S_mem_blocks.end());
764 _S_refill_pool() _GLIBCXX_THROW(
std::bad_alloc)
767 #if defined _GLIBCXX_DEBUG
768 _S_check_for_free_blocks();
772 / size_t(__detail::bits_per_block));
773 const size_t __size_to_allocate =
sizeof(size_t)
774 + _S_block_size *
sizeof(_Alloc_block)
778 reinterpret_cast<size_t*
>(this->_M_get(__size_to_allocate));
784 std::make_pair(
reinterpret_cast<_Alloc_block*
>
786 reinterpret_cast<_Alloc_block*
>
788 + _S_block_size - 1);
791 _S_mem_blocks.push_back(__bp);
794 __temp[__i] = ~
static_cast<size_t>(0);
799 static _BPVector _S_mem_blocks;
800 static std::size_t _S_block_size;
801 static __detail::_Bitmap_counter<_Alloc_block*> _S_last_request;
802 static typename _BPVector::size_type _S_last_dealloc_index;
803 #if defined __GTHREADS
804 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);
917 #if defined __GTHREADS
920 _Alloc_block* __real_p =
reinterpret_cast<_Alloc_block*
>(__p);
922 typedef typename _BPVector::iterator _Iterator;
923 typedef typename _BPVector::difference_type _Difference_type;
925 _Difference_type __diff;
928 _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0);
930 __detail::_Inclusive_between<_Alloc_block*> __ibt(__real_p);
931 if (__ibt(_S_mem_blocks[_S_last_dealloc_index]))
933 _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index
934 <= _S_mem_blocks.size() - 1);
937 __diff = _S_last_dealloc_index;
938 __displacement = __real_p - _S_mem_blocks[__diff].first;
942 _Iterator _iter = _S_find(__ibt);
944 _GLIBCXX_DEBUG_ASSERT(_iter != _S_mem_blocks.end());
946 __diff = _iter - _S_mem_blocks.begin();
947 __displacement = __real_p - _S_mem_blocks[__diff].first;
948 _S_last_dealloc_index = __diff;
952 const size_t __rotate = (__displacement
953 % size_t(__detail::bits_per_block));
955 reinterpret_cast<size_t*
>
956 (_S_mem_blocks[__diff].first) - 1;
957 __bitmapC -= (__displacement / size_t(__detail::bits_per_block));
960 size_t* __puse_count =
reinterpret_cast<size_t*
>
961 (_S_mem_blocks[__diff].first)
964 _GLIBCXX_DEBUG_ASSERT(*__puse_count != 0);
968 if (__builtin_expect(*__puse_count == 0,
false))
974 this->_M_insert(__puse_count);
975 _S_mem_blocks.erase(_S_mem_blocks.begin() + __diff);
983 if ((_Difference_type)_S_last_request._M_where() >= __diff--)
984 _S_last_request._M_reset(__diff);
991 if (_S_last_dealloc_index >= _S_mem_blocks.size())
993 _S_last_dealloc_index =(__diff != -1 ? __diff : 0);
994 _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0);
1003 bitmap_allocator(
const bitmap_allocator&) _GLIBCXX_USE_NOEXCEPT
1006 template<
typename _Tp1>
1007 bitmap_allocator(
const bitmap_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT
1010 ~bitmap_allocator() _GLIBCXX_USE_NOEXCEPT
1013 _GLIBCXX_NODISCARD pointer
1014 allocate(size_type __n)
1016 if (__n > this->max_size())
1017 std::__throw_bad_alloc();
1019 #if __cpp_aligned_new
1020 if (
alignof(value_type) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
1022 const size_type __b = __n *
sizeof(value_type);
1023 std::align_val_t __al = std::align_val_t(
alignof(value_type));
1024 return static_cast<pointer
>(::operator
new(__b, __al));
1028 if (__builtin_expect(__n == 1,
true))
1032 const size_type __b = __n *
sizeof(value_type);
1033 return reinterpret_cast<pointer
>(::operator
new(__b));
1037 _GLIBCXX_NODISCARD pointer
1038 allocate(size_type __n,
typename bitmap_allocator<void>::const_pointer)
1039 {
return allocate(__n); }
1042 deallocate(pointer __p, size_type __n)
throw()
1044 if (__builtin_expect(__p != 0,
true))
1046 #if __cpp_aligned_new
1048 if (
alignof(value_type) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
1050 ::operator
delete(__p, std::align_val_t(
alignof(value_type)));
1055 if (__builtin_expect(__n == 1,
true))
1058 ::operator
delete(__p);
1063 address(reference __r)
const _GLIBCXX_NOEXCEPT
1067 address(const_reference __r)
const _GLIBCXX_NOEXCEPT
1071 max_size() const _GLIBCXX_USE_NOEXCEPT
1072 {
return size_type(-1) /
sizeof(value_type); }
1074 #if __cplusplus >= 201103L
1075 template<
typename _Up,
typename... _Args>
1077 construct(_Up* __p, _Args&&... __args)
1078 { ::new((
void *)__p) _Up(std::forward<_Args>(__args)...); }
1080 template<
typename _Up>
1086 construct(pointer __p, const_reference __data)
1087 { ::new((
void *)__p) value_type(__data); }
1090 destroy(pointer __p)
1091 { __p->~value_type(); }
1095 template<
typename _Tp1,
typename _Tp2>
1097 operator==(
const bitmap_allocator<_Tp1>&,
1098 const bitmap_allocator<_Tp2>&)
throw()
1101 #if __cpp_impl_three_way_comparison < 201907L
1102 template<
typename _Tp1,
typename _Tp2>
1104 operator!=(
const bitmap_allocator<_Tp1>&,
1105 const bitmap_allocator<_Tp2>&)
throw()
1110 template<
typename _Tp>
1111 typename bitmap_allocator<_Tp>::_BPVector
1112 bitmap_allocator<_Tp>::_S_mem_blocks;
1114 template<
typename _Tp>
1115 std::size_t bitmap_allocator<_Tp>::_S_block_size
1116 = 2 * std::size_t(__detail::bits_per_block);
1118 template<
typename _Tp>
1119 typename bitmap_allocator<_Tp>::_BPVector::size_type
1120 bitmap_allocator<_Tp>::_S_last_dealloc_index = 0;
1122 template<
typename _Tp>
1123 __detail::_Bitmap_counter
1124 <
typename bitmap_allocator<_Tp>::_Alloc_block*>
1125 bitmap_allocator<_Tp>::_S_last_request(_S_mem_blocks);
1127 #if defined __GTHREADS
1128 template<
typename _Tp>
1129 typename bitmap_allocator<_Tp>::__mutex_type
1130 bitmap_allocator<_Tp>::_S_mut;
1133 _GLIBCXX_END_NAMESPACE_VERSION