aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/ext/mt_allocator.h
diff options
context:
space:
mode:
authorBenjamin Kosnik <bkoz@redhat.com>2004-10-28 20:46:08 +0000
committerBenjamin Kosnik <bkoz@gcc.gnu.org>2004-10-28 20:46:08 +0000
commit6571df13b4c1b52d50a7e297db59ec698c2220ee (patch)
tree42e84384ba20cde73791c69c66e64d90df17bc78 /libstdc++-v3/include/ext/mt_allocator.h
parenta827e21a71040a2b8b4101e0c0c68396f360203c (diff)
downloadgcc-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.h362
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