diff options
author | Benjamin Kosnik <bkoz@redhat.com> | 2004-10-28 20:46:08 +0000 |
---|---|---|
committer | Benjamin Kosnik <bkoz@gcc.gnu.org> | 2004-10-28 20:46:08 +0000 |
commit | 6571df13b4c1b52d50a7e297db59ec698c2220ee (patch) | |
tree | 42e84384ba20cde73791c69c66e64d90df17bc78 /libstdc++-v3/include/ext/mt_allocator.h | |
parent | a827e21a71040a2b8b4101e0c0c68396f360203c (diff) | |
download | gcc-6571df13b4c1b52d50a7e297db59ec698c2220ee.zip gcc-6571df13b4c1b52d50a7e297db59ec698c2220ee.tar.gz gcc-6571df13b4c1b52d50a7e297db59ec698c2220ee.tar.bz2 |
mt_allocator.h (__common_pool_policy): Add template template parameter for pool class type.
2004-10-28 Benjamin Kosnik <bkoz@redhat.com>
* include/ext/mt_allocator.h (__common_pool_policy): Add template
template parameter for pool class type.
(__per_type_pool_policy): Same.
(__mt_allocator): Don't inherit policy. Qualify policy_type calls.
* testsuite/ext/mt_allocator/check_deallocate_null.cc: Fix.
* testsuite/ext/mt_allocator/check_deallocate_null_thread.cc: Same.
* testsuite/ext/mt_allocator/deallocate_global-2.cc: Same.
* testsuite/ext/mt_allocator/deallocate_global-4.cc: Same.
* testsuite/ext/mt_allocator/deallocate_global_thread-1.cc: Same.
* testsuite/ext/mt_allocator/deallocate_global_thread-3.cc: Same.
* testsuite/ext/mt_allocator/deallocate_local-2.cc: Same.
* testsuite/ext/mt_allocator/deallocate_local-4.cc: Same.
* testsuite/ext/mt_allocator/deallocate_local_thread-1.cc: Same.
* testsuite/ext/mt_allocator/deallocate_local_thread-3.cc: Same.
* testsuite/ext/mt_allocator/instantiate.cc: Same.
* testsuite/ext/mt_allocator/tune-1.cc: Same.
* testsuite/ext/mt_allocator/tune-2.cc: Same.
* testsuite/ext/mt_allocator/tune-3.cc: Same.
* testsuite/ext/mt_allocator/tune-4.cc: Same.
From-SVN: r89776
Diffstat (limited to 'libstdc++-v3/include/ext/mt_allocator.h')
-rw-r--r-- | libstdc++-v3/include/ext/mt_allocator.h | 362 |
1 files changed, 167 insertions, 195 deletions
diff --git a/libstdc++-v3/include/ext/mt_allocator.h b/libstdc++-v3/include/ext/mt_allocator.h index 6649111..e5dab29 100644 --- a/libstdc++-v3/include/ext/mt_allocator.h +++ b/libstdc++-v3/include/ext/mt_allocator.h @@ -65,7 +65,7 @@ namespace __gnu_cxx // Variables used to configure the behavior of the allocator, // assigned and explained in detail below. struct _Tune - { + { // Compile time constants for the default _Tune values. enum { _S_align = 8 }; enum { _S_max_bytes = 128 }; @@ -129,19 +129,6 @@ namespace __gnu_cxx _M_chunk_size(__chunk), _M_max_threads(__maxthreads), _M_freelist_headroom(__headroom), _M_force_new(__force) { } - - bool - is_default() const - { - bool __ret = true; - __ret &= _M_align == _S_align; - __ret &= _M_max_bytes == _S_max_bytes; - __ret &= _M_min_bin == _S_min_bin; - __ret &= _M_chunk_size == _S_chunk_size; - __ret &= _M_max_threads == _S_max_threads; - __ret &= _M_freelist_headroom == _S_freelist_headroom; - return __ret; - } }; struct _Block_address @@ -173,11 +160,20 @@ namespace __gnu_cxx _M_get_align() { return _M_options._M_align; } - explicit __pool_base() + explicit + __pool_base() : _M_options(_Tune()), _M_binmap(NULL), _M_init(false) { } - explicit __pool_base(const _Tune& __tune) - : _M_options(__tune), _M_binmap(NULL), _M_init(false) { } + explicit + __pool_base(const _Tune& __options) + : _M_options(__options), _M_binmap(NULL), _M_init(false) { } + + private: + explicit + __pool_base(const __pool_base&); + + __pool_base& + operator=(const __pool_base&); protected: // Configuration options. @@ -185,8 +181,9 @@ namespace __gnu_cxx _Binmap_type* _M_binmap; - // We need to create the initial lists and set up some variables - // before we can answer to the first request for memory. + // Configuration of the pool object via _M_options can happen + // after construction but before initialization. After + // initialization is complete, this variable is set to true. bool _M_init; }; @@ -201,9 +198,74 @@ namespace __gnu_cxx template<> class __pool<false>; + // Specialization for single thread. + template<> + class __pool<false> : public __pool_base + { + public: + union _Block_record + { + // Points to the block_record of the next free block. + _Block_record* volatile _M_next; + }; + + struct _Bin_record + { + // An "array" of pointers to the first free block. + _Block_record** volatile _M_first; + // A list of the initial addresses of all allocated blocks. + _Block_address* _M_address; + }; + + void + _M_initialize_once() + { + if (__builtin_expect(_M_init == false, false)) + _M_initialize(); + } + + void + _M_destroy() throw(); + + char* + _M_reserve_block(size_t __bytes, const size_t __thread_id); + + void + _M_reclaim_block(char* __p, size_t __bytes); + + size_t + _M_get_thread_id() { return 0; } + + const _Bin_record& + _M_get_bin(size_t __which) + { return _M_bin[__which]; } + + void + _M_adjust_freelist(const _Bin_record&, _Block_record*, size_t) + { } + + explicit __pool() + : _M_bin(NULL), _M_bin_size(1) { } + + explicit __pool(const __pool_base::_Tune& __tune) + : __pool_base(__tune), _M_bin(NULL), _M_bin_size(1) { } + + 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; + + void + _M_initialize(); + }; + #ifdef __GTHREADS - // Specialization for thread enabled, via gthreads.h. + // Specialization for thread enabled, via gthreads.h. template<> class __pool<true> : public __pool_base { @@ -326,8 +388,6 @@ namespace __gnu_cxx _M_once = __tmp; } - ~__pool() { } - private: // An "array" of bin_records each of which represents a specific // power of 2 size. Memory to this "array" is allocated in @@ -344,94 +404,24 @@ namespace __gnu_cxx }; #endif - // Specialization for single thread. - template<> - class __pool<false> : public __pool_base - { - public: - union _Block_record - { - // Points to the block_record of the next free block. - _Block_record* volatile _M_next; - }; - - struct _Bin_record - { - // An "array" of pointers to the first free block. - _Block_record** volatile _M_first; - // A list of the initial addresses of all allocated blocks. - _Block_address* _M_address; - }; - - void - _M_initialize_once() - { - if (__builtin_expect(_M_init == false, false)) - _M_initialize(); - } + template<template <bool> class _PoolTp, bool _Thread> + struct __common_pool_policy; - void - _M_destroy() throw(); - - char* - _M_reserve_block(size_t __bytes, const size_t __thread_id); - - void - _M_reclaim_block(char* __p, size_t __bytes); - - size_t - _M_get_thread_id() { return 0; } - - const _Bin_record& - _M_get_bin(size_t __which) - { return _M_bin[__which]; } - - void - _M_adjust_freelist(const _Bin_record&, _Block_record*, size_t) - { } - - explicit __pool() - : _M_bin(NULL), _M_bin_size(1) { } - - explicit __pool(const __pool_base::_Tune& __tune) - : __pool_base(__tune), _M_bin(NULL), _M_bin_size(1) { } - - ~__pool() { } - - 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; - - void - _M_initialize(); - }; - - template<bool _Thread> - struct __common_pool_policy + template<template <bool> class _PoolTp> + struct __common_pool_policy<_PoolTp, false> { - typedef __pool<_Thread> __pool_type; - - template<typename _Tp1, bool _Thread1 = _Thread> - struct _M_rebind; - - template<typename _Tp1> - struct _M_rebind<_Tp1, true> - { typedef __common_pool_policy<true> other; }; - - template<typename _Tp1> - struct _M_rebind<_Tp1, false> - { typedef __common_pool_policy<false> other; }; + 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& + static pool_type& _S_get_pool() { - static __pool_type _S_pool; + static pool_type _S_pool; return _S_pool; } @@ -447,42 +437,25 @@ namespace __gnu_cxx } }; - template<> - struct __common_pool_policy<true>; - #ifdef __GTHREADS - template<> - struct __common_pool_policy<true> + template<template <bool> class _PoolTp> + struct __common_pool_policy<_PoolTp, true> { - typedef __pool<true> __pool_type; - - template<typename _Tp1, bool _Thread1 = true> - struct _M_rebind; - - template<typename _Tp1> - struct _M_rebind<_Tp1, true> - { typedef __common_pool_policy<true> other; }; - - template<typename _Tp1> - struct _M_rebind<_Tp1, false> - { typedef __common_pool_policy<false> other; }; + 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& + static pool_type& _S_get_pool() { - static __pool_type _S_pool; + static pool_type _S_pool; return _S_pool; } 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); } - - static void _S_initialize_once() { static bool __init; @@ -492,34 +465,40 @@ namespace __gnu_cxx __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 + + template<typename _Tp, template <bool> class _PoolTp, bool _Thread> + struct __per_type_pool_policy; - template<typename _Tp, bool _Thread> - struct __per_type_pool_policy + template<typename _Tp, template <bool> class _PoolTp> + struct __per_type_pool_policy<_Tp, _PoolTp, false> { - typedef __pool<_Thread> __pool_type; - - template<typename _Tp1, bool _Thread1 = _Thread> - struct _M_rebind; + typedef _Tp value_type; + typedef _PoolTp<false> pool_type; - template<typename _Tp1> - struct _M_rebind<_Tp1, false> - { typedef __per_type_pool_policy<_Tp1, false> other; }; + template<typename _Tp1, template <bool> class _PoolTp1 = _PoolTp, + bool _Thread1 = false> + struct _M_rebind + { typedef __per_type_pool_policy<_Tp1, _PoolTp1, _Thread1> other; }; - template<typename _Tp1> - struct _M_rebind<_Tp1, true> - { typedef __per_type_pool_policy<_Tp1, true> other; }; - - // Avoid static initialization ordering issues. - static __pool_type& - _S_get_pool() + static pool_type& + _S_get_pool() { - // Sane defaults for the __pool_type. - const static size_t __align = __alignof__(_Tp) >= sizeof(typename __pool_type::_Block_record) ? __alignof__(_Tp) : sizeof(typename __pool_type::_Block_record); - static __pool_base::_Tune _S_tune(__align, sizeof(_Tp) * 128, (sizeof(_Tp) * 2) >= __align ? sizeof(_Tp) * 2 : __align, __pool_type::_Tune::_S_chunk_size, __pool_type::_Tune::_S_max_threads, __pool_type::_Tune::_S_freelist_headroom, getenv("GLIBCXX_FORCE_NEW") ? true : false); - static __pool_type _S_pool(_S_tune); + // Sane defaults for the _PoolTp. + const static size_t __align = __alignof__(_Tp) >= sizeof(typename pool_type::_Block_record) ? __alignof__(_Tp) : sizeof(typename pool_type::_Block_record); + static __pool_base::_Tune _S_tune(__align, sizeof(_Tp) * 128, (sizeof(_Tp) * 2) >= __align ? sizeof(_Tp) * 2 : __align, __pool_base::_Tune::_S_chunk_size, __pool_base::_Tune::_S_max_threads, __pool_base::_Tune::_S_freelist_headroom, getenv("GLIBCXX_FORCE_NEW") ? true : false); + static pool_type _S_pool(_S_tune); return _S_pool; } @@ -535,46 +514,29 @@ namespace __gnu_cxx } }; - template<typename _Tp> - struct __per_type_pool_policy<_Tp, true>; - #ifdef __GTHREADS - template<typename _Tp> - struct __per_type_pool_policy<_Tp, true> + template<typename _Tp, template <bool> class _PoolTp> + struct __per_type_pool_policy<_Tp, _PoolTp, true> { - typedef __pool<true> __pool_type; - - template<typename _Tp1, bool _Thread1 = true> - struct _M_rebind; + typedef _Tp value_type; + typedef _PoolTp<true> pool_type; - template<typename _Tp1> - struct _M_rebind<_Tp1, false> - { typedef __per_type_pool_policy<_Tp1, false> other; }; + template<typename _Tp1, template <bool> class _PoolTp1 = _PoolTp, + bool _Thread1 = true> + struct _M_rebind + { typedef __per_type_pool_policy<_Tp1, _PoolTp1, _Thread1> other; }; - template<typename _Tp1> - struct _M_rebind<_Tp1, true> - { typedef __per_type_pool_policy<_Tp1, true> other; }; - - // Avoid static initialization ordering issues. - static __pool_type& - _S_get_pool( ) + static pool_type& + _S_get_pool() { - // Sane defaults for the __pool_type. - const static size_t __align = __alignof__(_Tp) >= sizeof(typename __pool_type::_Block_record) ? __alignof__(_Tp) : sizeof(typename __pool_type::_Block_record); - static __pool_base::_Tune _S_tune(__align, sizeof(_Tp) * 128, (sizeof(_Tp) * 2) >= __align ? sizeof(_Tp) * 2 : __align, __pool_type::_Tune::_S_chunk_size, __pool_type::_Tune::_S_max_threads, __pool_type::_Tune::_S_freelist_headroom, getenv("GLIBCXX_FORCE_NEW") ? true : false); - static __pool_type _S_pool(_S_tune); + // Sane defaults for the _PoolTp. + const static size_t __align = __alignof__(_Tp) >= sizeof(typename pool_type::_Block_record) ? __alignof__(_Tp) : sizeof(typename pool_type::_Block_record); + static __pool_base::_Tune _S_tune(__align, sizeof(_Tp) * 128, (sizeof(_Tp) * 2) >= __align ? sizeof(_Tp) * 2 : __align, __pool_base::_Tune::_S_chunk_size, __pool_base::_Tune::_S_max_threads, __pool_base::_Tune::_S_freelist_headroom, getenv("GLIBCXX_FORCE_NEW") ? true : false); + static pool_type _S_pool(_S_tune); return _S_pool; } 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); } - - static void _S_initialize_once() { static bool __init; @@ -584,6 +546,15 @@ namespace __gnu_cxx __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 @@ -622,13 +593,14 @@ namespace __gnu_cxx }; #ifdef __GTHREADS -#define __default_policy __common_pool_policy<true> +#define __thread_default true #else -#define __default_policy __common_pool_policy<false> +#define __thread_default false #endif - template<typename _Tp, typename _Poolp = __default_policy> - class __mt_alloc : public __mt_alloc_base<_Tp>, _Poolp + 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; @@ -638,8 +610,8 @@ namespace __gnu_cxx typedef _Tp& reference; typedef const _Tp& const_reference; typedef _Tp value_type; - typedef _Poolp __policy_type; - typedef typename _Poolp::__pool_type __pool_type; + typedef _Poolp __policy_type; + typedef typename _Poolp::pool_type __pool_type; template<typename _Tp1, typename _Poolp1 = _Poolp> struct rebind @@ -670,12 +642,12 @@ namespace __gnu_cxx _M_get_options() { // Return a copy, not a reference, for external consumption. - return __pool_base::_Tune(this->_S_get_pool()._M_get_options()); + return __policy_type::_S_get_pool()._M_get_options(); } void _M_set_options(__pool_base::_Tune __t) - { this->_S_get_pool()._M_set_options(__t); } + { __policy_type::_S_get_pool()._M_set_options(__t); } }; template<typename _Tp, typename _Poolp> @@ -683,14 +655,14 @@ namespace __gnu_cxx __mt_alloc<_Tp, _Poolp>:: allocate(size_type __n, const void*) { - this->_S_initialize_once(); - 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 = this->_S_get_pool(); + __pool_type& __pool = __policy_type::_S_get_pool(); const size_t __bytes = __n * sizeof(_Tp); if (__pool._M_check_threshold(__bytes)) { @@ -734,7 +706,7 @@ namespace __gnu_cxx { // Requests larger than _M_max_bytes are handled by // operators new/delete directly. - __pool_type& __pool = this->_S_get_pool(); + __pool_type& __pool = __policy_type::_S_get_pool(); const size_t __bytes = __n * sizeof(_Tp); if (__pool._M_check_threshold(__bytes)) ::operator delete(__p); @@ -753,7 +725,7 @@ namespace __gnu_cxx operator!=(const __mt_alloc<_Tp, _Poolp>&, const __mt_alloc<_Tp, _Poolp>&) { return false; } -#undef __default_policy +#undef __thread_default } // namespace __gnu_cxx #endif |