aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/ext/mt_allocator.h
diff options
context:
space:
mode:
authorBenjamin Kosnik <bkoz@gcc.gnu.org>2005-09-12 04:49:11 +0000
committerBenjamin Kosnik <bkoz@gcc.gnu.org>2005-09-12 04:49:11 +0000
commit2f9f6cef1cdc149a05754839ca27af001c8d3d1e (patch)
tree8b5f928c92d3aae14b4285ea94519fe9d16b10f5 /libstdc++-v3/include/ext/mt_allocator.h
parent56b4ea3de8efa797ff0edf9504704803d2ae4981 (diff)
downloadgcc-2f9f6cef1cdc149a05754839ca27af001c8d3d1e.zip
gcc-2f9f6cef1cdc149a05754839ca27af001c8d3d1e.tar.gz
gcc-2f9f6cef1cdc149a05754839ca27af001c8d3d1e.tar.bz2
[multiple changes]
2005-09-11 Benjamin Kosnik <bkoz@redhat.com> PR libstdc++/19265 PR libstdc++/22309 * include/ext/mt_allocator.h (__gnu_cxx::__create_handler): Remove. (__pool<true>::_M_destroy_thread_key): Compatibility only. (__pool<true>::_M_initialize(__destroy): Same. (__pool<true>::_M_initialize): New. (__pool<true>::_M_initialize_once): Nothing fancy. (__pool<true>::_M_once): Remove. (__common_pool): New. (__common_pool_base): New. (__per_type_pool): New. (__per_type_pool_base): New. * src/mt_allocator.cc: Same. * config/linker-map.gnu (__pool<true>::_M_initialize()): Add. 2005-09-11 Jakub Jelinek <jakub@redhat.com> PR libstdc++/19265 PR libstdc++/22309 * src/mt_allocator.cc (__gnu_internal::freelist_mutex): Make static. (__gnu_internal::__freelist): New type. (__gnu_internal::freelist): New variable. (__gnu_internal::_M_destroy_thread_key): New function. (__gnu_cxx::__pool<true>::_M_destroy): Don't delete _M_thread_freelist_initial. (__gnu_cxx::__pool<true>::_M_initialize): Make argument nameless. Don't use _M_thread_freelist and _M_thread_freelist_initial __pool<true> fields, instead use __gnu_internal::freelist fields, call gthread_key_create just once. Use __gnu_internal::_M_destroy_thread_key as key destructor. (__gnu_cxx::__pool<true>::_M_get_thread_id): Store size_t id rather than _Thread_record* in the thread specific value. Don't use _M_thread_freelist __pool<true> field, instead use __gnu_internal::freelist fields. (__gnu_cxx::__pool<true>::_M_destroy_thread_key): Do nothing. 2005-09-11 Benjamin Kosnik <bkoz@redhat.com> Jakub Jelinek <jakub@redhat.com> PR libstdc++/19265 PR libstdc++/22309 * testsuite/testsuite_shared.cc: New. * testsuite/lib/dg-options.exp (dg-require-sharedlib): New. * testsuite/lib/libstdc++.exp (libstdc++_init): Look for shared library, and set v3-sharedlib based on this. (check_v3_target_sharedlib): New. (proc v3-build_support): Build shared objects. * testsuite/ext/mt_allocator/22309_thread.cc: New, use above. From-SVN: r104161
Diffstat (limited to 'libstdc++-v3/include/ext/mt_allocator.h')
-rw-r--r--libstdc++-v3/include/ext/mt_allocator.h238
1 files changed, 103 insertions, 135 deletions
diff --git a/libstdc++-v3/include/ext/mt_allocator.h b/libstdc++-v3/include/ext/mt_allocator.h
index b2cf89b..311e219 100644
--- a/libstdc++-v3/include/ext/mt_allocator.h
+++ b/libstdc++-v3/include/ext/mt_allocator.h
@@ -43,7 +43,6 @@
namespace __gnu_cxx
{
typedef void (*__destroy_handler)(void*);
- typedef void (*__create_handler)(void);
/// @brief Base class for pool object.
struct __pool_base
@@ -185,12 +184,6 @@ namespace __gnu_cxx
template<bool _Thread>
class __pool;
- template<>
- class __pool<true>;
-
- template<>
- class __pool<false>;
-
/// Specialization for single thread.
template<>
class __pool<false> : public __pool_base
@@ -313,24 +306,15 @@ namespace __gnu_cxx
__gthread_mutex_t* _M_mutex;
};
+ // XXX GLIBCXX_ABI Deprecated
void
- _M_initialize(__destroy_handler __d);
+ _M_initialize(__destroy_handler);
void
- _M_initialize_once(__create_handler __c)
+ _M_initialize_once()
{
- // Although the test in __gthread_once() would suffice, we
- // wrap test of the once condition in our own unlocked
- // check. This saves one function call to pthread_once()
- // (which itself only tests for the once value unlocked anyway
- // and immediately returns if set)
if (__builtin_expect(_M_init == false, false))
- {
- if (__gthread_active_p())
- __gthread_once(&_M_once, __c);
- if (!_M_init)
- __c();
- }
+ _M_initialize();
}
void
@@ -358,28 +342,21 @@ namespace __gnu_cxx
}
}
+ // XXX GLIBCXX_ABI Deprecated
void
- _M_destroy_thread_key(void* __freelist_pos);
+ _M_destroy_thread_key(void*);
size_t
_M_get_thread_id();
explicit __pool()
: _M_bin(NULL), _M_bin_size(1), _M_thread_freelist(NULL)
- {
- // On some platforms, __gthread_once_t is an aggregate.
- __gthread_once_t __tmp = __GTHREAD_ONCE_INIT;
- _M_once = __tmp;
- }
+ { }
explicit __pool(const __pool_base::_Tune& __tune)
: __pool_base(__tune), _M_bin(NULL), _M_bin_size(1),
_M_thread_freelist(NULL)
- {
- // On some platforms, __gthread_once_t is an aggregate.
- __gthread_once_t __tmp = __GTHREAD_ONCE_INIT;
- _M_once = __tmp;
- }
+ { }
private:
// An "array" of bin_records each of which represents a specific
@@ -390,39 +367,39 @@ namespace __gnu_cxx
// 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;
+
+ void
+ _M_initialize();
};
#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>
+ struct __common_pool
{
- typedef _PoolTp<false> pool_type;
+ typedef _PoolTp<_Thread> 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;
}
+ };
+
+ template<template <bool> class _PoolTp, bool _Thread>
+ struct __common_pool_base;
+
+ template<template <bool> class _PoolTp>
+ struct __common_pool_base<_PoolTp, false>
+ : public __common_pool<_PoolTp, false>
+ {
+ using __common_pool<_PoolTp, false>::_S_get_pool;
static void
- _S_initialize_once()
- {
+ _S_initialize_once()
+ {
static bool __init;
if (__builtin_expect(__init == false, false))
{
@@ -433,76 +410,67 @@ namespace __gnu_cxx
};
#ifdef __GTHREADS
- /// Partial specialization for thread enabled, via gthreads.h.
template<template <bool> class _PoolTp>
- struct __common_pool_policy<_PoolTp, true>
+ struct __common_pool_base<_PoolTp, true>
+ : public __common_pool<_PoolTp, true>
{
- typedef _PoolTp<true> pool_type;
+ using __common_pool<_PoolTp, true>::_S_get_pool;
- 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()
+ { _S_get_pool()._M_initialize_once(); }
static void
- _S_initialize_once()
+ _S_initialize_once()
{
static bool __init;
if (__builtin_expect(__init == false, false))
{
- _S_get_pool()._M_initialize_once(_S_initialize);
+ if (__gthread_active_p())
+ {
+ // On some platforms, __gthread_once_t is an aggregate.
+ static __gthread_once_t __once = __GTHREAD_ONCE_INIT;
+ __gthread_once(&__once, _S_initialize);
+ }
+ else
+ _S_get_pool()._M_initialize_once();
__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>
+ /// @brief Policy for shared __pool objects.
+ template<template <bool> class _PoolTp, bool _Thread>
+ struct __common_pool_policy : public __common_pool_base<_PoolTp, _Thread>
{
- typedef _Tp value_type;
- typedef _PoolTp<false> pool_type;
-
template<typename _Tp1, template <bool> class _PoolTp1 = _PoolTp,
- bool _Thread1 = false>
+ bool _Thread1 = _Thread>
struct _M_rebind
- { typedef __per_type_pool_policy<_Tp1, _PoolTp1, _Thread1> other; };
+ { typedef __common_pool_policy<_PoolTp1, _Thread1> other; };
+ using __common_pool_base<_PoolTp, _Thread>::_S_get_pool;
+ using __common_pool_base<_PoolTp, _Thread>::_S_initialize_once;
+ };
+
+
+ template<typename _Tp, template <bool> class _PoolTp, bool _Thread>
+ struct __per_type_pool
+ {
+ typedef _Tp value_type;
+ typedef _PoolTp<_Thread> pool_type;
+
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));
+ const static size_t __a = (__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,
+ static _Tune _S_tune(__a, sizeof(_Tp) * 64,
+ sizeof(_Tp) * 2 >= __a ? sizeof(_Tp) * 2 : __a,
sizeof(_Tp) * size_t(_Tune::_S_chunk_size),
_Tune::_S_max_threads,
_Tune::_S_freelist_headroom,
@@ -510,10 +478,20 @@ namespace __gnu_cxx
static pool_type _S_pool(_S_tune);
return _S_pool;
}
+ };
+
+ template<typename _Tp, template <bool> class _PoolTp, bool _Thread>
+ struct __per_type_pool_base;
+
+ template<typename _Tp, template <bool> class _PoolTp>
+ struct __per_type_pool_base<_Tp, _PoolTp, false>
+ : public __per_type_pool<_Tp, _PoolTp, false>
+ {
+ using __per_type_pool<_Tp, _PoolTp, false>::_S_get_pool;
static void
_S_initialize_once()
- {
+ {
static bool __init;
if (__builtin_expect(__init == false, false))
{
@@ -523,39 +501,16 @@ namespace __gnu_cxx
}
};
-#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>
+ #ifdef __GTHREADS
+ template<typename _Tp, template <bool> class _PoolTp>
+ struct __per_type_pool_base<_Tp, _PoolTp, true>
+ : public __per_type_pool<_Tp, _PoolTp, true>
{
- typedef _Tp value_type;
- typedef _PoolTp<true> pool_type;
+ using __per_type_pool<_Tp, _PoolTp, true>::_S_get_pool;
- 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()
+ { _S_get_pool()._M_initialize_once(); }
static void
_S_initialize_once()
@@ -563,22 +518,35 @@ namespace __gnu_cxx
static bool __init;
if (__builtin_expect(__init == false, false))
{
- _S_get_pool()._M_initialize_once(_S_initialize);
+ if (__gthread_active_p())
+ {
+ // On some platforms, __gthread_once_t is an aggregate.
+ static __gthread_once_t __once = __GTHREAD_ONCE_INIT;
+ __gthread_once(&__once, _S_initialize);
+ }
+ else
+ _S_get_pool()._M_initialize_once();
__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
+ : public __per_type_pool_base<_Tp, _PoolTp, _Thread>
+ {
+ template<typename _Tp1, template <bool> class _PoolTp1 = _PoolTp,
+ bool _Thread1 = _Thread>
+ struct _M_rebind
+ { typedef __per_type_pool_policy<_Tp1, _PoolTp1, _Thread1> other; };
+
+ using __per_type_pool_base<_Tp, _PoolTp, _Thread>::_S_get_pool;
+ using __per_type_pool_base<_Tp, _PoolTp, _Thread>::_S_initialize_once;
+ };
+
+
/// @brief Base class for _Tp dependent member functions.
template<typename _Tp>
class __mt_alloc_base