29 #ifndef _MT_ALLOCATOR_H 
   30 #define _MT_ALLOCATOR_H 1 
   37 #if __cplusplus >= 201103L 
   41 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 
   43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   48   typedef void (*__destroy_handler)(
void*);
 
   55     typedef unsigned short int _Binmap_type;
 
   62       enum { _S_align = 8 };
 
   63       enum { _S_max_bytes = 128 };
 
   64       enum { _S_min_bin = 8 };
 
   65       enum { _S_chunk_size = 4096 - 4 * 
sizeof(
void*) };
 
   66       enum { _S_max_threads = 4096 };
 
   67       enum { _S_freelist_headroom = 10 };
 
  100       size_t    _M_max_threads;
 
  108       size_t    _M_freelist_headroom;
 
  115       : _M_align(_S_align), _M_max_bytes(_S_max_bytes), _M_min_bin(_S_min_bin),
 
  116       _M_chunk_size(_S_chunk_size), _M_max_threads(_S_max_threads), 
 
  117       _M_freelist_headroom(_S_freelist_headroom), 
 
  118       _M_force_new(std::getenv(
"GLIBCXX_FORCE_NEW") ? 
true : 
false)
 
  122       _Tune(
size_t __align, 
size_t __maxb, 
size_t __minbin, 
size_t __chunk, 
 
  123         size_t __maxthreads, 
size_t __headroom, 
bool __force) 
 
  124       : _M_align(__align), _M_max_bytes(__maxb), _M_min_bin(__minbin),
 
  125       _M_chunk_size(__chunk), _M_max_threads(__maxthreads),
 
  126       _M_freelist_headroom(__headroom), _M_force_new(__force)
 
  130     struct _Block_address
 
  133       _Block_address*       _M_next;
 
  137     _M_get_options()
 const 
  138     { 
return _M_options; }
 
  141     _M_set_options(_Tune __t)
 
  148     _M_check_threshold(
size_t __bytes)
 
  149     { 
return __bytes > _M_options._M_max_bytes || _M_options._M_force_new; }
 
  152     _M_get_binmap(
size_t __bytes)
 
  153     { 
return _M_binmap[__bytes]; }
 
  157     { 
return _M_options._M_align; }
 
  161     : _M_options(_Tune()), _M_binmap(0), _M_init(
false) { }
 
  165     : _M_options(__options), _M_binmap(0), _M_init(
false) { }
 
  178     _Binmap_type*       _M_binmap;
 
  191   template<
bool _Thread>
 
  202     _Block_record*          _M_next;
 
  208     _Block_record**         _M_first;
 
  211     _Block_address*             _M_address;
 
  217     if (__builtin_expect(_M_init == 
false, 
false))
 
  222       _M_destroy() 
throw();
 
  225       _M_reserve_block(
size_t __bytes, 
const size_t __thread_id);
 
  228       _M_reclaim_block(
char* __p, 
size_t __bytes) 
throw ();
 
  231       _M_get_thread_id() { 
return 0; }
 
  234       _M_get_bin(
size_t __which)
 
  235       { 
return _M_bin[__which]; }
 
  238       _M_adjust_freelist(
const _Bin_record&, _Block_record*, 
size_t)
 
  242       : _M_bin(0), _M_bin_size(1) { }
 
  244       explicit __pool(
const __pool_base::_Tune& __tune) 
 
  245       : 
__pool_base(__tune), _M_bin(0), _M_bin_size(1) { }
 
  275       struct _Thread_record
 
  278     _Thread_record*         _M_next;
 
  287     _Block_record*          _M_next;
 
  298     _Block_record**         _M_first;
 
  301     _Block_address*             _M_address;
 
  318     __gthread_mutex_t*              _M_mutex;
 
  323       _M_initialize(__destroy_handler);
 
  328     if (__builtin_expect(_M_init == 
false, 
false))
 
  333       _M_destroy() 
throw();
 
  336       _M_reserve_block(
size_t __bytes, 
const size_t __thread_id);
 
  339       _M_reclaim_block(
char* __p, 
size_t __bytes) 
throw ();
 
  342       _M_get_bin(
size_t __which)
 
  343       { 
return _M_bin[__which]; }
 
  346       _M_adjust_freelist(
const _Bin_record& __bin, _Block_record* __block, 
 
  349     if (__gthread_active_p())
 
  351         __block->_M_thread_id = __thread_id;
 
  352         --__bin._M_free[__thread_id];
 
  353         ++__bin._M_used[__thread_id];
 
  359       _M_destroy_thread_key(
void*) 
throw ();
 
  365       : _M_bin(0), _M_bin_size(1), _M_thread_freelist(0) 
 
  368       explicit __pool(
const __pool_base::_Tune& __tune) 
 
  370     _M_thread_freelist(0) 
 
  382       _Thread_record*       _M_thread_freelist;
 
  383       void*         _M_thread_freelist_initial;
 
  390   template<
template <
bool> 
class _PoolTp, 
bool _Thread>
 
  393       typedef _PoolTp<_Thread>      pool_type;
 
  398     static pool_type _S_pool;
 
  403   template<
template <
bool> 
class _PoolTp, 
bool _Thread>
 
  404     struct __common_pool_base;
 
  406   template<
template <
bool> 
class _PoolTp>
 
  407     struct __common_pool_base<_PoolTp, false> 
 
  408     : 
public __common_pool<_PoolTp, false>
 
  410       using  __common_pool<_PoolTp, false>::_S_get_pool;
 
  416     if (__builtin_expect(__init == 
false, 
false))
 
  418         _S_get_pool()._M_initialize_once(); 
 
  425   template<
template <
bool> 
class _PoolTp>
 
  426     struct __common_pool_base<_PoolTp, true>
 
  427     : 
public __common_pool<_PoolTp, true>
 
  429       using  __common_pool<_PoolTp, true>::_S_get_pool;
 
  433       { _S_get_pool()._M_initialize_once(); }
 
  439     if (__builtin_expect(__init == 
false, 
false))
 
  441         if (__gthread_active_p())
 
  444         static __gthread_once_t __once = __GTHREAD_ONCE_INIT;
 
  445         __gthread_once(&__once, _S_initialize);
 
  451         _S_get_pool()._M_initialize_once(); 
 
  459   template<
template <
bool> 
class _PoolTp, 
bool _Thread>
 
  462       template<
typename _Tp1, 
template <
bool> 
class _PoolTp1 = _PoolTp, 
 
  463            bool _Thread1 = _Thread>
 
  467       using  __common_pool_base<_PoolTp, _Thread>::_S_get_pool;
 
  468       using  __common_pool_base<_PoolTp, _Thread>::_S_initialize_once;
 
  472   template<
typename _Tp, 
template <
bool> 
class _PoolTp, 
bool _Thread>
 
  473     struct __per_type_pool
 
  475       typedef _Tp           value_type;
 
  476       typedef _PoolTp<_Thread>      pool_type;
 
  482     typedef typename pool_type::_Block_record _Block_record;
 
  483     const static size_t __a = (__alignof__(_Tp) >= 
sizeof(_Block_record)
 
  484                    ? __alignof__(_Tp) : 
sizeof(_Block_record));
 
  486     typedef typename __pool_base::_Tune _Tune;
 
  487     static _Tune _S_tune(__a, 
sizeof(_Tp) * 64,
 
  488                  sizeof(_Tp) * 2 >= __a ? 
sizeof(_Tp) * 2 : __a,
 
  489                  sizeof(_Tp) * 
size_t(_Tune::_S_chunk_size),
 
  490                  _Tune::_S_max_threads,
 
  491                  _Tune::_S_freelist_headroom,
 
  492                  std::getenv(
"GLIBCXX_FORCE_NEW") ? 
true : 
false);
 
  493     static pool_type _S_pool(_S_tune);
 
  498   template<
typename _Tp, 
template <
bool> 
class _PoolTp, 
bool _Thread>
 
  499     struct __per_type_pool_base;
 
  501   template<
typename _Tp, 
template <
bool> 
class _PoolTp>
 
  502     struct __per_type_pool_base<_Tp, _PoolTp, false> 
 
  503     : 
public __per_type_pool<_Tp, _PoolTp, false> 
 
  505       using  __per_type_pool<_Tp, _PoolTp, false>::_S_get_pool;
 
  511     if (__builtin_expect(__init == 
false, 
false))
 
  513         _S_get_pool()._M_initialize_once(); 
 
  520  template<
typename _Tp, 
template <
bool> 
class _PoolTp>
 
  521     struct __per_type_pool_base<_Tp, _PoolTp, true> 
 
  522     : 
public __per_type_pool<_Tp, _PoolTp, true> 
 
  524       using  __per_type_pool<_Tp, _PoolTp, true>::_S_get_pool;
 
  528       { _S_get_pool()._M_initialize_once(); }
 
  534     if (__builtin_expect(__init == 
false, 
false))
 
  536         if (__gthread_active_p())
 
  539         static __gthread_once_t __once = __GTHREAD_ONCE_INIT;
 
  540         __gthread_once(&__once, _S_initialize);
 
  546         _S_get_pool()._M_initialize_once(); 
 
  554   template<
typename _Tp, 
template <
bool> 
class _PoolTp, 
bool _Thread>
 
  556     : 
public __per_type_pool_base<_Tp, _PoolTp, _Thread>
 
  558       template<
typename _Tp1, 
template <
bool> 
class _PoolTp1 = _PoolTp, 
 
  559            bool _Thread1 = _Thread>
 
  563       using  __per_type_pool_base<_Tp, _PoolTp, _Thread>::_S_get_pool;
 
  564       using  __per_type_pool_base<_Tp, _PoolTp, _Thread>::_S_initialize_once;
 
  569   template<
typename _Tp>
 
  573       typedef size_t                    size_type;
 
  574       typedef ptrdiff_t                 difference_type;
 
  575       typedef _Tp*                      pointer;
 
  576       typedef const _Tp*                const_pointer;
 
  577       typedef _Tp&                      reference;
 
  578       typedef const _Tp&                const_reference;
 
  579       typedef _Tp                       value_type;
 
  581 #if __cplusplus >= 201103L 
  588       address(reference __x) 
const _GLIBCXX_NOEXCEPT
 
  592       address(const_reference __x) 
const _GLIBCXX_NOEXCEPT
 
  596       max_size() 
const _GLIBCXX_USE_NOEXCEPT 
 
  597       { 
return size_t(-1) / 
sizeof(_Tp); }
 
  599 #if __cplusplus >= 201103L 
  600       template<
typename _Up, 
typename... _Args>
 
  602         construct(_Up* __p, _Args&&... __args)
 
  603     { ::new((
void *)__p) _Up(std::forward<_Args>(__args)...); }
 
  605       template<
typename _Up>
 
  607         destroy(_Up* __p) { __p->~_Up(); }
 
  612       construct(pointer __p, 
const _Tp& __val) 
 
  613       { ::new((
void *)__p) _Tp(__val); }
 
  616       destroy(pointer __p) { __p->~_Tp(); }
 
  621 #define __thread_default true 
  623 #define __thread_default false 
  637   template<
typename _Tp, 
 
  642       typedef size_t                        size_type;
 
  643       typedef ptrdiff_t                     difference_type;
 
  644       typedef _Tp*                          pointer;
 
  645       typedef const _Tp*                    const_pointer;
 
  646       typedef _Tp&                          reference;
 
  647       typedef const _Tp&                    const_reference;
 
  648       typedef _Tp                           value_type;
 
  649       typedef _Poolp                __policy_type;
 
  650       typedef typename _Poolp::pool_type    __pool_type;
 
  652       template<
typename _Tp1, 
typename _Poolp1 = _Poolp>
 
  655       typedef typename _Poolp1::template _M_rebind<_Tp1>::other pol_type;
 
  663       template<
typename _Tp1, 
typename _Poolp1>
 
  669       allocate(size_type __n, 
const void* = 0);
 
  672       deallocate(pointer __p, size_type __n);
 
  674       const __pool_base::_Tune
 
  678     return __policy_type::_S_get_pool()._M_get_options();
 
  682       _M_set_options(__pool_base::_Tune __t)
 
  683       { __policy_type::_S_get_pool()._M_set_options(__t); }
 
  686   template<
typename _Tp, 
typename _Poolp>
 
  687     typename __mt_alloc<_Tp, _Poolp>::pointer
 
  689     allocate(size_type __n, 
const void*)
 
  691       if (__n > this->max_size())
 
  692     std::__throw_bad_alloc();
 
  694       __policy_type::_S_initialize_once();
 
  698       __pool_type& 
__pool = __policy_type::_S_get_pool();
 
  699       const size_t __bytes = __n * 
sizeof(_Tp);
 
  700       if (__pool._M_check_threshold(__bytes))
 
  702       void* __ret = ::operator 
new(__bytes);
 
  703       return static_cast<_Tp*
>(__ret);
 
  707       const size_t __which = __pool._M_get_binmap(__bytes);
 
  708       const size_t __thread_id = __pool._M_get_thread_id();
 
  713       typedef typename __pool_type::_Bin_record _Bin_record;
 
  714       const _Bin_record& __bin = __pool._M_get_bin(__which);
 
  715       if (__bin._M_first[__thread_id])
 
  718       typedef typename __pool_type::_Block_record _Block_record;
 
  719       _Block_record* __block = __bin._M_first[__thread_id];
 
  720       __bin._M_first[__thread_id] = __block->_M_next;
 
  722       __pool._M_adjust_freelist(__bin, __block, __thread_id);
 
  723       __c = 
reinterpret_cast<char*
>(__block) + __pool._M_get_align();
 
  728       __c = __pool._M_reserve_block(__bytes, __thread_id);
 
  730       return static_cast<_Tp*
>(
static_cast<void*
>(__c));
 
  733   template<
typename _Tp, 
typename _Poolp>
 
  735     __mt_alloc<_Tp, _Poolp>::
 
  736     deallocate(pointer __p, size_type __n)
 
  738       if (__builtin_expect(__p != 0, 
true))
 
  742       __pool_type& __pool = __policy_type::_S_get_pool();
 
  743       const size_t __bytes = __n * 
sizeof(_Tp);
 
  744       if (__pool._M_check_threshold(__bytes))
 
  745         ::
operator delete(__p);
 
  747         __pool._M_reclaim_block(reinterpret_cast<char*>(__p), __bytes);
 
  751   template<
typename _Tp, 
typename _Poolp>
 
  753     operator==(
const __mt_alloc<_Tp, _Poolp>&, 
const __mt_alloc<_Tp, _Poolp>&)
 
  756   template<
typename _Tp, 
typename _Poolp>
 
  758     operator!=(
const __mt_alloc<_Tp, _Poolp>&, 
const __mt_alloc<_Tp, _Poolp>&)
 
  761 #undef __thread_default 
  763 _GLIBCXX_END_NAMESPACE_VERSION
 
This is a fixed size (power of 2) allocator which - when compiled with thread support - will maintain...
 
Base class for pool object. 
 
Policy for shared __pool objects. 
 
Policy for individual __pool objects. 
 
Data describing the underlying memory pool, parameterized on threading support. 
 
Base class for _Tp dependent member functions. 
 
_Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.