00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef _BITMAP_ALLOCATOR_H
00031 #define _BITMAP_ALLOCATOR_H 1
00032
00033 #include <utility>
00034 #include <bits/functexcept.h>
00035 #include <functional>
00036 #include <new>
00037 #include <debug/debug.h>
00038 #include <ext/concurrence.h>
00039 #include <bits/move.h>
00040
00041
00042
00043
00044 #define _BALLOC_ALIGN_BYTES 8
00045
00046 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
00047
00048 using std::size_t;
00049 using std::ptrdiff_t;
00050
00051 namespace __detail
00052 {
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 template<typename _Tp>
00070 class __mini_vector
00071 {
00072 __mini_vector(const __mini_vector&);
00073 __mini_vector& operator=(const __mini_vector&);
00074
00075 public:
00076 typedef _Tp value_type;
00077 typedef _Tp* pointer;
00078 typedef _Tp& reference;
00079 typedef const _Tp& const_reference;
00080 typedef size_t size_type;
00081 typedef ptrdiff_t difference_type;
00082 typedef pointer iterator;
00083
00084 private:
00085 pointer _M_start;
00086 pointer _M_finish;
00087 pointer _M_end_of_storage;
00088
00089 size_type
00090 _M_space_left() const throw()
00091 { return _M_end_of_storage - _M_finish; }
00092
00093 pointer
00094 allocate(size_type __n)
00095 { return static_cast<pointer>(::operator new(__n * sizeof(_Tp))); }
00096
00097 void
00098 deallocate(pointer __p, size_type)
00099 { ::operator delete(__p); }
00100
00101 public:
00102
00103
00104
00105
00106 __mini_vector()
00107 : _M_start(0), _M_finish(0), _M_end_of_storage(0) { }
00108
00109 size_type
00110 size() const throw()
00111 { return _M_finish - _M_start; }
00112
00113 iterator
00114 begin() const throw()
00115 { return this->_M_start; }
00116
00117 iterator
00118 end() const throw()
00119 { return this->_M_finish; }
00120
00121 reference
00122 back() const throw()
00123 { return *(this->end() - 1); }
00124
00125 reference
00126 operator[](const size_type __pos) const throw()
00127 { return this->_M_start[__pos]; }
00128
00129 void
00130 insert(iterator __pos, const_reference __x);
00131
00132 void
00133 push_back(const_reference __x)
00134 {
00135 if (this->_M_space_left())
00136 {
00137 *this->end() = __x;
00138 ++this->_M_finish;
00139 }
00140 else
00141 this->insert(this->end(), __x);
00142 }
00143
00144 void
00145 pop_back() throw()
00146 { --this->_M_finish; }
00147
00148 void
00149 erase(iterator __pos) throw();
00150
00151 void
00152 clear() throw()
00153 { this->_M_finish = this->_M_start; }
00154 };
00155
00156
00157 template<typename _Tp>
00158 void __mini_vector<_Tp>::
00159 insert(iterator __pos, const_reference __x)
00160 {
00161 if (this->_M_space_left())
00162 {
00163 size_type __to_move = this->_M_finish - __pos;
00164 iterator __dest = this->end();
00165 iterator __src = this->end() - 1;
00166
00167 ++this->_M_finish;
00168 while (__to_move)
00169 {
00170 *__dest = *__src;
00171 --__dest; --__src; --__to_move;
00172 }
00173 *__pos = __x;
00174 }
00175 else
00176 {
00177 size_type __new_size = this->size() ? this->size() * 2 : 1;
00178 iterator __new_start = this->allocate(__new_size);
00179 iterator __first = this->begin();
00180 iterator __start = __new_start;
00181 while (__first != __pos)
00182 {
00183 *__start = *__first;
00184 ++__start; ++__first;
00185 }
00186 *__start = __x;
00187 ++__start;
00188 while (__first != this->end())
00189 {
00190 *__start = *__first;
00191 ++__start; ++__first;
00192 }
00193 if (this->_M_start)
00194 this->deallocate(this->_M_start, this->size());
00195
00196 this->_M_start = __new_start;
00197 this->_M_finish = __start;
00198 this->_M_end_of_storage = this->_M_start + __new_size;
00199 }
00200 }
00201
00202 template<typename _Tp>
00203 void __mini_vector<_Tp>::
00204 erase(iterator __pos) throw()
00205 {
00206 while (__pos + 1 != this->end())
00207 {
00208 *__pos = __pos[1];
00209 ++__pos;
00210 }
00211 --this->_M_finish;
00212 }
00213
00214
00215 template<typename _Tp>
00216 struct __mv_iter_traits
00217 {
00218 typedef typename _Tp::value_type value_type;
00219 typedef typename _Tp::difference_type difference_type;
00220 };
00221
00222 template<typename _Tp>
00223 struct __mv_iter_traits<_Tp*>
00224 {
00225 typedef _Tp value_type;
00226 typedef ptrdiff_t difference_type;
00227 };
00228
00229 enum
00230 {
00231 bits_per_byte = 8,
00232 bits_per_block = sizeof(size_t) * size_t(bits_per_byte)
00233 };
00234
00235 template<typename _ForwardIterator, typename _Tp, typename _Compare>
00236 _ForwardIterator
00237 __lower_bound(_ForwardIterator __first, _ForwardIterator __last,
00238 const _Tp& __val, _Compare __comp)
00239 {
00240 typedef typename __mv_iter_traits<_ForwardIterator>::value_type
00241 _ValueType;
00242 typedef typename __mv_iter_traits<_ForwardIterator>::difference_type
00243 _DistanceType;
00244
00245 _DistanceType __len = __last - __first;
00246 _DistanceType __half;
00247 _ForwardIterator __middle;
00248
00249 while (__len > 0)
00250 {
00251 __half = __len >> 1;
00252 __middle = __first;
00253 __middle += __half;
00254 if (__comp(*__middle, __val))
00255 {
00256 __first = __middle;
00257 ++__first;
00258 __len = __len - __half - 1;
00259 }
00260 else
00261 __len = __half;
00262 }
00263 return __first;
00264 }
00265
00266
00267
00268
00269 template<typename _AddrPair>
00270 inline size_t
00271 __num_blocks(_AddrPair __ap)
00272 { return (__ap.second - __ap.first) + 1; }
00273
00274
00275
00276
00277 template<typename _AddrPair>
00278 inline size_t
00279 __num_bitmaps(_AddrPair __ap)
00280 { return __num_blocks(__ap) / size_t(bits_per_block); }
00281
00282
00283 template<typename _Tp>
00284 class _Inclusive_between
00285 : public std::unary_function<typename std::pair<_Tp, _Tp>, bool>
00286 {
00287 typedef _Tp pointer;
00288 pointer _M_ptr_value;
00289 typedef typename std::pair<_Tp, _Tp> _Block_pair;
00290
00291 public:
00292 _Inclusive_between(pointer __ptr) : _M_ptr_value(__ptr)
00293 { }
00294
00295 bool
00296 operator()(_Block_pair __bp) const throw()
00297 {
00298 if (std::less_equal<pointer>()(_M_ptr_value, __bp.second)
00299 && std::greater_equal<pointer>()(_M_ptr_value, __bp.first))
00300 return true;
00301 else
00302 return false;
00303 }
00304 };
00305
00306
00307 template<typename _Functor>
00308 class _Functor_Ref
00309 : public std::unary_function<typename _Functor::argument_type,
00310 typename _Functor::result_type>
00311 {
00312 _Functor& _M_fref;
00313
00314 public:
00315 typedef typename _Functor::argument_type argument_type;
00316 typedef typename _Functor::result_type result_type;
00317
00318 _Functor_Ref(_Functor& __fref) : _M_fref(__fref)
00319 { }
00320
00321 result_type
00322 operator()(argument_type __arg)
00323 { return _M_fref(__arg); }
00324 };
00325
00326
00327
00328
00329
00330
00331
00332
00333 template<typename _Tp>
00334 class _Ffit_finder
00335 : public std::unary_function<typename std::pair<_Tp, _Tp>, bool>
00336 {
00337 typedef typename std::pair<_Tp, _Tp> _Block_pair;
00338 typedef typename __detail::__mini_vector<_Block_pair> _BPVector;
00339 typedef typename _BPVector::difference_type _Counter_type;
00340
00341 size_t* _M_pbitmap;
00342 _Counter_type _M_data_offset;
00343
00344 public:
00345 _Ffit_finder() : _M_pbitmap(0), _M_data_offset(0)
00346 { }
00347
00348 bool
00349 operator()(_Block_pair __bp) throw()
00350 {
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 _Counter_type __diff = __detail::__num_bitmaps(__bp);
00362
00363 if (*(reinterpret_cast<size_t*>
00364 (__bp.first) - (__diff + 1)) == __detail::__num_blocks(__bp))
00365 return false;
00366
00367 size_t* __rover = reinterpret_cast<size_t*>(__bp.first) - 1;
00368
00369 for (_Counter_type __i = 0; __i < __diff; ++__i)
00370 {
00371 _M_data_offset = __i;
00372 if (*__rover)
00373 {
00374 _M_pbitmap = __rover;
00375 return true;
00376 }
00377 --__rover;
00378 }
00379 return false;
00380 }
00381
00382 size_t*
00383 _M_get() const throw()
00384 { return _M_pbitmap; }
00385
00386 _Counter_type
00387 _M_offset() const throw()
00388 { return _M_data_offset * size_t(bits_per_block); }
00389 };
00390
00391
00392
00393
00394
00395
00396
00397
00398 template<typename _Tp>
00399 class _Bitmap_counter
00400 {
00401 typedef typename
00402 __detail::__mini_vector<typename std::pair<_Tp, _Tp> > _BPVector;
00403 typedef typename _BPVector::size_type _Index_type;
00404 typedef _Tp pointer;
00405
00406 _BPVector& _M_vbp;
00407 size_t* _M_curr_bmap;
00408 size_t* _M_last_bmap_in_block;
00409 _Index_type _M_curr_index;
00410
00411 public:
00412
00413
00414
00415 _Bitmap_counter(_BPVector& Rvbp, long __index = -1) : _M_vbp(Rvbp)
00416 { this->_M_reset(__index); }
00417
00418 void
00419 _M_reset(long __index = -1) throw()
00420 {
00421 if (__index == -1)
00422 {
00423 _M_curr_bmap = 0;
00424 _M_curr_index = static_cast<_Index_type>(-1);
00425 return;
00426 }
00427
00428 _M_curr_index = __index;
00429 _M_curr_bmap = reinterpret_cast<size_t*>
00430 (_M_vbp[_M_curr_index].first) - 1;
00431
00432 _GLIBCXX_DEBUG_ASSERT(__index <= (long)_M_vbp.size() - 1);
00433
00434 _M_last_bmap_in_block = _M_curr_bmap
00435 - ((_M_vbp[_M_curr_index].second
00436 - _M_vbp[_M_curr_index].first + 1)
00437 / size_t(bits_per_block) - 1);
00438 }
00439
00440
00441
00442
00443 void
00444 _M_set_internal_bitmap(size_t* __new_internal_marker) throw()
00445 { _M_curr_bmap = __new_internal_marker; }
00446
00447 bool
00448 _M_finished() const throw()
00449 { return(_M_curr_bmap == 0); }
00450
00451 _Bitmap_counter&
00452 operator++() throw()
00453 {
00454 if (_M_curr_bmap == _M_last_bmap_in_block)
00455 {
00456 if (++_M_curr_index == _M_vbp.size())
00457 _M_curr_bmap = 0;
00458 else
00459 this->_M_reset(_M_curr_index);
00460 }
00461 else
00462 --_M_curr_bmap;
00463 return *this;
00464 }
00465
00466 size_t*
00467 _M_get() const throw()
00468 { return _M_curr_bmap; }
00469
00470 pointer
00471 _M_base() const throw()
00472 { return _M_vbp[_M_curr_index].first; }
00473
00474 _Index_type
00475 _M_offset() const throw()
00476 {
00477 return size_t(bits_per_block)
00478 * ((reinterpret_cast<size_t*>(this->_M_base())
00479 - _M_curr_bmap) - 1);
00480 }
00481
00482 _Index_type
00483 _M_where() const throw()
00484 { return _M_curr_index; }
00485 };
00486
00487
00488
00489
00490 inline void
00491 __bit_allocate(size_t* __pbmap, size_t __pos) throw()
00492 {
00493 size_t __mask = 1 << __pos;
00494 __mask = ~__mask;
00495 *__pbmap &= __mask;
00496 }
00497
00498
00499
00500
00501 inline void
00502 __bit_free(size_t* __pbmap, size_t __pos) throw()
00503 {
00504 size_t __mask = 1 << __pos;
00505 *__pbmap |= __mask;
00506 }
00507 }
00508
00509
00510
00511 inline size_t
00512 _Bit_scan_forward(size_t __num)
00513 { return static_cast<size_t>(__builtin_ctzl(__num)); }
00514
00515
00516
00517
00518
00519
00520 class free_list
00521 {
00522 public:
00523 typedef size_t* value_type;
00524 typedef __detail::__mini_vector<value_type> vector_type;
00525 typedef vector_type::iterator iterator;
00526 typedef __mutex __mutex_type;
00527
00528 private:
00529 struct _LT_pointer_compare
00530 {
00531 bool
00532 operator()(const size_t* __pui,
00533 const size_t __cui) const throw()
00534 { return *__pui < __cui; }
00535 };
00536
00537 #if defined __GTHREADS
00538 __mutex_type&
00539 _M_get_mutex()
00540 {
00541 static __mutex_type _S_mutex;
00542 return _S_mutex;
00543 }
00544 #endif
00545
00546 vector_type&
00547 _M_get_free_list()
00548 {
00549 static vector_type _S_free_list;
00550 return _S_free_list;
00551 }
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563 void
00564 _M_validate(size_t* __addr) throw()
00565 {
00566 vector_type& __free_list = _M_get_free_list();
00567 const vector_type::size_type __max_size = 64;
00568 if (__free_list.size() >= __max_size)
00569 {
00570
00571
00572 if (*__addr >= *__free_list.back())
00573 {
00574
00575
00576
00577 ::operator delete(static_cast<void*>(__addr));
00578 return;
00579 }
00580 else
00581 {
00582
00583
00584 ::operator delete(static_cast<void*>(__free_list.back()));
00585 __free_list.pop_back();
00586 }
00587 }
00588
00589
00590 iterator __temp = __detail::__lower_bound
00591 (__free_list.begin(), __free_list.end(),
00592 *__addr, _LT_pointer_compare());
00593
00594
00595 __free_list.insert(__temp, __addr);
00596 }
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609 bool
00610 _M_should_i_give(size_t __block_size,
00611 size_t __required_size) throw()
00612 {
00613 const size_t __max_wastage_percentage = 36;
00614 if (__block_size >= __required_size &&
00615 (((__block_size - __required_size) * 100 / __block_size)
00616 < __max_wastage_percentage))
00617 return true;
00618 else
00619 return false;
00620 }
00621
00622 public:
00623
00624
00625
00626
00627
00628
00629 inline void
00630 _M_insert(size_t* __addr) throw()
00631 {
00632 #if defined __GTHREADS
00633 __scoped_lock __bfl_lock(_M_get_mutex());
00634 #endif
00635
00636
00637 this->_M_validate(reinterpret_cast<size_t*>(__addr) - 1);
00638
00639 }
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649 size_t*
00650 _M_get(size_t __sz) throw(std::bad_alloc);
00651
00652
00653
00654
00655 void
00656 _M_clear();
00657 };
00658
00659
00660
00661 template<typename _Tp>
00662 class bitmap_allocator;
00663
00664
00665 template<>
00666 class bitmap_allocator<void>
00667 {
00668 public:
00669 typedef void* pointer;
00670 typedef const void* const_pointer;
00671
00672
00673 typedef void value_type;
00674 template<typename _Tp1>
00675 struct rebind
00676 {
00677 typedef bitmap_allocator<_Tp1> other;
00678 };
00679 };
00680
00681
00682
00683
00684
00685 template<typename _Tp>
00686 class bitmap_allocator : private free_list
00687 {
00688 public:
00689 typedef size_t size_type;
00690 typedef ptrdiff_t difference_type;
00691 typedef _Tp* pointer;
00692 typedef const _Tp* const_pointer;
00693 typedef _Tp& reference;
00694 typedef const _Tp& const_reference;
00695 typedef _Tp value_type;
00696 typedef free_list::__mutex_type __mutex_type;
00697
00698 template<typename _Tp1>
00699 struct rebind
00700 {
00701 typedef bitmap_allocator<_Tp1> other;
00702 };
00703
00704 private:
00705 template<size_t _BSize, size_t _AlignSize>
00706 struct aligned_size
00707 {
00708 enum
00709 {
00710 modulus = _BSize % _AlignSize,
00711 value = _BSize + (modulus ? _AlignSize - (modulus) : 0)
00712 };
00713 };
00714
00715 struct _Alloc_block
00716 {
00717 char __M_unused[aligned_size<sizeof(value_type),
00718 _BALLOC_ALIGN_BYTES>::value];
00719 };
00720
00721
00722 typedef typename std::pair<_Alloc_block*, _Alloc_block*> _Block_pair;
00723
00724 typedef typename __detail::__mini_vector<_Block_pair> _BPVector;
00725 typedef typename _BPVector::iterator _BPiter;
00726
00727 template<typename _Predicate>
00728 static _BPiter
00729 _S_find(_Predicate __p)
00730 {
00731 _BPiter __first = _S_mem_blocks.begin();
00732 while (__first != _S_mem_blocks.end() && !__p(*__first))
00733 ++__first;
00734 return __first;
00735 }
00736
00737 #if defined _GLIBCXX_DEBUG
00738
00739
00740 void
00741 _S_check_for_free_blocks() throw()
00742 {
00743 typedef typename __detail::_Ffit_finder<_Alloc_block*> _FFF;
00744 _BPiter __bpi = _S_find(_FFF());
00745
00746 _GLIBCXX_DEBUG_ASSERT(__bpi == _S_mem_blocks.end());
00747 }
00748 #endif
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761 void
00762 _S_refill_pool() throw(std::bad_alloc)
00763 {
00764 #if defined _GLIBCXX_DEBUG
00765 _S_check_for_free_blocks();
00766 #endif
00767
00768 const size_t __num_bitmaps = (_S_block_size
00769 / size_t(__detail::bits_per_block));
00770 const size_t __size_to_allocate = sizeof(size_t)
00771 + _S_block_size * sizeof(_Alloc_block)
00772 + __num_bitmaps * sizeof(size_t);
00773
00774 size_t* __temp =
00775 reinterpret_cast<size_t*>(this->_M_get(__size_to_allocate));
00776 *__temp = 0;
00777 ++__temp;
00778
00779
00780 _Block_pair __bp =
00781 std::make_pair(reinterpret_cast<_Alloc_block*>
00782 (__temp + __num_bitmaps),
00783 reinterpret_cast<_Alloc_block*>
00784 (__temp + __num_bitmaps)
00785 + _S_block_size - 1);
00786
00787
00788 _S_mem_blocks.push_back(__bp);
00789
00790 for (size_t __i = 0; __i < __num_bitmaps; ++__i)
00791 __temp[__i] = ~static_cast<size_t>(0);
00792
00793 _S_block_size *= 2;
00794 }
00795
00796 static _BPVector _S_mem_blocks;
00797 static size_t _S_block_size;
00798 static __detail::_Bitmap_counter<_Alloc_block*> _S_last_request;
00799 static typename _BPVector::size_type _S_last_dealloc_index;
00800 #if defined __GTHREADS
00801 static __mutex_type _S_mut;
00802 #endif
00803
00804 public:
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819 pointer
00820 _M_allocate_single_object() throw(std::bad_alloc)
00821 {
00822 #if defined __GTHREADS
00823 __scoped_lock __bit_lock(_S_mut);
00824 #endif
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839 while (_S_last_request._M_finished() == false
00840 && (*(_S_last_request._M_get()) == 0))
00841 _S_last_request.operator++();
00842
00843 if (__builtin_expect(_S_last_request._M_finished() == true, false))
00844 {
00845
00846 typedef typename __detail::_Ffit_finder<_Alloc_block*> _FFF;
00847 _FFF __fff;
00848 _BPiter __bpi = _S_find(__detail::_Functor_Ref<_FFF>(__fff));
00849
00850 if (__bpi != _S_mem_blocks.end())
00851 {
00852
00853
00854
00855 size_t __nz_bit = _Bit_scan_forward(*__fff._M_get());
00856 __detail::__bit_allocate(__fff._M_get(), __nz_bit);
00857
00858 _S_last_request._M_reset(__bpi - _S_mem_blocks.begin());
00859
00860
00861 pointer __ret = reinterpret_cast<pointer>
00862 (__bpi->first + __fff._M_offset() + __nz_bit);
00863 size_t* __puse_count =
00864 reinterpret_cast<size_t*>
00865 (__bpi->first) - (__detail::__num_bitmaps(*__bpi) + 1);
00866
00867 ++(*__puse_count);
00868 return __ret;
00869 }
00870 else
00871 {
00872
00873
00874 _S_refill_pool();
00875
00876
00877
00878 _S_last_request._M_reset(_S_mem_blocks.size() - 1);
00879
00880
00881 }
00882 }
00883
00884
00885
00886 size_t __nz_bit = _Bit_scan_forward(*_S_last_request._M_get());
00887 __detail::__bit_allocate(_S_last_request._M_get(), __nz_bit);
00888
00889 pointer __ret = reinterpret_cast<pointer>
00890 (_S_last_request._M_base() + _S_last_request._M_offset() + __nz_bit);
00891
00892 size_t* __puse_count = reinterpret_cast<size_t*>
00893 (_S_mem_blocks[_S_last_request._M_where()].first)
00894 - (__detail::
00895 __num_bitmaps(_S_mem_blocks[_S_last_request._M_where()]) + 1);
00896
00897 ++(*__puse_count);
00898 return __ret;
00899 }
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909 void
00910 _M_deallocate_single_object(pointer __p) throw()
00911 {
00912 #if defined __GTHREADS
00913 __scoped_lock __bit_lock(_S_mut);
00914 #endif
00915 _Alloc_block* __real_p = reinterpret_cast<_Alloc_block*>(__p);
00916
00917 typedef typename _BPVector::iterator _Iterator;
00918 typedef typename _BPVector::difference_type _Difference_type;
00919
00920 _Difference_type __diff;
00921 long __displacement;
00922
00923 _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0);
00924
00925 __detail::_Inclusive_between<_Alloc_block*> __ibt(__real_p);
00926 if (__ibt(_S_mem_blocks[_S_last_dealloc_index]))
00927 {
00928 _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index
00929 <= _S_mem_blocks.size() - 1);
00930
00931
00932 __diff = _S_last_dealloc_index;
00933 __displacement = __real_p - _S_mem_blocks[__diff].first;
00934 }
00935 else
00936 {
00937 _Iterator _iter = _S_find(__ibt);
00938
00939 _GLIBCXX_DEBUG_ASSERT(_iter != _S_mem_blocks.end());
00940
00941 __diff = _iter - _S_mem_blocks.begin();
00942 __displacement = __real_p - _S_mem_blocks[__diff].first;
00943 _S_last_dealloc_index = __diff;
00944 }
00945
00946
00947 const size_t __rotate = (__displacement
00948 % size_t(__detail::bits_per_block));
00949 size_t* __bitmapC =
00950 reinterpret_cast<size_t*>
00951 (_S_mem_blocks[__diff].first) - 1;
00952 __bitmapC -= (__displacement / size_t(__detail::bits_per_block));
00953
00954 __detail::__bit_free(__bitmapC, __rotate);
00955 size_t* __puse_count = reinterpret_cast<size_t*>
00956 (_S_mem_blocks[__diff].first)
00957 - (__detail::__num_bitmaps(_S_mem_blocks[__diff]) + 1);
00958
00959 _GLIBCXX_DEBUG_ASSERT(*__puse_count != 0);
00960
00961 --(*__puse_count);
00962
00963 if (__builtin_expect(*__puse_count == 0, false))
00964 {
00965 _S_block_size /= 2;
00966
00967
00968
00969 this->_M_insert(__puse_count);
00970 _S_mem_blocks.erase(_S_mem_blocks.begin() + __diff);
00971
00972
00973
00974
00975
00976
00977
00978 if ((_Difference_type)_S_last_request._M_where() >= __diff--)
00979 _S_last_request._M_reset(__diff);
00980
00981
00982
00983
00984
00985
00986 if (_S_last_dealloc_index >= _S_mem_blocks.size())
00987 {
00988 _S_last_dealloc_index =(__diff != -1 ? __diff : 0);
00989 _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0);
00990 }
00991 }
00992 }
00993
00994 public:
00995 bitmap_allocator() throw()
00996 { }
00997
00998 bitmap_allocator(const bitmap_allocator&)
00999 { }
01000
01001 template<typename _Tp1>
01002 bitmap_allocator(const bitmap_allocator<_Tp1>&) throw()
01003 { }
01004
01005 ~bitmap_allocator() throw()
01006 { }
01007
01008 pointer
01009 allocate(size_type __n)
01010 {
01011 if (__n > this->max_size())
01012 std::__throw_bad_alloc();
01013
01014 if (__builtin_expect(__n == 1, true))
01015 return this->_M_allocate_single_object();
01016 else
01017 {
01018 const size_type __b = __n * sizeof(value_type);
01019 return reinterpret_cast<pointer>(::operator new(__b));
01020 }
01021 }
01022
01023 pointer
01024 allocate(size_type __n, typename bitmap_allocator<void>::const_pointer)
01025 { return allocate(__n); }
01026
01027 void
01028 deallocate(pointer __p, size_type __n) throw()
01029 {
01030 if (__builtin_expect(__p != 0, true))
01031 {
01032 if (__builtin_expect(__n == 1, true))
01033 this->_M_deallocate_single_object(__p);
01034 else
01035 ::operator delete(__p);
01036 }
01037 }
01038
01039 pointer
01040 address(reference __r) const
01041 { return std::__addressof(__r); }
01042
01043 const_pointer
01044 address(const_reference __r) const
01045 { return std::__addressof(__r); }
01046
01047 size_type
01048 max_size() const throw()
01049 { return size_type(-1) / sizeof(value_type); }
01050
01051 void
01052 construct(pointer __p, const_reference __data)
01053 { ::new((void *)__p) value_type(__data); }
01054
01055 #ifdef __GXX_EXPERIMENTAL_CXX0X__
01056 template<typename... _Args>
01057 void
01058 construct(pointer __p, _Args&&... __args)
01059 { ::new((void *)__p) _Tp(std::forward<_Args>(__args)...); }
01060 #endif
01061
01062 void
01063 destroy(pointer __p)
01064 { __p->~value_type(); }
01065 };
01066
01067 template<typename _Tp1, typename _Tp2>
01068 bool
01069 operator==(const bitmap_allocator<_Tp1>&,
01070 const bitmap_allocator<_Tp2>&) throw()
01071 { return true; }
01072
01073 template<typename _Tp1, typename _Tp2>
01074 bool
01075 operator!=(const bitmap_allocator<_Tp1>&,
01076 const bitmap_allocator<_Tp2>&) throw()
01077 { return false; }
01078
01079
01080 template<typename _Tp>
01081 typename bitmap_allocator<_Tp>::_BPVector
01082 bitmap_allocator<_Tp>::_S_mem_blocks;
01083
01084 template<typename _Tp>
01085 size_t bitmap_allocator<_Tp>::_S_block_size =
01086 2 * size_t(__detail::bits_per_block);
01087
01088 template<typename _Tp>
01089 typename bitmap_allocator<_Tp>::_BPVector::size_type
01090 bitmap_allocator<_Tp>::_S_last_dealloc_index = 0;
01091
01092 template<typename _Tp>
01093 __detail::_Bitmap_counter
01094 <typename bitmap_allocator<_Tp>::_Alloc_block*>
01095 bitmap_allocator<_Tp>::_S_last_request(_S_mem_blocks);
01096
01097 #if defined __GTHREADS
01098 template<typename _Tp>
01099 typename bitmap_allocator<_Tp>::__mutex_type
01100 bitmap_allocator<_Tp>::_S_mut;
01101 #endif
01102
01103 _GLIBCXX_END_NAMESPACE
01104
01105 #endif
01106