bitmap_allocator.h 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136
  1. // Bitmap Allocator. -*- C++ -*-
  2. // Copyright (C) 2004-2021 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file ext/bitmap_allocator.h
  21. * This file is a GNU extension to the Standard C++ Library.
  22. */
  23. #ifndef _BITMAP_ALLOCATOR_H
  24. #define _BITMAP_ALLOCATOR_H 1
  25. #include <utility> // For std::pair.
  26. #include <bits/functexcept.h> // For __throw_bad_alloc().
  27. #include <functional> // For greater_equal, and less_equal.
  28. #include <new> // For operator new.
  29. #include <debug/debug.h> // _GLIBCXX_DEBUG_ASSERT
  30. #include <ext/concurrence.h>
  31. #include <bits/move.h>
  32. /** @brief The constant in the expression below is the alignment
  33. * required in bytes.
  34. */
  35. #define _BALLOC_ALIGN_BYTES 8
  36. namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
  37. {
  38. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  39. namespace __detail
  40. {
  41. /** @class __mini_vector bitmap_allocator.h bitmap_allocator.h
  42. *
  43. * @brief __mini_vector<> is a stripped down version of the
  44. * full-fledged std::vector<>.
  45. *
  46. * It is to be used only for built-in types or PODs. Notable
  47. * differences are:
  48. *
  49. * 1. Not all accessor functions are present.
  50. * 2. Used ONLY for PODs.
  51. * 3. No Allocator template argument. Uses ::operator new() to get
  52. * memory, and ::operator delete() to free it.
  53. * Caveat: The dtor does NOT free the memory allocated, so this a
  54. * memory-leaking vector!
  55. */
  56. template<typename _Tp>
  57. class __mini_vector
  58. {
  59. __mini_vector(const __mini_vector&);
  60. __mini_vector& operator=(const __mini_vector&);
  61. public:
  62. typedef _Tp value_type;
  63. typedef _Tp* pointer;
  64. typedef _Tp& reference;
  65. typedef const _Tp& const_reference;
  66. typedef std::size_t size_type;
  67. typedef std::ptrdiff_t difference_type;
  68. typedef pointer iterator;
  69. private:
  70. pointer _M_start;
  71. pointer _M_finish;
  72. pointer _M_end_of_storage;
  73. size_type
  74. _M_space_left() const throw()
  75. { return _M_end_of_storage - _M_finish; }
  76. _GLIBCXX_NODISCARD pointer
  77. allocate(size_type __n)
  78. { return static_cast<pointer>(::operator new(__n * sizeof(_Tp))); }
  79. void
  80. deallocate(pointer __p, size_type)
  81. { ::operator delete(__p); }
  82. public:
  83. // Members used: size(), push_back(), pop_back(),
  84. // insert(iterator, const_reference), erase(iterator),
  85. // begin(), end(), back(), operator[].
  86. __mini_vector()
  87. : _M_start(0), _M_finish(0), _M_end_of_storage(0) { }
  88. size_type
  89. size() const throw()
  90. { return _M_finish - _M_start; }
  91. iterator
  92. begin() const throw()
  93. { return this->_M_start; }
  94. iterator
  95. end() const throw()
  96. { return this->_M_finish; }
  97. reference
  98. back() const throw()
  99. { return *(this->end() - 1); }
  100. reference
  101. operator[](const size_type __pos) const throw()
  102. { return this->_M_start[__pos]; }
  103. void
  104. insert(iterator __pos, const_reference __x);
  105. void
  106. push_back(const_reference __x)
  107. {
  108. if (this->_M_space_left())
  109. {
  110. *this->end() = __x;
  111. ++this->_M_finish;
  112. }
  113. else
  114. this->insert(this->end(), __x);
  115. }
  116. void
  117. pop_back() throw()
  118. { --this->_M_finish; }
  119. void
  120. erase(iterator __pos) throw();
  121. void
  122. clear() throw()
  123. { this->_M_finish = this->_M_start; }
  124. };
  125. // Out of line function definitions.
  126. template<typename _Tp>
  127. void __mini_vector<_Tp>::
  128. insert(iterator __pos, const_reference __x)
  129. {
  130. if (this->_M_space_left())
  131. {
  132. size_type __to_move = this->_M_finish - __pos;
  133. iterator __dest = this->end();
  134. iterator __src = this->end() - 1;
  135. ++this->_M_finish;
  136. while (__to_move)
  137. {
  138. *__dest = *__src;
  139. --__dest; --__src; --__to_move;
  140. }
  141. *__pos = __x;
  142. }
  143. else
  144. {
  145. size_type __new_size = this->size() ? this->size() * 2 : 1;
  146. iterator __new_start = this->allocate(__new_size);
  147. iterator __first = this->begin();
  148. iterator __start = __new_start;
  149. while (__first != __pos)
  150. {
  151. *__start = *__first;
  152. ++__start; ++__first;
  153. }
  154. *__start = __x;
  155. ++__start;
  156. while (__first != this->end())
  157. {
  158. *__start = *__first;
  159. ++__start; ++__first;
  160. }
  161. if (this->_M_start)
  162. this->deallocate(this->_M_start, this->size());
  163. this->_M_start = __new_start;
  164. this->_M_finish = __start;
  165. this->_M_end_of_storage = this->_M_start + __new_size;
  166. }
  167. }
  168. template<typename _Tp>
  169. void __mini_vector<_Tp>::
  170. erase(iterator __pos) throw()
  171. {
  172. while (__pos + 1 != this->end())
  173. {
  174. *__pos = __pos[1];
  175. ++__pos;
  176. }
  177. --this->_M_finish;
  178. }
  179. template<typename _Tp>
  180. struct __mv_iter_traits
  181. {
  182. typedef typename _Tp::value_type value_type;
  183. typedef typename _Tp::difference_type difference_type;
  184. };
  185. template<typename _Tp>
  186. struct __mv_iter_traits<_Tp*>
  187. {
  188. typedef _Tp value_type;
  189. typedef std::ptrdiff_t difference_type;
  190. };
  191. enum
  192. {
  193. bits_per_byte = 8,
  194. bits_per_block = sizeof(std::size_t) * std::size_t(bits_per_byte)
  195. };
  196. template<typename _ForwardIterator, typename _Tp, typename _Compare>
  197. _ForwardIterator
  198. __lower_bound(_ForwardIterator __first, _ForwardIterator __last,
  199. const _Tp& __val, _Compare __comp)
  200. {
  201. typedef typename __mv_iter_traits<_ForwardIterator>::difference_type
  202. _DistanceType;
  203. _DistanceType __len = __last - __first;
  204. _DistanceType __half;
  205. _ForwardIterator __middle;
  206. while (__len > 0)
  207. {
  208. __half = __len >> 1;
  209. __middle = __first;
  210. __middle += __half;
  211. if (__comp(*__middle, __val))
  212. {
  213. __first = __middle;
  214. ++__first;
  215. __len = __len - __half - 1;
  216. }
  217. else
  218. __len = __half;
  219. }
  220. return __first;
  221. }
  222. /** @brief The number of Blocks pointed to by the address pair
  223. * passed to the function.
  224. */
  225. template<typename _AddrPair>
  226. inline std::size_t
  227. __num_blocks(_AddrPair __ap)
  228. { return (__ap.second - __ap.first) + 1; }
  229. /** @brief The number of Bit-maps pointed to by the address pair
  230. * passed to the function.
  231. */
  232. template<typename _AddrPair>
  233. inline std::size_t
  234. __num_bitmaps(_AddrPair __ap)
  235. { return __num_blocks(__ap) / std::size_t(bits_per_block); }
  236. // _Tp should be a pointer type.
  237. template<typename _Tp>
  238. class _Inclusive_between
  239. : public std::unary_function<typename std::pair<_Tp, _Tp>, bool>
  240. {
  241. typedef _Tp pointer;
  242. pointer _M_ptr_value;
  243. typedef typename std::pair<_Tp, _Tp> _Block_pair;
  244. public:
  245. _Inclusive_between(pointer __ptr) : _M_ptr_value(__ptr)
  246. { }
  247. bool
  248. operator()(_Block_pair __bp) const throw()
  249. {
  250. if (std::less_equal<pointer>()(_M_ptr_value, __bp.second)
  251. && std::greater_equal<pointer>()(_M_ptr_value, __bp.first))
  252. return true;
  253. else
  254. return false;
  255. }
  256. };
  257. // Used to pass a Functor to functions by reference.
  258. template<typename _Functor>
  259. class _Functor_Ref
  260. : public std::unary_function<typename _Functor::argument_type,
  261. typename _Functor::result_type>
  262. {
  263. _Functor& _M_fref;
  264. public:
  265. typedef typename _Functor::argument_type argument_type;
  266. typedef typename _Functor::result_type result_type;
  267. _Functor_Ref(_Functor& __fref) : _M_fref(__fref)
  268. { }
  269. result_type
  270. operator()(argument_type __arg)
  271. { return _M_fref(__arg); }
  272. };
  273. /** @class _Ffit_finder bitmap_allocator.h bitmap_allocator.h
  274. *
  275. * @brief The class which acts as a predicate for applying the
  276. * first-fit memory allocation policy for the bitmap allocator.
  277. */
  278. // _Tp should be a pointer type, and _Alloc is the Allocator for
  279. // the vector.
  280. template<typename _Tp>
  281. class _Ffit_finder
  282. : public std::unary_function<typename std::pair<_Tp, _Tp>, bool>
  283. {
  284. typedef typename std::pair<_Tp, _Tp> _Block_pair;
  285. typedef typename __detail::__mini_vector<_Block_pair> _BPVector;
  286. typedef typename _BPVector::difference_type _Counter_type;
  287. std::size_t* _M_pbitmap;
  288. _Counter_type _M_data_offset;
  289. public:
  290. _Ffit_finder() : _M_pbitmap(0), _M_data_offset(0)
  291. { }
  292. bool
  293. operator()(_Block_pair __bp) throw()
  294. {
  295. using std::size_t;
  296. // Set the _rover to the last physical location bitmap,
  297. // which is the bitmap which belongs to the first free
  298. // block. Thus, the bitmaps are in exact reverse order of
  299. // the actual memory layout. So, we count down the bitmaps,
  300. // which is the same as moving up the memory.
  301. // If the used count stored at the start of the Bit Map headers
  302. // is equal to the number of Objects that the current Block can
  303. // store, then there is definitely no space for another single
  304. // object, so just return false.
  305. _Counter_type __diff = __detail::__num_bitmaps(__bp);
  306. if (*(reinterpret_cast<size_t*>
  307. (__bp.first) - (__diff + 1)) == __detail::__num_blocks(__bp))
  308. return false;
  309. size_t* __rover = reinterpret_cast<size_t*>(__bp.first) - 1;
  310. for (_Counter_type __i = 0; __i < __diff; ++__i)
  311. {
  312. _M_data_offset = __i;
  313. if (*__rover)
  314. {
  315. _M_pbitmap = __rover;
  316. return true;
  317. }
  318. --__rover;
  319. }
  320. return false;
  321. }
  322. std::size_t*
  323. _M_get() const throw()
  324. { return _M_pbitmap; }
  325. _Counter_type
  326. _M_offset() const throw()
  327. { return _M_data_offset * std::size_t(bits_per_block); }
  328. };
  329. /** @class _Bitmap_counter bitmap_allocator.h bitmap_allocator.h
  330. *
  331. * @brief The bitmap counter which acts as the bitmap
  332. * manipulator, and manages the bit-manipulation functions and
  333. * the searching and identification functions on the bit-map.
  334. */
  335. // _Tp should be a pointer type.
  336. template<typename _Tp>
  337. class _Bitmap_counter
  338. {
  339. typedef typename
  340. __detail::__mini_vector<typename std::pair<_Tp, _Tp> > _BPVector;
  341. typedef typename _BPVector::size_type _Index_type;
  342. typedef _Tp pointer;
  343. _BPVector& _M_vbp;
  344. std::size_t* _M_curr_bmap;
  345. std::size_t* _M_last_bmap_in_block;
  346. _Index_type _M_curr_index;
  347. public:
  348. // Use the 2nd parameter with care. Make sure that such an
  349. // entry exists in the vector before passing that particular
  350. // index to this ctor.
  351. _Bitmap_counter(_BPVector& Rvbp, long __index = -1) : _M_vbp(Rvbp)
  352. { this->_M_reset(__index); }
  353. void
  354. _M_reset(long __index = -1) throw()
  355. {
  356. if (__index == -1)
  357. {
  358. _M_curr_bmap = 0;
  359. _M_curr_index = static_cast<_Index_type>(-1);
  360. return;
  361. }
  362. _M_curr_index = __index;
  363. _M_curr_bmap = reinterpret_cast<std::size_t*>
  364. (_M_vbp[_M_curr_index].first) - 1;
  365. _GLIBCXX_DEBUG_ASSERT(__index <= (long)_M_vbp.size() - 1);
  366. _M_last_bmap_in_block = _M_curr_bmap
  367. - ((_M_vbp[_M_curr_index].second
  368. - _M_vbp[_M_curr_index].first + 1)
  369. / std::size_t(bits_per_block) - 1);
  370. }
  371. // Dangerous Function! Use with extreme care. Pass to this
  372. // function ONLY those values that are known to be correct,
  373. // otherwise this will mess up big time.
  374. void
  375. _M_set_internal_bitmap(std::size_t* __new_internal_marker) throw()
  376. { _M_curr_bmap = __new_internal_marker; }
  377. bool
  378. _M_finished() const throw()
  379. { return(_M_curr_bmap == 0); }
  380. _Bitmap_counter&
  381. operator++() throw()
  382. {
  383. if (_M_curr_bmap == _M_last_bmap_in_block)
  384. {
  385. if (++_M_curr_index == _M_vbp.size())
  386. _M_curr_bmap = 0;
  387. else
  388. this->_M_reset(_M_curr_index);
  389. }
  390. else
  391. --_M_curr_bmap;
  392. return *this;
  393. }
  394. std::size_t*
  395. _M_get() const throw()
  396. { return _M_curr_bmap; }
  397. pointer
  398. _M_base() const throw()
  399. { return _M_vbp[_M_curr_index].first; }
  400. _Index_type
  401. _M_offset() const throw()
  402. {
  403. return std::size_t(bits_per_block)
  404. * ((reinterpret_cast<std::size_t*>(this->_M_base())
  405. - _M_curr_bmap) - 1);
  406. }
  407. _Index_type
  408. _M_where() const throw()
  409. { return _M_curr_index; }
  410. };
  411. /** @brief Mark a memory address as allocated by re-setting the
  412. * corresponding bit in the bit-map.
  413. */
  414. inline void
  415. __bit_allocate(std::size_t* __pbmap, std::size_t __pos) throw()
  416. {
  417. std::size_t __mask = 1 << __pos;
  418. __mask = ~__mask;
  419. *__pbmap &= __mask;
  420. }
  421. /** @brief Mark a memory address as free by setting the
  422. * corresponding bit in the bit-map.
  423. */
  424. inline void
  425. __bit_free(std::size_t* __pbmap, std::size_t __pos) throw()
  426. {
  427. std::size_t __mask = 1 << __pos;
  428. *__pbmap |= __mask;
  429. }
  430. } // namespace __detail
  431. /** @brief Generic Version of the bsf instruction.
  432. */
  433. inline std::size_t
  434. _Bit_scan_forward(std::size_t __num)
  435. { return static_cast<std::size_t>(__builtin_ctzl(__num)); }
  436. /** @class free_list bitmap_allocator.h bitmap_allocator.h
  437. *
  438. * @brief The free list class for managing chunks of memory to be
  439. * given to and returned by the bitmap_allocator.
  440. */
  441. class free_list
  442. {
  443. public:
  444. typedef std::size_t* value_type;
  445. typedef __detail::__mini_vector<value_type> vector_type;
  446. typedef vector_type::iterator iterator;
  447. typedef __mutex __mutex_type;
  448. private:
  449. struct _LT_pointer_compare
  450. {
  451. bool
  452. operator()(const std::size_t* __pui,
  453. const std::size_t __cui) const throw()
  454. { return *__pui < __cui; }
  455. };
  456. #if defined __GTHREADS
  457. __mutex_type&
  458. _M_get_mutex()
  459. {
  460. static __mutex_type _S_mutex;
  461. return _S_mutex;
  462. }
  463. #endif
  464. vector_type&
  465. _M_get_free_list()
  466. {
  467. static vector_type _S_free_list;
  468. return _S_free_list;
  469. }
  470. /** @brief Performs validation of memory based on their size.
  471. *
  472. * @param __addr The pointer to the memory block to be
  473. * validated.
  474. *
  475. * Validates the memory block passed to this function and
  476. * appropriately performs the action of managing the free list of
  477. * blocks by adding this block to the free list or deleting this
  478. * or larger blocks from the free list.
  479. */
  480. void
  481. _M_validate(std::size_t* __addr) throw()
  482. {
  483. vector_type& __free_list = _M_get_free_list();
  484. const vector_type::size_type __max_size = 64;
  485. if (__free_list.size() >= __max_size)
  486. {
  487. // Ok, the threshold value has been reached. We determine
  488. // which block to remove from the list of free blocks.
  489. if (*__addr >= *__free_list.back())
  490. {
  491. // Ok, the new block is greater than or equal to the
  492. // last block in the list of free blocks. We just free
  493. // the new block.
  494. ::operator delete(static_cast<void*>(__addr));
  495. return;
  496. }
  497. else
  498. {
  499. // Deallocate the last block in the list of free lists,
  500. // and insert the new one in its correct position.
  501. ::operator delete(static_cast<void*>(__free_list.back()));
  502. __free_list.pop_back();
  503. }
  504. }
  505. // Just add the block to the list of free lists unconditionally.
  506. iterator __temp = __detail::__lower_bound
  507. (__free_list.begin(), __free_list.end(),
  508. *__addr, _LT_pointer_compare());
  509. // We may insert the new free list before _temp;
  510. __free_list.insert(__temp, __addr);
  511. }
  512. /** @brief Decides whether the wastage of memory is acceptable for
  513. * the current memory request and returns accordingly.
  514. *
  515. * @param __block_size The size of the block available in the free
  516. * list.
  517. *
  518. * @param __required_size The required size of the memory block.
  519. *
  520. * @return true if the wastage incurred is acceptable, else returns
  521. * false.
  522. */
  523. bool
  524. _M_should_i_give(std::size_t __block_size,
  525. std::size_t __required_size) throw()
  526. {
  527. const std::size_t __max_wastage_percentage = 36;
  528. if (__block_size >= __required_size &&
  529. (((__block_size - __required_size) * 100 / __block_size)
  530. < __max_wastage_percentage))
  531. return true;
  532. else
  533. return false;
  534. }
  535. public:
  536. /** @brief This function returns the block of memory to the
  537. * internal free list.
  538. *
  539. * @param __addr The pointer to the memory block that was given
  540. * by a call to the _M_get function.
  541. */
  542. inline void
  543. _M_insert(std::size_t* __addr) throw()
  544. {
  545. #if defined __GTHREADS
  546. __scoped_lock __bfl_lock(_M_get_mutex());
  547. #endif
  548. // Call _M_validate to decide what should be done with
  549. // this particular free list.
  550. this->_M_validate(reinterpret_cast<std::size_t*>(__addr) - 1);
  551. // See discussion as to why this is 1!
  552. }
  553. /** @brief This function gets a block of memory of the specified
  554. * size from the free list.
  555. *
  556. * @param __sz The size in bytes of the memory required.
  557. *
  558. * @return A pointer to the new memory block of size at least
  559. * equal to that requested.
  560. */
  561. std::size_t*
  562. _M_get(std::size_t __sz) _GLIBCXX_THROW(std::bad_alloc);
  563. /** @brief This function just clears the internal Free List, and
  564. * gives back all the memory to the OS.
  565. */
  566. void
  567. _M_clear();
  568. };
  569. // Forward declare the class.
  570. template<typename _Tp>
  571. class bitmap_allocator;
  572. // Specialize for void:
  573. template<>
  574. class bitmap_allocator<void>
  575. {
  576. public:
  577. typedef void* pointer;
  578. typedef const void* const_pointer;
  579. // Reference-to-void members are impossible.
  580. typedef void value_type;
  581. template<typename _Tp1>
  582. struct rebind
  583. {
  584. typedef bitmap_allocator<_Tp1> other;
  585. };
  586. };
  587. /**
  588. * @brief Bitmap Allocator, primary template.
  589. * @ingroup allocators
  590. */
  591. template<typename _Tp>
  592. class bitmap_allocator : private free_list
  593. {
  594. public:
  595. typedef std::size_t size_type;
  596. typedef std::ptrdiff_t difference_type;
  597. typedef _Tp* pointer;
  598. typedef const _Tp* const_pointer;
  599. typedef _Tp& reference;
  600. typedef const _Tp& const_reference;
  601. typedef _Tp value_type;
  602. typedef free_list::__mutex_type __mutex_type;
  603. template<typename _Tp1>
  604. struct rebind
  605. {
  606. typedef bitmap_allocator<_Tp1> other;
  607. };
  608. #if __cplusplus >= 201103L
  609. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  610. // 2103. propagate_on_container_move_assignment
  611. typedef std::true_type propagate_on_container_move_assignment;
  612. #endif
  613. private:
  614. template<std::size_t _BSize, std::size_t _AlignSize>
  615. struct aligned_size
  616. {
  617. enum
  618. {
  619. modulus = _BSize % _AlignSize,
  620. value = _BSize + (modulus ? _AlignSize - (modulus) : 0)
  621. };
  622. };
  623. struct _Alloc_block
  624. {
  625. char __M_unused[aligned_size<sizeof(value_type),
  626. _BALLOC_ALIGN_BYTES>::value];
  627. };
  628. typedef typename std::pair<_Alloc_block*, _Alloc_block*> _Block_pair;
  629. typedef typename __detail::__mini_vector<_Block_pair> _BPVector;
  630. typedef typename _BPVector::iterator _BPiter;
  631. template<typename _Predicate>
  632. static _BPiter
  633. _S_find(_Predicate __p)
  634. {
  635. _BPiter __first = _S_mem_blocks.begin();
  636. while (__first != _S_mem_blocks.end() && !__p(*__first))
  637. ++__first;
  638. return __first;
  639. }
  640. #if defined _GLIBCXX_DEBUG
  641. // Complexity: O(lg(N)). Where, N is the number of block of size
  642. // sizeof(value_type).
  643. void
  644. _S_check_for_free_blocks() throw()
  645. {
  646. typedef typename __detail::_Ffit_finder<_Alloc_block*> _FFF;
  647. _BPiter __bpi = _S_find(_FFF());
  648. _GLIBCXX_DEBUG_ASSERT(__bpi == _S_mem_blocks.end());
  649. }
  650. #endif
  651. /** @brief Responsible for exponentially growing the internal
  652. * memory pool.
  653. *
  654. * @throw std::bad_alloc. If memory cannot be allocated.
  655. *
  656. * Complexity: O(1), but internally depends upon the
  657. * complexity of the function free_list::_M_get. The part where
  658. * the bitmap headers are written has complexity: O(X),where X
  659. * is the number of blocks of size sizeof(value_type) within
  660. * the newly acquired block. Having a tight bound.
  661. */
  662. void
  663. _S_refill_pool() _GLIBCXX_THROW(std::bad_alloc)
  664. {
  665. using std::size_t;
  666. #if defined _GLIBCXX_DEBUG
  667. _S_check_for_free_blocks();
  668. #endif
  669. const size_t __num_bitmaps = (_S_block_size
  670. / size_t(__detail::bits_per_block));
  671. const size_t __size_to_allocate = sizeof(size_t)
  672. + _S_block_size * sizeof(_Alloc_block)
  673. + __num_bitmaps * sizeof(size_t);
  674. size_t* __temp =
  675. reinterpret_cast<size_t*>(this->_M_get(__size_to_allocate));
  676. *__temp = 0;
  677. ++__temp;
  678. // The Header information goes at the Beginning of the Block.
  679. _Block_pair __bp =
  680. std::make_pair(reinterpret_cast<_Alloc_block*>
  681. (__temp + __num_bitmaps),
  682. reinterpret_cast<_Alloc_block*>
  683. (__temp + __num_bitmaps)
  684. + _S_block_size - 1);
  685. // Fill the Vector with this information.
  686. _S_mem_blocks.push_back(__bp);
  687. for (size_t __i = 0; __i < __num_bitmaps; ++__i)
  688. __temp[__i] = ~static_cast<size_t>(0); // 1 Indicates all Free.
  689. _S_block_size *= 2;
  690. }
  691. static _BPVector _S_mem_blocks;
  692. static std::size_t _S_block_size;
  693. static __detail::_Bitmap_counter<_Alloc_block*> _S_last_request;
  694. static typename _BPVector::size_type _S_last_dealloc_index;
  695. #if defined __GTHREADS
  696. static __mutex_type _S_mut;
  697. #endif
  698. public:
  699. /** @brief Allocates memory for a single object of size
  700. * sizeof(_Tp).
  701. *
  702. * @throw std::bad_alloc. If memory cannot be allocated.
  703. *
  704. * Complexity: Worst case complexity is O(N), but that
  705. * is hardly ever hit. If and when this particular case is
  706. * encountered, the next few cases are guaranteed to have a
  707. * worst case complexity of O(1)! That's why this function
  708. * performs very well on average. You can consider this
  709. * function to have a complexity referred to commonly as:
  710. * Amortized Constant time.
  711. */
  712. pointer
  713. _M_allocate_single_object() _GLIBCXX_THROW(std::bad_alloc)
  714. {
  715. using std::size_t;
  716. #if defined __GTHREADS
  717. __scoped_lock __bit_lock(_S_mut);
  718. #endif
  719. // The algorithm is something like this: The last_request
  720. // variable points to the last accessed Bit Map. When such a
  721. // condition occurs, we try to find a free block in the
  722. // current bitmap, or succeeding bitmaps until the last bitmap
  723. // is reached. If no free block turns up, we resort to First
  724. // Fit method.
  725. // WARNING: Do not re-order the condition in the while
  726. // statement below, because it relies on C++'s short-circuit
  727. // evaluation. The return from _S_last_request->_M_get() will
  728. // NOT be dereference able if _S_last_request->_M_finished()
  729. // returns true. This would inevitably lead to a NULL pointer
  730. // dereference if tinkered with.
  731. while (_S_last_request._M_finished() == false
  732. && (*(_S_last_request._M_get()) == 0))
  733. _S_last_request.operator++();
  734. if (__builtin_expect(_S_last_request._M_finished() == true, false))
  735. {
  736. // Fall Back to First Fit algorithm.
  737. typedef typename __detail::_Ffit_finder<_Alloc_block*> _FFF;
  738. _FFF __fff;
  739. _BPiter __bpi = _S_find(__detail::_Functor_Ref<_FFF>(__fff));
  740. if (__bpi != _S_mem_blocks.end())
  741. {
  742. // Search was successful. Ok, now mark the first bit from
  743. // the right as 0, meaning Allocated. This bit is obtained
  744. // by calling _M_get() on __fff.
  745. size_t __nz_bit = _Bit_scan_forward(*__fff._M_get());
  746. __detail::__bit_allocate(__fff._M_get(), __nz_bit);
  747. _S_last_request._M_reset(__bpi - _S_mem_blocks.begin());
  748. // Now, get the address of the bit we marked as allocated.
  749. pointer __ret = reinterpret_cast<pointer>
  750. (__bpi->first + __fff._M_offset() + __nz_bit);
  751. size_t* __puse_count =
  752. reinterpret_cast<size_t*>
  753. (__bpi->first) - (__detail::__num_bitmaps(*__bpi) + 1);
  754. ++(*__puse_count);
  755. return __ret;
  756. }
  757. else
  758. {
  759. // Search was unsuccessful. We Add more memory to the
  760. // pool by calling _S_refill_pool().
  761. _S_refill_pool();
  762. // _M_Reset the _S_last_request structure to the first
  763. // free block's bit map.
  764. _S_last_request._M_reset(_S_mem_blocks.size() - 1);
  765. // Now, mark that bit as allocated.
  766. }
  767. }
  768. // _S_last_request holds a pointer to a valid bit map, that
  769. // points to a free block in memory.
  770. size_t __nz_bit = _Bit_scan_forward(*_S_last_request._M_get());
  771. __detail::__bit_allocate(_S_last_request._M_get(), __nz_bit);
  772. pointer __ret = reinterpret_cast<pointer>
  773. (_S_last_request._M_base() + _S_last_request._M_offset() + __nz_bit);
  774. size_t* __puse_count = reinterpret_cast<size_t*>
  775. (_S_mem_blocks[_S_last_request._M_where()].first)
  776. - (__detail::
  777. __num_bitmaps(_S_mem_blocks[_S_last_request._M_where()]) + 1);
  778. ++(*__puse_count);
  779. return __ret;
  780. }
  781. /** @brief Deallocates memory that belongs to a single object of
  782. * size sizeof(_Tp).
  783. *
  784. * Complexity: O(lg(N)), but the worst case is not hit
  785. * often! This is because containers usually deallocate memory
  786. * close to each other and this case is handled in O(1) time by
  787. * the deallocate function.
  788. */
  789. void
  790. _M_deallocate_single_object(pointer __p) throw()
  791. {
  792. using std::size_t;
  793. #if defined __GTHREADS
  794. __scoped_lock __bit_lock(_S_mut);
  795. #endif
  796. _Alloc_block* __real_p = reinterpret_cast<_Alloc_block*>(__p);
  797. typedef typename _BPVector::iterator _Iterator;
  798. typedef typename _BPVector::difference_type _Difference_type;
  799. _Difference_type __diff;
  800. long __displacement;
  801. _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0);
  802. __detail::_Inclusive_between<_Alloc_block*> __ibt(__real_p);
  803. if (__ibt(_S_mem_blocks[_S_last_dealloc_index]))
  804. {
  805. _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index
  806. <= _S_mem_blocks.size() - 1);
  807. // Initial Assumption was correct!
  808. __diff = _S_last_dealloc_index;
  809. __displacement = __real_p - _S_mem_blocks[__diff].first;
  810. }
  811. else
  812. {
  813. _Iterator _iter = _S_find(__ibt);
  814. _GLIBCXX_DEBUG_ASSERT(_iter != _S_mem_blocks.end());
  815. __diff = _iter - _S_mem_blocks.begin();
  816. __displacement = __real_p - _S_mem_blocks[__diff].first;
  817. _S_last_dealloc_index = __diff;
  818. }
  819. // Get the position of the iterator that has been found.
  820. const size_t __rotate = (__displacement
  821. % size_t(__detail::bits_per_block));
  822. size_t* __bitmapC =
  823. reinterpret_cast<size_t*>
  824. (_S_mem_blocks[__diff].first) - 1;
  825. __bitmapC -= (__displacement / size_t(__detail::bits_per_block));
  826. __detail::__bit_free(__bitmapC, __rotate);
  827. size_t* __puse_count = reinterpret_cast<size_t*>
  828. (_S_mem_blocks[__diff].first)
  829. - (__detail::__num_bitmaps(_S_mem_blocks[__diff]) + 1);
  830. _GLIBCXX_DEBUG_ASSERT(*__puse_count != 0);
  831. --(*__puse_count);
  832. if (__builtin_expect(*__puse_count == 0, false))
  833. {
  834. _S_block_size /= 2;
  835. // We can safely remove this block.
  836. // _Block_pair __bp = _S_mem_blocks[__diff];
  837. this->_M_insert(__puse_count);
  838. _S_mem_blocks.erase(_S_mem_blocks.begin() + __diff);
  839. // Reset the _S_last_request variable to reflect the
  840. // erased block. We do this to protect future requests
  841. // after the last block has been removed from a particular
  842. // memory Chunk, which in turn has been returned to the
  843. // free list, and hence had been erased from the vector,
  844. // so the size of the vector gets reduced by 1.
  845. if ((_Difference_type)_S_last_request._M_where() >= __diff--)
  846. _S_last_request._M_reset(__diff);
  847. // If the Index into the vector of the region of memory
  848. // that might hold the next address that will be passed to
  849. // deallocated may have been invalidated due to the above
  850. // erase procedure being called on the vector, hence we
  851. // try to restore this invariant too.
  852. if (_S_last_dealloc_index >= _S_mem_blocks.size())
  853. {
  854. _S_last_dealloc_index =(__diff != -1 ? __diff : 0);
  855. _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0);
  856. }
  857. }
  858. }
  859. public:
  860. bitmap_allocator() _GLIBCXX_USE_NOEXCEPT
  861. { }
  862. bitmap_allocator(const bitmap_allocator&) _GLIBCXX_USE_NOEXCEPT
  863. { }
  864. template<typename _Tp1>
  865. bitmap_allocator(const bitmap_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT
  866. { }
  867. ~bitmap_allocator() _GLIBCXX_USE_NOEXCEPT
  868. { }
  869. _GLIBCXX_NODISCARD pointer
  870. allocate(size_type __n)
  871. {
  872. if (__n > this->max_size())
  873. std::__throw_bad_alloc();
  874. #if __cpp_aligned_new
  875. if (alignof(value_type) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
  876. {
  877. const size_type __b = __n * sizeof(value_type);
  878. std::align_val_t __al = std::align_val_t(alignof(value_type));
  879. return static_cast<pointer>(::operator new(__b, __al));
  880. }
  881. #endif
  882. if (__builtin_expect(__n == 1, true))
  883. return this->_M_allocate_single_object();
  884. else
  885. {
  886. const size_type __b = __n * sizeof(value_type);
  887. return reinterpret_cast<pointer>(::operator new(__b));
  888. }
  889. }
  890. _GLIBCXX_NODISCARD pointer
  891. allocate(size_type __n, typename bitmap_allocator<void>::const_pointer)
  892. { return allocate(__n); }
  893. void
  894. deallocate(pointer __p, size_type __n) throw()
  895. {
  896. if (__builtin_expect(__p != 0, true))
  897. {
  898. #if __cpp_aligned_new
  899. // Types with extended alignment are handled by operator delete.
  900. if (alignof(value_type) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
  901. {
  902. ::operator delete(__p, std::align_val_t(alignof(value_type)));
  903. return;
  904. }
  905. #endif
  906. if (__builtin_expect(__n == 1, true))
  907. this->_M_deallocate_single_object(__p);
  908. else
  909. ::operator delete(__p);
  910. }
  911. }
  912. pointer
  913. address(reference __r) const _GLIBCXX_NOEXCEPT
  914. { return std::__addressof(__r); }
  915. const_pointer
  916. address(const_reference __r) const _GLIBCXX_NOEXCEPT
  917. { return std::__addressof(__r); }
  918. size_type
  919. max_size() const _GLIBCXX_USE_NOEXCEPT
  920. { return size_type(-1) / sizeof(value_type); }
  921. #if __cplusplus >= 201103L
  922. template<typename _Up, typename... _Args>
  923. void
  924. construct(_Up* __p, _Args&&... __args)
  925. { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
  926. template<typename _Up>
  927. void
  928. destroy(_Up* __p)
  929. { __p->~_Up(); }
  930. #else
  931. void
  932. construct(pointer __p, const_reference __data)
  933. { ::new((void *)__p) value_type(__data); }
  934. void
  935. destroy(pointer __p)
  936. { __p->~value_type(); }
  937. #endif
  938. };
  939. template<typename _Tp1, typename _Tp2>
  940. bool
  941. operator==(const bitmap_allocator<_Tp1>&,
  942. const bitmap_allocator<_Tp2>&) throw()
  943. { return true; }
  944. #if __cpp_impl_three_way_comparison < 201907L
  945. template<typename _Tp1, typename _Tp2>
  946. bool
  947. operator!=(const bitmap_allocator<_Tp1>&,
  948. const bitmap_allocator<_Tp2>&) throw()
  949. { return false; }
  950. #endif
  951. // Static member definitions.
  952. template<typename _Tp>
  953. typename bitmap_allocator<_Tp>::_BPVector
  954. bitmap_allocator<_Tp>::_S_mem_blocks;
  955. template<typename _Tp>
  956. std::size_t bitmap_allocator<_Tp>::_S_block_size
  957. = 2 * std::size_t(__detail::bits_per_block);
  958. template<typename _Tp>
  959. typename bitmap_allocator<_Tp>::_BPVector::size_type
  960. bitmap_allocator<_Tp>::_S_last_dealloc_index = 0;
  961. template<typename _Tp>
  962. __detail::_Bitmap_counter
  963. <typename bitmap_allocator<_Tp>::_Alloc_block*>
  964. bitmap_allocator<_Tp>::_S_last_request(_S_mem_blocks);
  965. #if defined __GTHREADS
  966. template<typename _Tp>
  967. typename bitmap_allocator<_Tp>::__mutex_type
  968. bitmap_allocator<_Tp>::_S_mut;
  969. #endif
  970. _GLIBCXX_END_NAMESPACE_VERSION
  971. } // namespace __gnu_cxx
  972. #endif