30 #ifndef _BITMAP_ALLOCATOR_H
31 #define _BITMAP_ALLOCATOR_H 1
44 #define _BALLOC_ALIGN_BYTES 8
46 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
53 _GLIBCXX_BEGIN_NAMESPACE_VERSION
70 template<
typename _Tp>
77 typedef _Tp value_type;
79 typedef _Tp& reference;
80 typedef const _Tp& const_reference;
81 typedef size_t size_type;
82 typedef ptrdiff_t difference_type;
83 typedef pointer iterator;
88 pointer _M_end_of_storage;
91 _M_space_left()
const throw()
92 {
return _M_end_of_storage - _M_finish; }
95 allocate(size_type __n)
96 {
return static_cast<pointer
>(::operator
new(__n *
sizeof(_Tp))); }
99 deallocate(pointer __p, size_type)
100 { ::operator
delete(__p); }
108 : _M_start(0), _M_finish(0), _M_end_of_storage(0) { }
112 {
return _M_finish - _M_start; }
115 begin()
const throw()
116 {
return this->_M_start; }
120 {
return this->_M_finish; }
124 {
return *(this->end() - 1); }
127 operator[](
const size_type __pos)
const throw()
128 {
return this->_M_start[__pos]; }
131 insert(iterator __pos, const_reference __x);
134 push_back(const_reference __x)
136 if (this->_M_space_left())
142 this->insert(this->end(), __x);
147 { --this->_M_finish; }
150 erase(iterator __pos)
throw();
154 { this->_M_finish = this->_M_start; }
158 template<
typename _Tp>
162 if (this->_M_space_left())
164 size_type __to_move = this->_M_finish - __pos;
172 --__dest; --__src; --__to_move;
178 size_type __new_size = this->
size() ? this->
size() * 2 : 1;
179 iterator __new_start = this->allocate(__new_size);
180 iterator __first = this->
begin();
181 iterator __start = __new_start;
182 while (__first != __pos)
185 ++__start; ++__first;
189 while (__first != this->
end())
192 ++__start; ++__first;
195 this->deallocate(this->_M_start, this->
size());
197 this->_M_start = __new_start;
198 this->_M_finish = __start;
199 this->_M_end_of_storage = this->_M_start + __new_size;
203 template<
typename _Tp>
204 void __mini_vector<_Tp>::
205 erase(iterator __pos)
throw()
207 while (__pos + 1 != this->
end())
216 template<
typename _Tp>
217 struct __mv_iter_traits
219 typedef typename _Tp::value_type value_type;
220 typedef typename _Tp::difference_type difference_type;
223 template<
typename _Tp>
224 struct __mv_iter_traits<_Tp*>
226 typedef _Tp value_type;
227 typedef ptrdiff_t difference_type;
233 bits_per_block =
sizeof(size_t) *
size_t(bits_per_byte)
236 template<
typename _ForwardIterator,
typename _Tp,
typename _Compare>
238 __lower_bound(_ForwardIterator __first, _ForwardIterator __last,
239 const _Tp& __val, _Compare __comp)
241 typedef typename __mv_iter_traits<_ForwardIterator>::value_type
243 typedef typename __mv_iter_traits<_ForwardIterator>::difference_type
246 _DistanceType __len = __last - __first;
247 _DistanceType __half;
248 _ForwardIterator __middle;
255 if (__comp(*__middle, __val))
259 __len = __len - __half - 1;
270 template<
typename _AddrPair>
273 {
return (__ap.second - __ap.first) + 1; }
278 template<
typename _AddrPair>
284 template<
typename _Tp>
285 class _Inclusive_between
289 pointer _M_ptr_value;
293 _Inclusive_between(pointer __ptr) : _M_ptr_value(__ptr)
297 operator()(_Block_pair __bp)
const throw()
308 template<
typename _Functor>
311 typename _Functor::result_type>
316 typedef typename _Functor::argument_type argument_type;
317 typedef typename _Functor::result_type result_type;
319 _Functor_Ref(_Functor& __fref) : _M_fref(__fref)
323 operator()(argument_type __arg)
324 {
return _M_fref(__arg); }
334 template<
typename _Tp>
340 typedef typename _BPVector::difference_type _Counter_type;
343 _Counter_type _M_data_offset;
364 if (*(reinterpret_cast<size_t*>
368 size_t* __rover =
reinterpret_cast<size_t*
>(__bp.
first) - 1;
370 for (_Counter_type __i = 0; __i < __diff; ++__i)
372 _M_data_offset = __i;
375 _M_pbitmap = __rover;
384 _M_get()
const throw()
385 {
return _M_pbitmap; }
388 _M_offset()
const throw()
389 {
return _M_data_offset * size_t(bits_per_block); }
399 template<
typename _Tp>
404 typedef typename _BPVector::size_type _Index_type;
408 size_t* _M_curr_bmap;
409 size_t* _M_last_bmap_in_block;
410 _Index_type _M_curr_index;
417 { this->_M_reset(__index); }
420 _M_reset(
long __index = -1)
throw()
425 _M_curr_index =
static_cast<_Index_type
>(-1);
429 _M_curr_index = __index;
430 _M_curr_bmap =
reinterpret_cast<size_t*
>
431 (_M_vbp[_M_curr_index].first) - 1;
433 _GLIBCXX_DEBUG_ASSERT(__index <= (
long)_M_vbp.size() - 1);
435 _M_last_bmap_in_block = _M_curr_bmap
436 - ((_M_vbp[_M_curr_index].second
437 - _M_vbp[_M_curr_index].first + 1)
438 /
size_t(bits_per_block) - 1);
445 _M_set_internal_bitmap(
size_t* __new_internal_marker)
throw()
446 { _M_curr_bmap = __new_internal_marker; }
449 _M_finished()
const throw()
450 {
return(_M_curr_bmap == 0); }
455 if (_M_curr_bmap == _M_last_bmap_in_block)
457 if (++_M_curr_index == _M_vbp.size())
460 this->_M_reset(_M_curr_index);
468 _M_get()
const throw()
469 {
return _M_curr_bmap; }
472 _M_base()
const throw()
473 {
return _M_vbp[_M_curr_index].first; }
476 _M_offset()
const throw()
478 return size_t(bits_per_block)
479 * ((
reinterpret_cast<size_t*
>(this->_M_base())
480 - _M_curr_bmap) - 1);
484 _M_where()
const throw()
485 {
return _M_curr_index; }
494 size_t __mask = 1 << __pos;
505 size_t __mask = 1 << __pos;
509 _GLIBCXX_END_NAMESPACE_VERSION
512 _GLIBCXX_BEGIN_NAMESPACE_VERSION
518 {
return static_cast<size_t>(__builtin_ctzl(__num)); }
528 typedef size_t* value_type;
530 typedef vector_type::iterator iterator;
531 typedef __mutex __mutex_type;
534 struct _LT_pointer_compare
537 operator()(
const size_t* __pui,
538 const size_t __cui)
const throw()
539 {
return *__pui < __cui; }
542 #if defined __GTHREADS
546 static __mutex_type _S_mutex;
569 _M_validate(
size_t* __addr)
throw()
572 const vector_type::size_type __max_size = 64;
573 if (__free_list.size() >= __max_size)
577 if (*__addr >= *__free_list.back())
582 ::operator
delete(
static_cast<void*
>(__addr));
589 ::operator
delete(
static_cast<void*
>(__free_list.back()));
590 __free_list.pop_back();
595 iterator __temp = __detail::__lower_bound
596 (__free_list.begin(), __free_list.end(),
597 *__addr, _LT_pointer_compare());
600 __free_list.insert(__temp, __addr);
615 _M_should_i_give(
size_t __block_size,
616 size_t __required_size)
throw()
618 const size_t __max_wastage_percentage = 36;
619 if (__block_size >= __required_size &&
620 (((__block_size - __required_size) * 100 / __block_size)
621 < __max_wastage_percentage))
637 #if defined __GTHREADS
642 this->_M_validate(reinterpret_cast<size_t*>(__addr) - 1);
666 template<
typename _Tp>
674 typedef void* pointer;
675 typedef const void* const_pointer;
678 typedef void value_type;
679 template<
typename _Tp1>
690 template<
typename _Tp>
691 class bitmap_allocator :
private free_list
694 typedef size_t size_type;
695 typedef ptrdiff_t difference_type;
696 typedef _Tp* pointer;
697 typedef const _Tp* const_pointer;
698 typedef _Tp& reference;
699 typedef const _Tp& const_reference;
700 typedef _Tp value_type;
701 typedef free_list::__mutex_type __mutex_type;
703 template<
typename _Tp1>
706 typedef bitmap_allocator<_Tp1> other;
710 template<
size_t _BSize,
size_t _AlignSize>
715 modulus = _BSize % _AlignSize,
716 value = _BSize + (modulus ? _AlignSize - (modulus) : 0)
722 char __M_unused[aligned_size<
sizeof(value_type),
729 typedef typename __detail::__mini_vector<_Block_pair> _BPVector;
730 typedef typename _BPVector::iterator _BPiter;
732 template<
typename _Predicate>
734 _S_find(_Predicate __p)
736 _BPiter __first = _S_mem_blocks.begin();
737 while (__first != _S_mem_blocks.end() && !__p(*__first))
742 #if defined _GLIBCXX_DEBUG
746 _S_check_for_free_blocks() throw()
748 typedef typename __detail::_Ffit_finder<_Alloc_block*> _FFF;
749 _BPiter __bpi = _S_find(_FFF());
751 _GLIBCXX_DEBUG_ASSERT(__bpi == _S_mem_blocks.end());
767 _S_refill_pool() throw(std::bad_alloc)
769 #if defined _GLIBCXX_DEBUG
770 _S_check_for_free_blocks();
774 / size_t(__detail::bits_per_block));
775 const size_t __size_to_allocate =
sizeof(size_t)
776 + _S_block_size *
sizeof(_Alloc_block)
777 + __num_bitmaps *
sizeof(size_t);
780 reinterpret_cast<size_t*
>(this->
_M_get(__size_to_allocate));
787 (__temp + __num_bitmaps),
788 reinterpret_cast<_Alloc_block*>
789 (__temp + __num_bitmaps)
790 + _S_block_size - 1);
793 _S_mem_blocks.push_back(__bp);
796 __temp[__i] = ~static_cast<size_t>(0);
801 static _BPVector _S_mem_blocks;
802 static size_t _S_block_size;
803 static __detail::_Bitmap_counter<_Alloc_block*> _S_last_request;
804 static typename _BPVector::size_type _S_last_dealloc_index;
805 #if defined __GTHREADS
806 static __mutex_type _S_mut;
827 #if defined __GTHREADS
844 while (_S_last_request._M_finished() ==
false
845 && (*(_S_last_request._M_get()) == 0))
846 _S_last_request.operator++();
848 if (__builtin_expect(_S_last_request._M_finished() ==
true,
false))
853 _BPiter __bpi = _S_find(__detail::_Functor_Ref<_FFF>(__fff));
855 if (__bpi != _S_mem_blocks.end())
863 _S_last_request._M_reset(__bpi - _S_mem_blocks.begin());
866 pointer __ret =
reinterpret_cast<pointer
>
867 (__bpi->first + __fff._M_offset() + __nz_bit);
868 size_t* __puse_count =
869 reinterpret_cast<size_t*
>
883 _S_last_request._M_reset(_S_mem_blocks.size() - 1);
894 pointer __ret =
reinterpret_cast<pointer
>
895 (_S_last_request._M_base() + _S_last_request._M_offset() + __nz_bit);
897 size_t* __puse_count =
reinterpret_cast<size_t*
>
898 (_S_mem_blocks[_S_last_request._M_where()].first)
900 __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))
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&)
1006 template<
typename _Tp1>
1007 bitmap_allocator(
const bitmap_allocator<_Tp1>&) throw()
1010 ~bitmap_allocator() throw()
1014 allocate(size_type __n)
1016 if (__n > this->max_size())
1017 std::__throw_bad_alloc();
1019 if (__builtin_expect(__n == 1,
true))
1023 const size_type __b = __n *
sizeof(value_type);
1024 return reinterpret_cast<pointer
>(::operator
new(__b));
1029 allocate(size_type __n,
typename bitmap_allocator<void>::const_pointer)
1030 {
return allocate(__n); }
1033 deallocate(pointer __p, size_type __n)
throw()
1035 if (__builtin_expect(__p != 0,
true))
1037 if (__builtin_expect(__n == 1,
true))
1040 ::operator
delete(__p);
1045 address(reference __r)
const
1046 {
return std::__addressof(__r); }
1049 address(const_reference __r)
const
1050 {
return std::__addressof(__r); }
1053 max_size()
const throw()
1054 {
return size_type(-1) /
sizeof(value_type); }
1057 construct(pointer __p, const_reference __data)
1058 { ::new((
void *)__p) value_type(__data); }
1060 #ifdef __GXX_EXPERIMENTAL_CXX0X__
1061 template<
typename... _Args>
1063 construct(pointer __p, _Args&&... __args)
1064 { ::new((
void *)__p) _Tp(std::
forward<_Args>(__args)...); }
1068 destroy(pointer __p)
1069 { __p->~value_type(); }
1072 template<
typename _Tp1,
typename _Tp2>
1074 operator==(
const bitmap_allocator<_Tp1>&,
1075 const bitmap_allocator<_Tp2>&) throw()
1078 template<
typename _Tp1,
typename _Tp2>
1080 operator!=(
const bitmap_allocator<_Tp1>&,
1081 const bitmap_allocator<_Tp2>&) throw()
1085 template<
typename _Tp>
1086 typename bitmap_allocator<_Tp>::_BPVector
1087 bitmap_allocator<_Tp>::_S_mem_blocks;
1089 template<
typename _Tp>
1090 size_t bitmap_allocator<_Tp>::_S_block_size =
1091 2 * size_t(__detail::bits_per_block);
1093 template<
typename _Tp>
1094 typename bitmap_allocator<_Tp>::_BPVector::size_type
1095 bitmap_allocator<_Tp>::_S_last_dealloc_index = 0;
1097 template<
typename _Tp>
1098 __detail::_Bitmap_counter
1099 <
typename bitmap_allocator<_Tp>::_Alloc_block*>
1100 bitmap_allocator<_Tp>::_S_last_request(_S_mem_blocks);
1102 #if defined __GTHREADS
1103 template<
typename _Tp>
1104 typename bitmap_allocator<_Tp>::__mutex_type
1105 bitmap_allocator<_Tp>::_S_mut;
1108 _GLIBCXX_END_NAMESPACE_VERSION
Struct holding two objects of arbitrary type.
_T1 first
second_type is the second bound type
constexpr const _Tp * begin(initializer_list< _Tp > __ils)
Return an iterator pointing to the first element of the initilizer_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.
size_t __num_blocks(_AddrPair __ap)
The number of Blocks pointed to by the address pair passed to the function.
size_t _Bit_scan_forward(size_t __num)
Generic Version of the bsf instruction.
void __rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, forward_iterator_tag)
This is a helper function for the rotate algorithm.
Exception possibly thrown by new.bad_alloc (or classes derived from it) is used to report allocation ...
__mini_vector<> is a stripped down version of the full-fledged std::vector<>.
#define _BALLOC_ALIGN_BYTES
The constant in the expression below is the alignment required in bytes.
One of the comparison functors.
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.
void __bit_free(size_t *__pbmap, size_t __pos)
Mark a memory address as free by setting the corresponding bit in the bit-map.
constexpr size_t size() const
Returns the total number of bits.
One of the comparison functors.
pointer _M_allocate_single_object()
Allocates memory for a single object of size sizeof(_Tp).
The free list class for managing chunks of memory to be given to and returned by the bitmap_allocator...
Bitmap Allocator, primary template.
size_t __num_bitmaps(_AddrPair __ap)
The number of Bit-maps pointed to by the address pair passed to the function.
constexpr const _Tp * end(initializer_list< _Tp > __ils)
Return an iterator pointing to one past the last element of the initilizer_list.
void _M_deallocate_single_object(pointer __p)
Deallocates memory that belongs to a single object of size sizeof(_Tp).
The class which acts as a predicate for applying the first-fit memory allocation policy for the bitma...
void _M_clear()
This function just clears the internal Free List, and gives back all the memory to the OS...
_Tp && forward(typename std::remove_reference< _Tp >::type &__t)
forward (as per N3143)
void _M_insert(size_t *__addr)
This function returns the block of memory to the internal free list.
size_t * _M_get(size_t __sz)
This function gets a block of memory of the specified size from the free list.
The bitmap counter which acts as the bitmap manipulator, and manages the bit-manipulation functions a...