mt_allocator.h

来自「Mac OS X 10.4.9 for x86 Source Code gcc」· C头文件 代码 · 共 764 行 · 第 1/2 页

H
764
字号
    private:      // An "array" of bin_records each of which represents a specific      // power of 2 size. Memory to this "array" is allocated in      // _M_initialize().      _Bin_record* volatile	_M_bin;      // Actual value calculated in _M_initialize().      size_t 	       	     	_M_bin_size;      __gthread_once_t 		_M_once;            _Thread_record* 		_M_thread_freelist;      void*			_M_thread_freelist_initial;    };#endif  /// @brief  Policy for shared __pool objects.  template<template <bool> class _PoolTp, bool _Thread>    struct __common_pool_policy;  /// Partial specialization for single thread.  template<template <bool> class _PoolTp>    struct __common_pool_policy<_PoolTp, false>    {      typedef _PoolTp<false> pool_type;            template<typename _Tp1, template <bool> class _PoolTp1 = _PoolTp, 	       bool _Thread1 = false>        struct _M_rebind        { typedef __common_pool_policy<_PoolTp1, _Thread1> other; };      static pool_type&      _S_get_pool()      { 	static pool_type _S_pool;	return _S_pool;      }      static void      _S_initialize_once()       { 	static bool __init;	if (__builtin_expect(__init == false, false))	  {	    _S_get_pool()._M_initialize_once(); 	    __init = true;	  }      }    };#ifdef __GTHREADS  /// Partial specialization for thread enabled, via gthreads.h.  template<template <bool> class _PoolTp>    struct __common_pool_policy<_PoolTp, true>    {      typedef _PoolTp<true> pool_type;            template<typename _Tp1, template <bool> class _PoolTp1 = _PoolTp, 	       bool _Thread1 = true>        struct _M_rebind        { typedef __common_pool_policy<_PoolTp1, _Thread1> other; };      static pool_type&      _S_get_pool()      { 	static pool_type _S_pool;	return _S_pool;      }      static void      _S_initialize_once()       { 	static bool __init;	if (__builtin_expect(__init == false, false))	  {	    _S_get_pool()._M_initialize_once(_S_initialize); 	    __init = true;	  }      }    private:      static void      _S_destroy_thread_key(void* __freelist_pos)      { _S_get_pool()._M_destroy_thread_key(__freelist_pos); }            static void      _S_initialize()       { _S_get_pool()._M_initialize(_S_destroy_thread_key); }   };#endif   /// @brief  Policy for individual __pool objects.  template<typename _Tp, template <bool> class _PoolTp, bool _Thread>    struct __per_type_pool_policy;  /// Partial specialization for single thread.  template<typename _Tp, template <bool> class _PoolTp>    struct __per_type_pool_policy<_Tp, _PoolTp, false>    {      typedef _Tp value_type;      typedef _PoolTp<false> pool_type;      template<typename _Tp1, template <bool> class _PoolTp1 = _PoolTp, 	       bool _Thread1 = false>        struct _M_rebind        { typedef __per_type_pool_policy<_Tp1, _PoolTp1, _Thread1> other; };      static pool_type&      _S_get_pool()      { 	// Sane defaults for the _PoolTp.	typedef typename pool_type::_Block_record _Block_record;	const static size_t __align = (__alignof__(_Tp) >= sizeof(_Block_record)				       ? __alignof__(_Tp)				       : sizeof(_Block_record));	typedef typename __pool_base::_Tune _Tune;	static _Tune _S_tune(__align, sizeof(_Tp) * 64,			     sizeof(_Tp) * 2 >= __align ? sizeof(_Tp) * 2			                                : __align,			     sizeof(_Tp) * size_t(_Tune::_S_chunk_size),			     _Tune::_S_max_threads,			     _Tune::_S_freelist_headroom,			     getenv("GLIBCXX_FORCE_NEW") ? true : false);	static pool_type _S_pool(_S_tune);	return _S_pool;      }      static void      _S_initialize_once()      { 	static bool __init;	if (__builtin_expect(__init == false, false))	  {	    _S_get_pool()._M_initialize_once(); 	    __init = true;	  }      }    };#ifdef __GTHREADS  /// Partial specialization for thread enabled, via gthreads.h.  template<typename _Tp, template <bool> class _PoolTp>    struct __per_type_pool_policy<_Tp, _PoolTp, true>    {      typedef _Tp value_type;      typedef _PoolTp<true> pool_type;     template<typename _Tp1, template <bool> class _PoolTp1 = _PoolTp, 	       bool _Thread1 = true>        struct _M_rebind        { typedef __per_type_pool_policy<_Tp1, _PoolTp1, _Thread1> other; };      static pool_type&      _S_get_pool()      { 	// Sane defaults for the _PoolTp.	typedef typename pool_type::_Block_record _Block_record;	const static size_t __align = (__alignof__(_Tp) >= sizeof(_Block_record)				       ? __alignof__(_Tp)				       : sizeof(_Block_record));	typedef typename __pool_base::_Tune _Tune;	static _Tune _S_tune(__align, sizeof(_Tp) * 64,			     sizeof(_Tp) * 2 >= __align ? sizeof(_Tp) * 2                                                        : __align,			     sizeof(_Tp) * size_t(_Tune::_S_chunk_size),			     _Tune::_S_max_threads,			     _Tune::_S_freelist_headroom,			     getenv("GLIBCXX_FORCE_NEW") ? true : false);	static pool_type _S_pool(_S_tune);	return _S_pool;      }      static void      _S_initialize_once()      { 	static bool __init;	if (__builtin_expect(__init == false, false))	  {	    _S_get_pool()._M_initialize_once(_S_initialize); 	    __init = true;	  }      }    private:      static void      _S_destroy_thread_key(void* __freelist_pos)      { _S_get_pool()._M_destroy_thread_key(__freelist_pos); }            static void      _S_initialize()       { _S_get_pool()._M_initialize(_S_destroy_thread_key); }    };#endif  /// @brief  Base class for _Tp dependent member functions.  template<typename _Tp>    class __mt_alloc_base     {    public:      typedef size_t                    size_type;      typedef ptrdiff_t                 difference_type;      typedef _Tp*                      pointer;      typedef const _Tp*                const_pointer;      typedef _Tp&                      reference;      typedef const _Tp&                const_reference;      typedef _Tp                       value_type;      pointer      address(reference __x) const      { return &__x; }      const_pointer      address(const_reference __x) const      { return &__x; }      size_type      max_size() const throw()       { return size_t(-1) / sizeof(_Tp); }      // _GLIBCXX_RESOLVE_LIB_DEFECTS      // 402. wrong new expression in [some_] allocator::construct      void       construct(pointer __p, const _Tp& __val)       { ::new(__p) _Tp(__val); }      void       destroy(pointer __p) { __p->~_Tp(); }    };#ifdef __GTHREADS#define __thread_default true#else#define __thread_default false#endif  /**   *  @brief  This is a fixed size (power of 2) allocator which - when   *  compiled with thread support - will maintain one freelist per   *  size per thread plus a "global" one. Steps are taken to limit   *  the per thread freelist sizes (by returning excess back to   *  the "global" list).   *   *  Further details:   *  http://gcc.gnu.org/onlinedocs/libstdc++/ext/mt_allocator.html   */  template<typename _Tp, 	   typename _Poolp = __common_pool_policy<__pool, __thread_default> >    class __mt_alloc : public __mt_alloc_base<_Tp>    {    public:      typedef size_t                    	size_type;      typedef ptrdiff_t                 	difference_type;      typedef _Tp*                      	pointer;      typedef const _Tp*                	const_pointer;      typedef _Tp&                      	reference;      typedef const _Tp&                	const_reference;      typedef _Tp                       	value_type;      typedef _Poolp      			__policy_type;      typedef typename _Poolp::pool_type	__pool_type;      template<typename _Tp1, typename _Poolp1 = _Poolp>        struct rebind        { 	  typedef typename _Poolp1::template _M_rebind<_Tp1>::other pol_type;	  typedef __mt_alloc<_Tp1, pol_type> other;	};      __mt_alloc() throw()       { __policy_type::_S_get_pool(); }      __mt_alloc(const __mt_alloc&) throw()       { __policy_type::_S_get_pool(); }      template<typename _Tp1, typename _Poolp1>        __mt_alloc(const __mt_alloc<_Tp1, _Poolp1>& obj) throw()          { __policy_type::_S_get_pool(); }      ~__mt_alloc() throw() { }      pointer      allocate(size_type __n, const void* = 0);      void      deallocate(pointer __p, size_type __n);      const __pool_base::_Tune      _M_get_options()      { 	// Return a copy, not a reference, for external consumption.	return __policy_type::_S_get_pool()._M_get_options();      }            void      _M_set_options(__pool_base::_Tune __t)      { __policy_type::_S_get_pool()._M_set_options(__t); }    };  template<typename _Tp, typename _Poolp>    typename __mt_alloc<_Tp, _Poolp>::pointer    __mt_alloc<_Tp, _Poolp>::    allocate(size_type __n, const void*)    {      if (__builtin_expect(__n > this->max_size(), false))	std::__throw_bad_alloc();      __policy_type::_S_initialize_once();      // Requests larger than _M_max_bytes are handled by operator      // new/delete directly.      __pool_type& __pool = __policy_type::_S_get_pool();      const size_t __bytes = __n * sizeof(_Tp);      if (__pool._M_check_threshold(__bytes))	{	  void* __ret = ::operator new(__bytes);	  return static_cast<_Tp*>(__ret);	}            // Round up to power of 2 and figure out which bin to use.      const size_t __which = __pool._M_get_binmap(__bytes);      const size_t __thread_id = __pool._M_get_thread_id();            // Find out if we have blocks on our freelist.  If so, go ahead      // and use them directly without having to lock anything.      char* __c;      typedef typename __pool_type::_Bin_record _Bin_record;      const _Bin_record& __bin = __pool._M_get_bin(__which);      if (__bin._M_first[__thread_id])	{	  // Already reserved.	  typedef typename __pool_type::_Block_record _Block_record;	  _Block_record* __block = __bin._M_first[__thread_id];	  __bin._M_first[__thread_id] = __block->_M_next;	  	  __pool._M_adjust_freelist(__bin, __block, __thread_id);	  __c = reinterpret_cast<char*>(__block) + __pool._M_get_align();	}      else	{	  // Null, reserve.	  __c = __pool._M_reserve_block(__bytes, __thread_id);	}      return static_cast<_Tp*>(static_cast<void*>(__c));    }    template<typename _Tp, typename _Poolp>    void    __mt_alloc<_Tp, _Poolp>::    deallocate(pointer __p, size_type __n)    {      if (__builtin_expect(__p != 0, true))	{	  // Requests larger than _M_max_bytes are handled by	  // operators new/delete directly.	  __pool_type& __pool = __policy_type::_S_get_pool();	  const size_t __bytes = __n * sizeof(_Tp);	  if (__pool._M_check_threshold(__bytes))	    ::operator delete(__p);	  else	    __pool._M_reclaim_block(reinterpret_cast<char*>(__p), __bytes);	}    }    template<typename _Tp, typename _Poolp>    inline bool    operator==(const __mt_alloc<_Tp, _Poolp>&, const __mt_alloc<_Tp, _Poolp>&)    { return true; }    template<typename _Tp, typename _Poolp>    inline bool    operator!=(const __mt_alloc<_Tp, _Poolp>&, const __mt_alloc<_Tp, _Poolp>&)    { return false; }#undef __thread_default} // namespace __gnu_cxx#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?