Mercurial > hg > CbC > CbC_gcc
comparison libstdc++-v3/include/ext/bitmap_allocator.h @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 // Bitmap Allocator. -*- C++ -*- | 1 // Bitmap Allocator. -*- C++ -*- |
2 | 2 |
3 // Copyright (C) 2004-2018 Free Software Foundation, Inc. | 3 // Copyright (C) 2004-2020 Free Software Foundation, Inc. |
4 // | 4 // |
5 // This file is part of the GNU ISO C++ Library. This library is free | 5 // This file is part of the GNU ISO C++ Library. This library is free |
6 // software; you can redistribute it and/or modify it under the | 6 // software; you can redistribute it and/or modify it under the |
7 // terms of the GNU General Public License as published by the | 7 // terms of the GNU General Public License as published by the |
8 // Free Software Foundation; either version 3, or (at your option) | 8 // Free Software Foundation; either version 3, or (at your option) |
43 #define _BALLOC_ALIGN_BYTES 8 | 43 #define _BALLOC_ALIGN_BYTES 8 |
44 | 44 |
45 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) | 45 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) |
46 { | 46 { |
47 _GLIBCXX_BEGIN_NAMESPACE_VERSION | 47 _GLIBCXX_BEGIN_NAMESPACE_VERSION |
48 | |
49 using std::size_t; | |
50 using std::ptrdiff_t; | |
51 | 48 |
52 namespace __detail | 49 namespace __detail |
53 { | 50 { |
54 /** @class __mini_vector bitmap_allocator.h bitmap_allocator.h | 51 /** @class __mini_vector bitmap_allocator.h bitmap_allocator.h |
55 * | 52 * |
75 public: | 72 public: |
76 typedef _Tp value_type; | 73 typedef _Tp value_type; |
77 typedef _Tp* pointer; | 74 typedef _Tp* pointer; |
78 typedef _Tp& reference; | 75 typedef _Tp& reference; |
79 typedef const _Tp& const_reference; | 76 typedef const _Tp& const_reference; |
80 typedef size_t size_type; | 77 typedef std::size_t size_type; |
81 typedef ptrdiff_t difference_type; | 78 typedef std::ptrdiff_t difference_type; |
82 typedef pointer iterator; | 79 typedef pointer iterator; |
83 | 80 |
84 private: | 81 private: |
85 pointer _M_start; | 82 pointer _M_start; |
86 pointer _M_finish; | 83 pointer _M_finish; |
88 | 85 |
89 size_type | 86 size_type |
90 _M_space_left() const throw() | 87 _M_space_left() const throw() |
91 { return _M_end_of_storage - _M_finish; } | 88 { return _M_end_of_storage - _M_finish; } |
92 | 89 |
93 pointer | 90 _GLIBCXX_NODISCARD pointer |
94 allocate(size_type __n) | 91 allocate(size_type __n) |
95 { return static_cast<pointer>(::operator new(__n * sizeof(_Tp))); } | 92 { return static_cast<pointer>(::operator new(__n * sizeof(_Tp))); } |
96 | 93 |
97 void | 94 void |
98 deallocate(pointer __p, size_type) | 95 deallocate(pointer __p, size_type) |
221 | 218 |
222 template<typename _Tp> | 219 template<typename _Tp> |
223 struct __mv_iter_traits<_Tp*> | 220 struct __mv_iter_traits<_Tp*> |
224 { | 221 { |
225 typedef _Tp value_type; | 222 typedef _Tp value_type; |
226 typedef ptrdiff_t difference_type; | 223 typedef std::ptrdiff_t difference_type; |
227 }; | 224 }; |
228 | 225 |
229 enum | 226 enum |
230 { | 227 { |
231 bits_per_byte = 8, | 228 bits_per_byte = 8, |
232 bits_per_block = sizeof(size_t) * size_t(bits_per_byte) | 229 bits_per_block = sizeof(std::size_t) * std::size_t(bits_per_byte) |
233 }; | 230 }; |
234 | 231 |
235 template<typename _ForwardIterator, typename _Tp, typename _Compare> | 232 template<typename _ForwardIterator, typename _Tp, typename _Compare> |
236 _ForwardIterator | 233 _ForwardIterator |
237 __lower_bound(_ForwardIterator __first, _ForwardIterator __last, | 234 __lower_bound(_ForwardIterator __first, _ForwardIterator __last, |
263 | 260 |
264 /** @brief The number of Blocks pointed to by the address pair | 261 /** @brief The number of Blocks pointed to by the address pair |
265 * passed to the function. | 262 * passed to the function. |
266 */ | 263 */ |
267 template<typename _AddrPair> | 264 template<typename _AddrPair> |
268 inline size_t | 265 inline std::size_t |
269 __num_blocks(_AddrPair __ap) | 266 __num_blocks(_AddrPair __ap) |
270 { return (__ap.second - __ap.first) + 1; } | 267 { return (__ap.second - __ap.first) + 1; } |
271 | 268 |
272 /** @brief The number of Bit-maps pointed to by the address pair | 269 /** @brief The number of Bit-maps pointed to by the address pair |
273 * passed to the function. | 270 * passed to the function. |
274 */ | 271 */ |
275 template<typename _AddrPair> | 272 template<typename _AddrPair> |
276 inline size_t | 273 inline std::size_t |
277 __num_bitmaps(_AddrPair __ap) | 274 __num_bitmaps(_AddrPair __ap) |
278 { return __num_blocks(__ap) / size_t(bits_per_block); } | 275 { return __num_blocks(__ap) / std::size_t(bits_per_block); } |
279 | 276 |
280 // _Tp should be a pointer type. | 277 // _Tp should be a pointer type. |
281 template<typename _Tp> | 278 template<typename _Tp> |
282 class _Inclusive_between | 279 class _Inclusive_between |
283 : public std::unary_function<typename std::pair<_Tp, _Tp>, bool> | 280 : public std::unary_function<typename std::pair<_Tp, _Tp>, bool> |
334 { | 331 { |
335 typedef typename std::pair<_Tp, _Tp> _Block_pair; | 332 typedef typename std::pair<_Tp, _Tp> _Block_pair; |
336 typedef typename __detail::__mini_vector<_Block_pair> _BPVector; | 333 typedef typename __detail::__mini_vector<_Block_pair> _BPVector; |
337 typedef typename _BPVector::difference_type _Counter_type; | 334 typedef typename _BPVector::difference_type _Counter_type; |
338 | 335 |
339 size_t* _M_pbitmap; | 336 std::size_t* _M_pbitmap; |
340 _Counter_type _M_data_offset; | 337 _Counter_type _M_data_offset; |
341 | 338 |
342 public: | 339 public: |
343 _Ffit_finder() : _M_pbitmap(0), _M_data_offset(0) | 340 _Ffit_finder() : _M_pbitmap(0), _M_data_offset(0) |
344 { } | 341 { } |
345 | 342 |
346 bool | 343 bool |
347 operator()(_Block_pair __bp) throw() | 344 operator()(_Block_pair __bp) throw() |
348 { | 345 { |
346 using std::size_t; | |
349 // Set the _rover to the last physical location bitmap, | 347 // Set the _rover to the last physical location bitmap, |
350 // which is the bitmap which belongs to the first free | 348 // which is the bitmap which belongs to the first free |
351 // block. Thus, the bitmaps are in exact reverse order of | 349 // block. Thus, the bitmaps are in exact reverse order of |
352 // the actual memory layout. So, we count down the bitmaps, | 350 // the actual memory layout. So, we count down the bitmaps, |
353 // which is the same as moving up the memory. | 351 // which is the same as moving up the memory. |
375 --__rover; | 373 --__rover; |
376 } | 374 } |
377 return false; | 375 return false; |
378 } | 376 } |
379 | 377 |
380 size_t* | 378 std::size_t* |
381 _M_get() const throw() | 379 _M_get() const throw() |
382 { return _M_pbitmap; } | 380 { return _M_pbitmap; } |
383 | 381 |
384 _Counter_type | 382 _Counter_type |
385 _M_offset() const throw() | 383 _M_offset() const throw() |
386 { return _M_data_offset * size_t(bits_per_block); } | 384 { return _M_data_offset * std::size_t(bits_per_block); } |
387 }; | 385 }; |
388 | 386 |
389 /** @class _Bitmap_counter bitmap_allocator.h bitmap_allocator.h | 387 /** @class _Bitmap_counter bitmap_allocator.h bitmap_allocator.h |
390 * | 388 * |
391 * @brief The bitmap counter which acts as the bitmap | 389 * @brief The bitmap counter which acts as the bitmap |
400 __detail::__mini_vector<typename std::pair<_Tp, _Tp> > _BPVector; | 398 __detail::__mini_vector<typename std::pair<_Tp, _Tp> > _BPVector; |
401 typedef typename _BPVector::size_type _Index_type; | 399 typedef typename _BPVector::size_type _Index_type; |
402 typedef _Tp pointer; | 400 typedef _Tp pointer; |
403 | 401 |
404 _BPVector& _M_vbp; | 402 _BPVector& _M_vbp; |
405 size_t* _M_curr_bmap; | 403 std::size_t* _M_curr_bmap; |
406 size_t* _M_last_bmap_in_block; | 404 std::size_t* _M_last_bmap_in_block; |
407 _Index_type _M_curr_index; | 405 _Index_type _M_curr_index; |
408 | 406 |
409 public: | 407 public: |
410 // Use the 2nd parameter with care. Make sure that such an | 408 // Use the 2nd parameter with care. Make sure that such an |
411 // entry exists in the vector before passing that particular | 409 // entry exists in the vector before passing that particular |
422 _M_curr_index = static_cast<_Index_type>(-1); | 420 _M_curr_index = static_cast<_Index_type>(-1); |
423 return; | 421 return; |
424 } | 422 } |
425 | 423 |
426 _M_curr_index = __index; | 424 _M_curr_index = __index; |
427 _M_curr_bmap = reinterpret_cast<size_t*> | 425 _M_curr_bmap = reinterpret_cast<std::size_t*> |
428 (_M_vbp[_M_curr_index].first) - 1; | 426 (_M_vbp[_M_curr_index].first) - 1; |
429 | 427 |
430 _GLIBCXX_DEBUG_ASSERT(__index <= (long)_M_vbp.size() - 1); | 428 _GLIBCXX_DEBUG_ASSERT(__index <= (long)_M_vbp.size() - 1); |
431 | 429 |
432 _M_last_bmap_in_block = _M_curr_bmap | 430 _M_last_bmap_in_block = _M_curr_bmap |
433 - ((_M_vbp[_M_curr_index].second | 431 - ((_M_vbp[_M_curr_index].second |
434 - _M_vbp[_M_curr_index].first + 1) | 432 - _M_vbp[_M_curr_index].first + 1) |
435 / size_t(bits_per_block) - 1); | 433 / std::size_t(bits_per_block) - 1); |
436 } | 434 } |
437 | 435 |
438 // Dangerous Function! Use with extreme care. Pass to this | 436 // Dangerous Function! Use with extreme care. Pass to this |
439 // function ONLY those values that are known to be correct, | 437 // function ONLY those values that are known to be correct, |
440 // otherwise this will mess up big time. | 438 // otherwise this will mess up big time. |
441 void | 439 void |
442 _M_set_internal_bitmap(size_t* __new_internal_marker) throw() | 440 _M_set_internal_bitmap(std::size_t* __new_internal_marker) throw() |
443 { _M_curr_bmap = __new_internal_marker; } | 441 { _M_curr_bmap = __new_internal_marker; } |
444 | 442 |
445 bool | 443 bool |
446 _M_finished() const throw() | 444 _M_finished() const throw() |
447 { return(_M_curr_bmap == 0); } | 445 { return(_M_curr_bmap == 0); } |
459 else | 457 else |
460 --_M_curr_bmap; | 458 --_M_curr_bmap; |
461 return *this; | 459 return *this; |
462 } | 460 } |
463 | 461 |
464 size_t* | 462 std::size_t* |
465 _M_get() const throw() | 463 _M_get() const throw() |
466 { return _M_curr_bmap; } | 464 { return _M_curr_bmap; } |
467 | 465 |
468 pointer | 466 pointer |
469 _M_base() const throw() | 467 _M_base() const throw() |
470 { return _M_vbp[_M_curr_index].first; } | 468 { return _M_vbp[_M_curr_index].first; } |
471 | 469 |
472 _Index_type | 470 _Index_type |
473 _M_offset() const throw() | 471 _M_offset() const throw() |
474 { | 472 { |
475 return size_t(bits_per_block) | 473 return std::size_t(bits_per_block) |
476 * ((reinterpret_cast<size_t*>(this->_M_base()) | 474 * ((reinterpret_cast<std::size_t*>(this->_M_base()) |
477 - _M_curr_bmap) - 1); | 475 - _M_curr_bmap) - 1); |
478 } | 476 } |
479 | 477 |
480 _Index_type | 478 _Index_type |
481 _M_where() const throw() | 479 _M_where() const throw() |
484 | 482 |
485 /** @brief Mark a memory address as allocated by re-setting the | 483 /** @brief Mark a memory address as allocated by re-setting the |
486 * corresponding bit in the bit-map. | 484 * corresponding bit in the bit-map. |
487 */ | 485 */ |
488 inline void | 486 inline void |
489 __bit_allocate(size_t* __pbmap, size_t __pos) throw() | 487 __bit_allocate(std::size_t* __pbmap, std::size_t __pos) throw() |
490 { | 488 { |
491 size_t __mask = 1 << __pos; | 489 std::size_t __mask = 1 << __pos; |
492 __mask = ~__mask; | 490 __mask = ~__mask; |
493 *__pbmap &= __mask; | 491 *__pbmap &= __mask; |
494 } | 492 } |
495 | 493 |
496 /** @brief Mark a memory address as free by setting the | 494 /** @brief Mark a memory address as free by setting the |
497 * corresponding bit in the bit-map. | 495 * corresponding bit in the bit-map. |
498 */ | 496 */ |
499 inline void | 497 inline void |
500 __bit_free(size_t* __pbmap, size_t __pos) throw() | 498 __bit_free(std::size_t* __pbmap, std::size_t __pos) throw() |
501 { | 499 { |
502 size_t __mask = 1 << __pos; | 500 std::size_t __mask = 1 << __pos; |
503 *__pbmap |= __mask; | 501 *__pbmap |= __mask; |
504 } | 502 } |
505 } // namespace __detail | 503 } // namespace __detail |
506 | 504 |
507 /** @brief Generic Version of the bsf instruction. | 505 /** @brief Generic Version of the bsf instruction. |
508 */ | 506 */ |
509 inline size_t | 507 inline std::size_t |
510 _Bit_scan_forward(size_t __num) | 508 _Bit_scan_forward(std::size_t __num) |
511 { return static_cast<size_t>(__builtin_ctzl(__num)); } | 509 { return static_cast<std::size_t>(__builtin_ctzl(__num)); } |
512 | 510 |
513 /** @class free_list bitmap_allocator.h bitmap_allocator.h | 511 /** @class free_list bitmap_allocator.h bitmap_allocator.h |
514 * | 512 * |
515 * @brief The free list class for managing chunks of memory to be | 513 * @brief The free list class for managing chunks of memory to be |
516 * given to and returned by the bitmap_allocator. | 514 * given to and returned by the bitmap_allocator. |
517 */ | 515 */ |
518 class free_list | 516 class free_list |
519 { | 517 { |
520 public: | 518 public: |
521 typedef size_t* value_type; | 519 typedef std::size_t* value_type; |
522 typedef __detail::__mini_vector<value_type> vector_type; | 520 typedef __detail::__mini_vector<value_type> vector_type; |
523 typedef vector_type::iterator iterator; | 521 typedef vector_type::iterator iterator; |
524 typedef __mutex __mutex_type; | 522 typedef __mutex __mutex_type; |
525 | 523 |
526 private: | 524 private: |
527 struct _LT_pointer_compare | 525 struct _LT_pointer_compare |
528 { | 526 { |
529 bool | 527 bool |
530 operator()(const size_t* __pui, | 528 operator()(const std::size_t* __pui, |
531 const size_t __cui) const throw() | 529 const std::size_t __cui) const throw() |
532 { return *__pui < __cui; } | 530 { return *__pui < __cui; } |
533 }; | 531 }; |
534 | 532 |
535 #if defined __GTHREADS | 533 #if defined __GTHREADS |
536 __mutex_type& | 534 __mutex_type& |
557 * appropriately performs the action of managing the free list of | 555 * appropriately performs the action of managing the free list of |
558 * blocks by adding this block to the free list or deleting this | 556 * blocks by adding this block to the free list or deleting this |
559 * or larger blocks from the free list. | 557 * or larger blocks from the free list. |
560 */ | 558 */ |
561 void | 559 void |
562 _M_validate(size_t* __addr) throw() | 560 _M_validate(std::size_t* __addr) throw() |
563 { | 561 { |
564 vector_type& __free_list = _M_get_free_list(); | 562 vector_type& __free_list = _M_get_free_list(); |
565 const vector_type::size_type __max_size = 64; | 563 const vector_type::size_type __max_size = 64; |
566 if (__free_list.size() >= __max_size) | 564 if (__free_list.size() >= __max_size) |
567 { | 565 { |
603 * | 601 * |
604 * @return true if the wastage incurred is acceptable, else returns | 602 * @return true if the wastage incurred is acceptable, else returns |
605 * false. | 603 * false. |
606 */ | 604 */ |
607 bool | 605 bool |
608 _M_should_i_give(size_t __block_size, | 606 _M_should_i_give(std::size_t __block_size, |
609 size_t __required_size) throw() | 607 std::size_t __required_size) throw() |
610 { | 608 { |
611 const size_t __max_wastage_percentage = 36; | 609 const std::size_t __max_wastage_percentage = 36; |
612 if (__block_size >= __required_size && | 610 if (__block_size >= __required_size && |
613 (((__block_size - __required_size) * 100 / __block_size) | 611 (((__block_size - __required_size) * 100 / __block_size) |
614 < __max_wastage_percentage)) | 612 < __max_wastage_percentage)) |
615 return true; | 613 return true; |
616 else | 614 else |
623 * | 621 * |
624 * @param __addr The pointer to the memory block that was given | 622 * @param __addr The pointer to the memory block that was given |
625 * by a call to the _M_get function. | 623 * by a call to the _M_get function. |
626 */ | 624 */ |
627 inline void | 625 inline void |
628 _M_insert(size_t* __addr) throw() | 626 _M_insert(std::size_t* __addr) throw() |
629 { | 627 { |
630 #if defined __GTHREADS | 628 #if defined __GTHREADS |
631 __scoped_lock __bfl_lock(_M_get_mutex()); | 629 __scoped_lock __bfl_lock(_M_get_mutex()); |
632 #endif | 630 #endif |
633 // Call _M_validate to decide what should be done with | 631 // Call _M_validate to decide what should be done with |
634 // this particular free list. | 632 // this particular free list. |
635 this->_M_validate(reinterpret_cast<size_t*>(__addr) - 1); | 633 this->_M_validate(reinterpret_cast<std::size_t*>(__addr) - 1); |
636 // See discussion as to why this is 1! | 634 // See discussion as to why this is 1! |
637 } | 635 } |
638 | 636 |
639 /** @brief This function gets a block of memory of the specified | 637 /** @brief This function gets a block of memory of the specified |
640 * size from the free list. | 638 * size from the free list. |
642 * @param __sz The size in bytes of the memory required. | 640 * @param __sz The size in bytes of the memory required. |
643 * | 641 * |
644 * @return A pointer to the new memory block of size at least | 642 * @return A pointer to the new memory block of size at least |
645 * equal to that requested. | 643 * equal to that requested. |
646 */ | 644 */ |
647 size_t* | 645 std::size_t* |
648 _M_get(size_t __sz) _GLIBCXX_THROW(std::bad_alloc); | 646 _M_get(std::size_t __sz) _GLIBCXX_THROW(std::bad_alloc); |
649 | 647 |
650 /** @brief This function just clears the internal Free List, and | 648 /** @brief This function just clears the internal Free List, and |
651 * gives back all the memory to the OS. | 649 * gives back all the memory to the OS. |
652 */ | 650 */ |
653 void | 651 void |
682 */ | 680 */ |
683 template<typename _Tp> | 681 template<typename _Tp> |
684 class bitmap_allocator : private free_list | 682 class bitmap_allocator : private free_list |
685 { | 683 { |
686 public: | 684 public: |
687 typedef size_t size_type; | 685 typedef std::size_t size_type; |
688 typedef ptrdiff_t difference_type; | 686 typedef std::ptrdiff_t difference_type; |
689 typedef _Tp* pointer; | 687 typedef _Tp* pointer; |
690 typedef const _Tp* const_pointer; | 688 typedef const _Tp* const_pointer; |
691 typedef _Tp& reference; | 689 typedef _Tp& reference; |
692 typedef const _Tp& const_reference; | 690 typedef const _Tp& const_reference; |
693 typedef _Tp value_type; | 691 typedef _Tp value_type; |
704 // 2103. propagate_on_container_move_assignment | 702 // 2103. propagate_on_container_move_assignment |
705 typedef std::true_type propagate_on_container_move_assignment; | 703 typedef std::true_type propagate_on_container_move_assignment; |
706 #endif | 704 #endif |
707 | 705 |
708 private: | 706 private: |
709 template<size_t _BSize, size_t _AlignSize> | 707 template<std::size_t _BSize, std::size_t _AlignSize> |
710 struct aligned_size | 708 struct aligned_size |
711 { | 709 { |
712 enum | 710 enum |
713 { | 711 { |
714 modulus = _BSize % _AlignSize, | 712 modulus = _BSize % _AlignSize, |
752 #endif | 750 #endif |
753 | 751 |
754 /** @brief Responsible for exponentially growing the internal | 752 /** @brief Responsible for exponentially growing the internal |
755 * memory pool. | 753 * memory pool. |
756 * | 754 * |
757 * @throw std::bad_alloc. If memory can not be allocated. | 755 * @throw std::bad_alloc. If memory cannot be allocated. |
758 * | 756 * |
759 * Complexity: O(1), but internally depends upon the | 757 * Complexity: O(1), but internally depends upon the |
760 * complexity of the function free_list::_M_get. The part where | 758 * complexity of the function free_list::_M_get. The part where |
761 * the bitmap headers are written has complexity: O(X),where X | 759 * the bitmap headers are written has complexity: O(X),where X |
762 * is the number of blocks of size sizeof(value_type) within | 760 * is the number of blocks of size sizeof(value_type) within |
763 * the newly acquired block. Having a tight bound. | 761 * the newly acquired block. Having a tight bound. |
764 */ | 762 */ |
765 void | 763 void |
766 _S_refill_pool() _GLIBCXX_THROW(std::bad_alloc) | 764 _S_refill_pool() _GLIBCXX_THROW(std::bad_alloc) |
767 { | 765 { |
766 using std::size_t; | |
768 #if defined _GLIBCXX_DEBUG | 767 #if defined _GLIBCXX_DEBUG |
769 _S_check_for_free_blocks(); | 768 _S_check_for_free_blocks(); |
770 #endif | 769 #endif |
771 | 770 |
772 const size_t __num_bitmaps = (_S_block_size | 771 const size_t __num_bitmaps = (_S_block_size |
796 | 795 |
797 _S_block_size *= 2; | 796 _S_block_size *= 2; |
798 } | 797 } |
799 | 798 |
800 static _BPVector _S_mem_blocks; | 799 static _BPVector _S_mem_blocks; |
801 static size_t _S_block_size; | 800 static std::size_t _S_block_size; |
802 static __detail::_Bitmap_counter<_Alloc_block*> _S_last_request; | 801 static __detail::_Bitmap_counter<_Alloc_block*> _S_last_request; |
803 static typename _BPVector::size_type _S_last_dealloc_index; | 802 static typename _BPVector::size_type _S_last_dealloc_index; |
804 #if defined __GTHREADS | 803 #if defined __GTHREADS |
805 static __mutex_type _S_mut; | 804 static __mutex_type _S_mut; |
806 #endif | 805 #endif |
808 public: | 807 public: |
809 | 808 |
810 /** @brief Allocates memory for a single object of size | 809 /** @brief Allocates memory for a single object of size |
811 * sizeof(_Tp). | 810 * sizeof(_Tp). |
812 * | 811 * |
813 * @throw std::bad_alloc. If memory can not be allocated. | 812 * @throw std::bad_alloc. If memory cannot be allocated. |
814 * | 813 * |
815 * Complexity: Worst case complexity is O(N), but that | 814 * Complexity: Worst case complexity is O(N), but that |
816 * is hardly ever hit. If and when this particular case is | 815 * is hardly ever hit. If and when this particular case is |
817 * encountered, the next few cases are guaranteed to have a | 816 * encountered, the next few cases are guaranteed to have a |
818 * worst case complexity of O(1)! That's why this function | 817 * worst case complexity of O(1)! That's why this function |
821 * Amortized Constant time. | 820 * Amortized Constant time. |
822 */ | 821 */ |
823 pointer | 822 pointer |
824 _M_allocate_single_object() _GLIBCXX_THROW(std::bad_alloc) | 823 _M_allocate_single_object() _GLIBCXX_THROW(std::bad_alloc) |
825 { | 824 { |
825 using std::size_t; | |
826 #if defined __GTHREADS | 826 #if defined __GTHREADS |
827 __scoped_lock __bit_lock(_S_mut); | 827 __scoped_lock __bit_lock(_S_mut); |
828 #endif | 828 #endif |
829 | 829 |
830 // The algorithm is something like this: The last_request | 830 // The algorithm is something like this: The last_request |
911 * the deallocate function. | 911 * the deallocate function. |
912 */ | 912 */ |
913 void | 913 void |
914 _M_deallocate_single_object(pointer __p) throw() | 914 _M_deallocate_single_object(pointer __p) throw() |
915 { | 915 { |
916 using std::size_t; | |
916 #if defined __GTHREADS | 917 #if defined __GTHREADS |
917 __scoped_lock __bit_lock(_S_mut); | 918 __scoped_lock __bit_lock(_S_mut); |
918 #endif | 919 #endif |
919 _Alloc_block* __real_p = reinterpret_cast<_Alloc_block*>(__p); | 920 _Alloc_block* __real_p = reinterpret_cast<_Alloc_block*>(__p); |
920 | 921 |
1007 { } | 1008 { } |
1008 | 1009 |
1009 ~bitmap_allocator() _GLIBCXX_USE_NOEXCEPT | 1010 ~bitmap_allocator() _GLIBCXX_USE_NOEXCEPT |
1010 { } | 1011 { } |
1011 | 1012 |
1012 pointer | 1013 _GLIBCXX_NODISCARD pointer |
1013 allocate(size_type __n) | 1014 allocate(size_type __n) |
1014 { | 1015 { |
1015 if (__n > this->max_size()) | 1016 if (__n > this->max_size()) |
1016 std::__throw_bad_alloc(); | 1017 std::__throw_bad_alloc(); |
1017 | 1018 |
1031 const size_type __b = __n * sizeof(value_type); | 1032 const size_type __b = __n * sizeof(value_type); |
1032 return reinterpret_cast<pointer>(::operator new(__b)); | 1033 return reinterpret_cast<pointer>(::operator new(__b)); |
1033 } | 1034 } |
1034 } | 1035 } |
1035 | 1036 |
1036 pointer | 1037 _GLIBCXX_NODISCARD pointer |
1037 allocate(size_type __n, typename bitmap_allocator<void>::const_pointer) | 1038 allocate(size_type __n, typename bitmap_allocator<void>::const_pointer) |
1038 { return allocate(__n); } | 1039 { return allocate(__n); } |
1039 | 1040 |
1040 void | 1041 void |
1041 deallocate(pointer __p, size_type __n) throw() | 1042 deallocate(pointer __p, size_type __n) throw() |
1107 template<typename _Tp> | 1108 template<typename _Tp> |
1108 typename bitmap_allocator<_Tp>::_BPVector | 1109 typename bitmap_allocator<_Tp>::_BPVector |
1109 bitmap_allocator<_Tp>::_S_mem_blocks; | 1110 bitmap_allocator<_Tp>::_S_mem_blocks; |
1110 | 1111 |
1111 template<typename _Tp> | 1112 template<typename _Tp> |
1112 size_t bitmap_allocator<_Tp>::_S_block_size = | 1113 std::size_t bitmap_allocator<_Tp>::_S_block_size |
1113 2 * size_t(__detail::bits_per_block); | 1114 = 2 * std::size_t(__detail::bits_per_block); |
1114 | 1115 |
1115 template<typename _Tp> | 1116 template<typename _Tp> |
1116 typename bitmap_allocator<_Tp>::_BPVector::size_type | 1117 typename bitmap_allocator<_Tp>::_BPVector::size_type |
1117 bitmap_allocator<_Tp>::_S_last_dealloc_index = 0; | 1118 bitmap_allocator<_Tp>::_S_last_dealloc_index = 0; |
1118 | 1119 |