re PR libstdc++/17780 (std::allocator vs. static init)
2004-10-05 Benjamin Kosnik <bkoz@redhat.com> PR libstdc++/17780 * include/ext/mt_allocator.h (__pool_base::_Tune): Add default options as compile-time constant enums. (__pool_base::_Tune::is_default): New. (__pool_base::_Block_address): New. (__pool_base): Rearrange data members. (__pool::_M_reserve_memory): To _M_reserve_block. (__pool::_M_reclaim_memory): To _M_reclaim_block. (__pool::_Bin_record): Add _Block_address data member. (__pool<false>): Add _M_thread_freelist_initial. (__pool::~__pool): Declare. (__common_pool_policy): Move static data member to... (__common_pool_policy::_S_get_pool): ...here, make static local. (__per_type_pool_policy): Move static data member to... (__per_type_pool_policy::_S_get_pool): ...here, make static local. (__mt_alloc::__mt_alloc): Call __policy_type::_S_get_pool. Remove static member definitions. Use define for __default_policy. * src/mt_allocator.cc: Same. * config/linker-map.gnu: Don't export _S_get_pool. Renames. * testsuite/ext/new_allocator: New. * testsuite/ext/new_allocator/instantiate.cc: New. * testsuite/ext/new_allocator/check_new.cc: New. * testsuite/ext/new_allocator/deallocate_global.cc: New. * testsuite/ext/new_allocator/deallocate_local.cc: New. * testsuite/ext/mt_allocator/instantiate.cc: Instantiate all template arguments. * testsuite/ext/mt_allocator/deallocate_global-1.cc: New. * testsuite/ext/mt_allocator/deallocate_global-2.cc: New. * testsuite/ext/mt_allocator/deallocate_global-3.cc: New. * testsuite/ext/mt_allocator/deallocate_global-4.cc: New. * testsuite/ext/mt_allocator/deallocate_local-1.cc: New. * testsuite/ext/mt_allocator/deallocate_local-2.cc: New. * testsuite/ext/mt_allocator/deallocate_local-3.cc: New. * testsuite/ext/mt_allocator/deallocate_local-4.cc: New. * testsuite/ext/mt_allocator/deallocate.cc: New. * testsuite/ext/malloc_allocator/deallocate.cc: New. * testsuite/ext/malloc_allocator/deallocate_global.cc: New. * testsuite/ext/malloc_allocator/deallocate_local.cc: New. From-SVN: r88589
This commit is contained in:
parent
743eeb5a81
commit
12cde21b12
19 changed files with 1351 additions and 247 deletions
|
@ -1,3 +1,44 @@
|
|||
2004-10-05 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
PR libstdc++/17780
|
||||
* include/ext/mt_allocator.h (__pool_base::_Tune): Add default
|
||||
options as compile-time constant enums.
|
||||
(__pool_base::_Tune::is_default): New.
|
||||
(__pool_base::_Block_address): New.
|
||||
(__pool_base): Rearrange data members.
|
||||
(__pool::_M_reserve_memory): To _M_reserve_block.
|
||||
(__pool::_M_reclaim_memory): To _M_reclaim_block.
|
||||
(__pool::_Bin_record): Add _Block_address data member.
|
||||
(__pool<false>): Add _M_thread_freelist_initial.
|
||||
(__pool::~__pool): Declare.
|
||||
(__common_pool_policy): Move static data member to...
|
||||
(__common_pool_policy::_S_get_pool): ...here, make static local.
|
||||
(__per_type_pool_policy): Move static data member to...
|
||||
(__per_type_pool_policy::_S_get_pool): ...here, make static local.
|
||||
(__mt_alloc::__mt_alloc): Call __policy_type::_S_get_pool.
|
||||
Remove static member definitions. Use define for __default_policy.
|
||||
* src/mt_allocator.cc: Same.
|
||||
* config/linker-map.gnu: Don't export _S_get_pool. Renames.
|
||||
* testsuite/ext/new_allocator: New.
|
||||
* testsuite/ext/new_allocator/instantiate.cc: New.
|
||||
* testsuite/ext/new_allocator/check_new.cc: New.
|
||||
* testsuite/ext/new_allocator/deallocate_global.cc: New.
|
||||
* testsuite/ext/new_allocator/deallocate_local.cc: New.
|
||||
* testsuite/ext/mt_allocator/instantiate.cc: Instantiate all
|
||||
template arguments.
|
||||
* testsuite/ext/mt_allocator/deallocate_global-1.cc: New.
|
||||
* testsuite/ext/mt_allocator/deallocate_global-2.cc: New.
|
||||
* testsuite/ext/mt_allocator/deallocate_global-3.cc: New.
|
||||
* testsuite/ext/mt_allocator/deallocate_global-4.cc: New.
|
||||
* testsuite/ext/mt_allocator/deallocate_local-1.cc: New.
|
||||
* testsuite/ext/mt_allocator/deallocate_local-2.cc: New.
|
||||
* testsuite/ext/mt_allocator/deallocate_local-3.cc: New.
|
||||
* testsuite/ext/mt_allocator/deallocate_local-4.cc: New.
|
||||
* testsuite/ext/mt_allocator/deallocate.cc: New.
|
||||
* testsuite/ext/malloc_allocator/deallocate.cc: New.
|
||||
* testsuite/ext/malloc_allocator/deallocate_global.cc: New.
|
||||
* testsuite/ext/malloc_allocator/deallocate_local.cc: New.
|
||||
|
||||
2004-10-05 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* configure.host (abi_baseline_pair): Define for s390-*-linux* and
|
||||
|
|
|
@ -267,9 +267,9 @@ GLIBCXX_3.4.3 {
|
|||
_ZN9__gnu_cxx6__poolILb1EE13_M_initializeEPFvPvE;
|
||||
_ZN9__gnu_cxx6__poolILb1EE21_M_destroy_thread_keyEPv;
|
||||
_ZN9__gnu_cxx6__poolILb1EE16_M_get_thread_idEv;
|
||||
_ZN9__gnu_cxx6__poolILb[01]EE17_M_reserve_memoryE[jm][jm];
|
||||
_ZN9__gnu_cxx6__poolILb[01]EE17_M_reclaim_memoryEPc[jm];
|
||||
_ZN9__gnu_cxx20__common_pool_policyILb[01]EE11_S_get_poolEv;
|
||||
_ZN9__gnu_cxx6__poolILb[01]EE16_M_reserve_blockE[jm][jm];
|
||||
_ZN9__gnu_cxx6__poolILb[01]EE16_M_reclaim_blockEPc[jm];
|
||||
_ZN9__gnu_cxx6__poolILb[01]EED[12]Ev;
|
||||
|
||||
# stub functions from libmath
|
||||
acosf;
|
||||
|
|
|
@ -56,17 +56,28 @@ namespace __gnu_cxx
|
|||
typedef void (*__destroy_handler)(void*);
|
||||
typedef void (*__create_handler)(void);
|
||||
|
||||
class __pool_base
|
||||
struct __pool_base
|
||||
{
|
||||
public:
|
||||
// Using short int as type for the binmap implies we are never
|
||||
// caching blocks larger than 65535 with this allocator.
|
||||
typedef unsigned short int _Binmap_type;
|
||||
|
||||
// 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 };
|
||||
enum { _S_min_bin = 8 };
|
||||
enum { _S_chunk_size = 4096 - 4 * sizeof(void*) };
|
||||
enum { _S_max_threads = 4096 };
|
||||
enum { _S_freelist_headroom = 10 };
|
||||
|
||||
// Alignment needed.
|
||||
// NB: In any case must be >= sizeof(_Block_record), that
|
||||
// is 4 on 32 bit machines and 8 on 64 bit machines.
|
||||
size_t _M_align;
|
||||
size_t _M_align;
|
||||
|
||||
// Allocation requests (after round-up to power of 2) below
|
||||
// this value will be handled by the allocator. A raw new/
|
||||
|
@ -75,14 +86,14 @@ namespace __gnu_cxx
|
|||
|
||||
// Size in bytes of the smallest bin.
|
||||
// NB: Must be a power of 2 and >= _M_align.
|
||||
size_t _M_min_bin;
|
||||
size_t _M_min_bin;
|
||||
|
||||
// In order to avoid fragmenting and minimize the number of
|
||||
// new() calls we always request new memory using this
|
||||
// value. Based on previous discussions on the libstdc++
|
||||
// mailing list we have choosen the value below.
|
||||
// See http://gcc.gnu.org/ml/libstdc++/2001-07/msg00077.html
|
||||
size_t _M_chunk_size;
|
||||
size_t _M_chunk_size;
|
||||
|
||||
// The maximum number of supported threads. For
|
||||
// single-threaded operation, use one. Maximum values will
|
||||
|
@ -105,9 +116,9 @@ namespace __gnu_cxx
|
|||
|
||||
explicit
|
||||
_Tune()
|
||||
: _M_align(8), _M_max_bytes(128), _M_min_bin(8),
|
||||
_M_chunk_size(4096 - 4 * sizeof(void*)),
|
||||
_M_max_threads(4096), _M_freelist_headroom(10),
|
||||
: _M_align(_S_align), _M_max_bytes(_S_max_bytes), _M_min_bin(_S_min_bin),
|
||||
_M_chunk_size(_S_chunk_size), _M_max_threads(_S_max_threads),
|
||||
_M_freelist_headroom(_S_freelist_headroom),
|
||||
_M_force_new(getenv("GLIBCXX_FORCE_NEW") ? true : false)
|
||||
{ }
|
||||
|
||||
|
@ -118,6 +129,25 @@ 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
|
||||
{
|
||||
void* _M_initial;
|
||||
_Block_address* _M_next;
|
||||
};
|
||||
|
||||
const _Tune&
|
||||
|
@ -140,20 +170,17 @@ namespace __gnu_cxx
|
|||
{ return _M_binmap[__bytes]; }
|
||||
|
||||
explicit __pool_base()
|
||||
: _M_init(false), _M_options(_Tune()), _M_binmap(NULL) { }
|
||||
: _M_options(_Tune()), _M_binmap(NULL), _M_init(false) { }
|
||||
|
||||
protected:
|
||||
// We need to create the initial lists and set up some variables
|
||||
// before we can answer to the first request for memory.
|
||||
bool _M_init;
|
||||
|
||||
// Configuration options.
|
||||
_Tune _M_options;
|
||||
|
||||
// Using short int as type for the binmap implies we are never
|
||||
// caching blocks larger than 65535 with this allocator.
|
||||
typedef unsigned short int _Binmap_type;
|
||||
_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.
|
||||
bool _M_init;
|
||||
};
|
||||
|
||||
// Data describing the underlying memory pool, parameterized on
|
||||
|
@ -204,10 +231,13 @@ namespace __gnu_cxx
|
|||
struct _Bin_record
|
||||
{
|
||||
// An "array" of pointers to the first free block for each
|
||||
// thread id. Memory to this "array" is allocated in _S_initialize()
|
||||
// for _S_max_threads + global pool 0.
|
||||
// thread id. Memory to this "array" is allocated in
|
||||
// _S_initialize() for _S_max_threads + global pool 0.
|
||||
_Block_record** volatile _M_first;
|
||||
|
||||
// A list of the initial addresses of all allocated blocks.
|
||||
_Block_address* _M_address;
|
||||
|
||||
// An "array" of counters used to keep track of the amount of
|
||||
// blocks that are on the freelist/used for each thread id.
|
||||
// Memory to these "arrays" is allocated in _S_initialize() for
|
||||
|
@ -242,10 +272,10 @@ namespace __gnu_cxx
|
|||
}
|
||||
|
||||
char*
|
||||
_M_reserve_memory(size_t __bytes, const size_t __thread_id);
|
||||
_M_reserve_block(size_t __bytes, const size_t __thread_id);
|
||||
|
||||
void
|
||||
_M_reclaim_memory(char* __p, size_t __bytes);
|
||||
_M_reclaim_block(char* __p, size_t __bytes);
|
||||
|
||||
const _Bin_record&
|
||||
_M_get_bin(size_t __which)
|
||||
|
@ -277,6 +307,8 @@ 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
|
||||
|
@ -289,6 +321,7 @@ namespace __gnu_cxx
|
|||
__gthread_once_t _M_once;
|
||||
|
||||
_Thread_record* _M_thread_freelist;
|
||||
void* _M_thread_freelist_initial;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -302,13 +335,14 @@ namespace __gnu_cxx
|
|||
// 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 for each
|
||||
// thread id. Memory to this "array" is allocated in _S_initialize()
|
||||
// for _S_max_threads + global pool 0.
|
||||
// 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
|
||||
|
@ -319,10 +353,10 @@ namespace __gnu_cxx
|
|||
}
|
||||
|
||||
char*
|
||||
_M_reserve_memory(size_t __bytes, const size_t __thread_id);
|
||||
_M_reserve_block(size_t __bytes, const size_t __thread_id);
|
||||
|
||||
void
|
||||
_M_reclaim_memory(char* __p, size_t __bytes);
|
||||
_M_reclaim_block(char* __p, size_t __bytes);
|
||||
|
||||
size_t
|
||||
_M_get_thread_id() { return 0; }
|
||||
|
@ -337,7 +371,9 @@ namespace __gnu_cxx
|
|||
|
||||
explicit __pool()
|
||||
: _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
|
||||
|
@ -351,10 +387,11 @@ namespace __gnu_cxx
|
|||
_M_initialize();
|
||||
};
|
||||
|
||||
|
||||
template<bool _Thread>
|
||||
struct __common_pool_policy
|
||||
{
|
||||
typedef __pool<_Thread> __pool_type;
|
||||
|
||||
template<typename _Tp1, bool _Thread1 = _Thread>
|
||||
struct _M_rebind;
|
||||
|
||||
|
@ -366,11 +403,12 @@ namespace __gnu_cxx
|
|||
struct _M_rebind<_Tp1, false>
|
||||
{ typedef __common_pool_policy<false> other; };
|
||||
|
||||
typedef __pool<_Thread> __pool_type;
|
||||
static __pool_type _S_data;
|
||||
|
||||
static __pool_type&
|
||||
_S_get_pool();
|
||||
_S_get_pool()
|
||||
{
|
||||
static __pool_type _S_pool;
|
||||
return _S_pool;
|
||||
}
|
||||
|
||||
static void
|
||||
_S_initialize_once()
|
||||
|
@ -391,6 +429,8 @@ namespace __gnu_cxx
|
|||
template<>
|
||||
struct __common_pool_policy<true>
|
||||
{
|
||||
typedef __pool<true> __pool_type;
|
||||
|
||||
template<typename _Tp1, bool _Thread1 = true>
|
||||
struct _M_rebind;
|
||||
|
||||
|
@ -402,11 +442,12 @@ namespace __gnu_cxx
|
|||
struct _M_rebind<_Tp1, false>
|
||||
{ typedef __common_pool_policy<false> other; };
|
||||
|
||||
typedef __pool<true> __pool_type;
|
||||
static __pool_type _S_data;
|
||||
|
||||
static __pool_type&
|
||||
_S_get_pool();
|
||||
_S_get_pool()
|
||||
{
|
||||
static __pool_type _S_pool;
|
||||
return _S_pool;
|
||||
}
|
||||
|
||||
static void
|
||||
_S_destroy_thread_key(void* __freelist_pos)
|
||||
|
@ -429,9 +470,12 @@ namespace __gnu_cxx
|
|||
};
|
||||
#endif
|
||||
|
||||
|
||||
template<typename _Tp, bool _Thread>
|
||||
struct __per_type_pool_policy
|
||||
{
|
||||
typedef __pool<_Thread> __pool_type;
|
||||
|
||||
template<typename _Tp1, bool _Thread1 = _Thread>
|
||||
struct _M_rebind;
|
||||
|
||||
|
@ -443,11 +487,13 @@ namespace __gnu_cxx
|
|||
struct _M_rebind<_Tp1, true>
|
||||
{ typedef __per_type_pool_policy<_Tp1, true> other; };
|
||||
|
||||
typedef __pool<_Thread> __pool_type;
|
||||
static __pool_type _S_data;
|
||||
|
||||
// Avoid static initialization ordering issues.
|
||||
static __pool_type&
|
||||
_S_get_pool( ) { return _S_data; }
|
||||
_S_get_pool()
|
||||
{
|
||||
static __pool_type _S_pool;
|
||||
return _S_pool;
|
||||
}
|
||||
|
||||
static void
|
||||
_S_initialize_once()
|
||||
|
@ -461,10 +507,6 @@ namespace __gnu_cxx
|
|||
}
|
||||
};
|
||||
|
||||
template<typename _Tp, bool _Thread>
|
||||
__pool<_Thread>
|
||||
__per_type_pool_policy<_Tp, _Thread>::_S_data;
|
||||
|
||||
template<typename _Tp>
|
||||
struct __per_type_pool_policy<_Tp, true>;
|
||||
|
||||
|
@ -472,6 +514,8 @@ namespace __gnu_cxx
|
|||
template<typename _Tp>
|
||||
struct __per_type_pool_policy<_Tp, true>
|
||||
{
|
||||
typedef __pool<true> __pool_type;
|
||||
|
||||
template<typename _Tp1, bool _Thread1 = true>
|
||||
struct _M_rebind;
|
||||
|
||||
|
@ -483,11 +527,13 @@ namespace __gnu_cxx
|
|||
struct _M_rebind<_Tp1, true>
|
||||
{ typedef __per_type_pool_policy<_Tp1, true> other; };
|
||||
|
||||
typedef __pool<true> __pool_type;
|
||||
static __pool_type _S_data;
|
||||
|
||||
// Avoid static initialization ordering issues.
|
||||
static __pool_type&
|
||||
_S_get_pool( ) { return _S_data; }
|
||||
_S_get_pool( )
|
||||
{
|
||||
static __pool_type _S_pool;
|
||||
return _S_pool;
|
||||
}
|
||||
|
||||
static void
|
||||
_S_destroy_thread_key(void* __freelist_pos)
|
||||
|
@ -508,16 +554,6 @@ namespace __gnu_cxx
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
__pool<true>
|
||||
__per_type_pool_policy<_Tp, true>::_S_data;
|
||||
#endif
|
||||
|
||||
#ifdef __GTHREADS
|
||||
typedef __common_pool_policy<true> __default_policy;
|
||||
#else
|
||||
typedef __common_pool_policy<false> __default_policy;
|
||||
#endif
|
||||
|
||||
template<typename _Tp>
|
||||
|
@ -554,8 +590,14 @@ namespace __gnu_cxx
|
|||
destroy(pointer __p) { __p->~_Tp(); }
|
||||
};
|
||||
|
||||
#ifdef __GTHREADS
|
||||
#define __default_policy __common_pool_policy<true>
|
||||
#else
|
||||
#define __default_policy __common_pool_policy<false>
|
||||
#endif
|
||||
|
||||
template<typename _Tp, typename _Poolp = __default_policy>
|
||||
class __mt_alloc : public __mt_alloc_base<_Tp>, _Poolp
|
||||
class __mt_alloc : public __mt_alloc_base<_Tp>, _Poolp
|
||||
{
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
|
@ -575,21 +617,18 @@ namespace __gnu_cxx
|
|||
typedef __mt_alloc<_Tp1, pol_type> other;
|
||||
};
|
||||
|
||||
// Create pool instance so that order of construction will be
|
||||
// pool_type first, then allocator. This is necessary for
|
||||
// correct global and static object construction/destruction.
|
||||
__mt_alloc() throw()
|
||||
{
|
||||
// XXX
|
||||
}
|
||||
{ __policy_type::_S_get_pool(); }
|
||||
|
||||
__mt_alloc(const __mt_alloc&) throw()
|
||||
{
|
||||
// XXX
|
||||
}
|
||||
{ __policy_type::_S_get_pool(); }
|
||||
|
||||
template<typename _Tp1, typename _Poolp1>
|
||||
__mt_alloc(const __mt_alloc<_Tp1, _Poolp1>& obj) throw()
|
||||
{
|
||||
// XXX
|
||||
}
|
||||
{ __policy_type::_S_get_pool(); }
|
||||
|
||||
~__mt_alloc() throw() { }
|
||||
|
||||
|
@ -620,23 +659,23 @@ namespace __gnu_cxx
|
|||
|
||||
// Requests larger than _M_max_bytes are handled by new/delete
|
||||
// directly.
|
||||
__pool_type& __pl = this->_S_get_pool();
|
||||
__pool_type& __pool = this->_S_get_pool();
|
||||
const size_t __bytes = __n * sizeof(_Tp);
|
||||
if (__pl._M_check_threshold(__bytes))
|
||||
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 = __pl._M_get_binmap(__bytes);
|
||||
const size_t __thread_id = __pl._M_get_thread_id();
|
||||
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 = __pl._M_get_bin(__which);
|
||||
const _Bin_record& __bin = __pool._M_get_bin(__which);
|
||||
if (__bin._M_first[__thread_id])
|
||||
{
|
||||
// Already reserved.
|
||||
|
@ -644,14 +683,14 @@ namespace __gnu_cxx
|
|||
_Block_record* __block = __bin._M_first[__thread_id];
|
||||
__bin._M_first[__thread_id] = __bin._M_first[__thread_id]->_M_next;
|
||||
|
||||
__pl._M_adjust_freelist(__bin, __block, __thread_id);
|
||||
const __pool_base::_Tune& __options = __pl._M_get_options();
|
||||
__pool._M_adjust_freelist(__bin, __block, __thread_id);
|
||||
const __pool_base::_Tune& __options = __pool._M_get_options();
|
||||
__c = reinterpret_cast<char*>(__block) + __options._M_align;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Null, reserve.
|
||||
__c = __pl._M_reserve_memory(__bytes, __thread_id);
|
||||
__c = __pool._M_reserve_block(__bytes, __thread_id);
|
||||
}
|
||||
return static_cast<_Tp*>(static_cast<void*>(__c));
|
||||
}
|
||||
|
@ -663,12 +702,12 @@ namespace __gnu_cxx
|
|||
{
|
||||
// Requests larger than _M_max_bytes are handled by operators
|
||||
// new/delete directly.
|
||||
__pool_type& __pl = this->_S_get_pool();
|
||||
__pool_type& __pool = this->_S_get_pool();
|
||||
const size_t __bytes = __n * sizeof(_Tp);
|
||||
if (__pl._M_check_threshold(__bytes))
|
||||
if (__pool._M_check_threshold(__bytes))
|
||||
::operator delete(__p);
|
||||
else
|
||||
__pl._M_reclaim_memory(reinterpret_cast<char*>(__p), __bytes);
|
||||
__pool._M_reclaim_block(reinterpret_cast<char*>(__p), __bytes);
|
||||
}
|
||||
|
||||
template<typename _Tp, typename _Poolp>
|
||||
|
@ -680,6 +719,8 @@ namespace __gnu_cxx
|
|||
inline bool
|
||||
operator!=(const __mt_alloc<_Tp, _Poolp>&, const __mt_alloc<_Tp, _Poolp>&)
|
||||
{ return false; }
|
||||
|
||||
#undef __default_policy
|
||||
} // namespace __gnu_cxx
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
//
|
||||
|
||||
#include <bits/c++config.h>
|
||||
#include <ext/mt_allocator.h>
|
||||
#include <bits/concurrence.h>
|
||||
#include <ext/mt_allocator.h>
|
||||
|
||||
namespace __gnu_internal
|
||||
{
|
||||
|
@ -46,18 +46,185 @@ namespace __gnu_internal
|
|||
|
||||
namespace __gnu_cxx
|
||||
{
|
||||
#ifdef __GTHREADS
|
||||
__pool<false>::~__pool()
|
||||
{
|
||||
if (_M_init && !_M_options._M_force_new)
|
||||
{
|
||||
for (size_t __n = 0; __n < _M_bin_size; ++__n)
|
||||
{
|
||||
_Bin_record& __bin = _M_bin[__n];
|
||||
while (__bin._M_address)
|
||||
{
|
||||
_Block_address* __tmp = __bin._M_address->_M_next;
|
||||
::operator delete(__bin._M_address->_M_initial);
|
||||
delete __bin._M_address;
|
||||
__bin._M_address = __tmp;
|
||||
}
|
||||
delete __bin._M_first;
|
||||
}
|
||||
delete _M_bin;
|
||||
delete _M_binmap;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
__pool<true>::_M_reclaim_memory(char* __p, size_t __bytes)
|
||||
__pool<false>::_M_reclaim_block(char* __p, size_t __bytes)
|
||||
{
|
||||
// Round up to power of 2 and figure out which bin to use.
|
||||
const size_t __which = _M_binmap[__bytes];
|
||||
_Bin_record& __bin = _M_bin[__which];
|
||||
|
||||
const _Tune& __options = _M_get_options();
|
||||
char* __c = __p - __options._M_align;
|
||||
_Block_record* __block = reinterpret_cast<_Block_record*>(__c);
|
||||
|
||||
// Single threaded application - return to global pool.
|
||||
__block->_M_next = __bin._M_first[0];
|
||||
__bin._M_first[0] = __block;
|
||||
}
|
||||
|
||||
char*
|
||||
__pool<false>::_M_reserve_block(size_t __bytes, const size_t __thread_id)
|
||||
{
|
||||
// Round up to power of 2 and figure out which bin to use.
|
||||
const size_t __which = _M_binmap[__bytes];
|
||||
const _Tune& __options = _M_get_options();
|
||||
const size_t __bin_size = ((__options._M_min_bin << __which)
|
||||
+ __options._M_align);
|
||||
size_t __block_count = __options._M_chunk_size / __bin_size;
|
||||
|
||||
// Get a new block dynamically, set it up for use.
|
||||
void* __v = ::operator new(__options._M_chunk_size);
|
||||
_Block_record* __block = static_cast<_Block_record*>(__v);
|
||||
--__block_count;
|
||||
_Block_record* __tmp = __block;
|
||||
while (__block_count-- > 0)
|
||||
{
|
||||
char* __c = reinterpret_cast<char*>(__tmp) + __bin_size;
|
||||
__tmp->_M_next = reinterpret_cast<_Block_record*>(__c);
|
||||
__tmp = __tmp->_M_next;
|
||||
}
|
||||
__tmp->_M_next = NULL;
|
||||
|
||||
// Update _Bin_record fields.
|
||||
_Bin_record& __bin = _M_bin[__which];
|
||||
__bin._M_first[__thread_id] = __block->_M_next;
|
||||
_Block_address* __address = new _Block_address;
|
||||
__address->_M_initial = __v;
|
||||
__address->_M_next = __bin._M_address;
|
||||
__bin._M_address = __address;
|
||||
|
||||
// NB: For alignment reasons, we can't use the first _M_align
|
||||
// bytes, even when sizeof(_Block_record) < _M_align.
|
||||
return reinterpret_cast<char*>(__block) + __options._M_align;
|
||||
}
|
||||
|
||||
void
|
||||
__pool<false>::_M_initialize()
|
||||
{
|
||||
// _M_force_new must not change after the first allocate(), which
|
||||
// in turn calls this method, so if it's false, it's false forever
|
||||
// and we don't need to return here ever again.
|
||||
if (_M_options._M_force_new)
|
||||
{
|
||||
_M_init = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the bins.
|
||||
// Calculate the number of bins required based on _M_max_bytes.
|
||||
// _M_bin_size is statically-initialized to one.
|
||||
size_t __bin_size = _M_options._M_min_bin;
|
||||
while (_M_options._M_max_bytes > __bin_size)
|
||||
{
|
||||
__bin_size <<= 1;
|
||||
++_M_bin_size;
|
||||
}
|
||||
|
||||
// Setup the bin map for quick lookup of the relevant bin.
|
||||
const size_t __j = (_M_options._M_max_bytes + 1) * sizeof(_Binmap_type);
|
||||
_M_binmap = static_cast<_Binmap_type*>(::operator new(__j));
|
||||
_Binmap_type* __bp = _M_binmap;
|
||||
_Binmap_type __bin_max = _M_options._M_min_bin;
|
||||
_Binmap_type __bint = 0;
|
||||
for (_Binmap_type __ct = 0; __ct <= _M_options._M_max_bytes; ++__ct)
|
||||
{
|
||||
if (__ct > __bin_max)
|
||||
{
|
||||
__bin_max <<= 1;
|
||||
++__bint;
|
||||
}
|
||||
*__bp++ = __bint;
|
||||
}
|
||||
|
||||
// Initialize _M_bin and its members.
|
||||
void* __v = ::operator new(sizeof(_Bin_record) * _M_bin_size);
|
||||
_M_bin = static_cast<_Bin_record*>(__v);
|
||||
for (size_t __n = 0; __n < _M_bin_size; ++__n)
|
||||
{
|
||||
_Bin_record& __bin = _M_bin[__n];
|
||||
__v = ::operator new(sizeof(_Block_record*));
|
||||
__bin._M_first = static_cast<_Block_record**>(__v);
|
||||
__bin._M_first[0] = NULL;
|
||||
__bin._M_address = NULL;
|
||||
}
|
||||
_M_init = true;
|
||||
}
|
||||
|
||||
#ifdef __GTHREADS
|
||||
__pool<true>::~__pool()
|
||||
{
|
||||
if (_M_init && !_M_options._M_force_new)
|
||||
{
|
||||
if (__gthread_active_p())
|
||||
{
|
||||
for (size_t __n = 0; __n < _M_bin_size; ++__n)
|
||||
{
|
||||
_Bin_record& __bin = _M_bin[__n];
|
||||
while (__bin._M_address)
|
||||
{
|
||||
_Block_address* __tmp = __bin._M_address->_M_next;
|
||||
::operator delete(__bin._M_address->_M_initial);
|
||||
delete __bin._M_address;
|
||||
__bin._M_address = __tmp;
|
||||
}
|
||||
delete __bin._M_first;
|
||||
delete __bin._M_free;
|
||||
delete __bin._M_used;
|
||||
delete __bin._M_mutex;
|
||||
}
|
||||
::operator delete(_M_thread_freelist_initial);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t __n = 0; __n < _M_bin_size; ++__n)
|
||||
{
|
||||
_Bin_record& __bin = _M_bin[__n];
|
||||
while (__bin._M_address)
|
||||
{
|
||||
_Block_address* __tmp = __bin._M_address->_M_next;
|
||||
::operator delete(__bin._M_address->_M_initial);
|
||||
delete __bin._M_address;
|
||||
__bin._M_address = __tmp;
|
||||
}
|
||||
delete __bin._M_first;
|
||||
}
|
||||
}
|
||||
delete _M_bin;
|
||||
delete _M_binmap;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
__pool<true>::_M_reclaim_block(char* __p, size_t __bytes)
|
||||
{
|
||||
// Round up to power of 2 and figure out which bin to use.
|
||||
const size_t __which = _M_binmap[__bytes];
|
||||
const _Bin_record& __bin = _M_bin[__which];
|
||||
|
||||
const _Tune& __options = _M_get_options();
|
||||
|
||||
char* __c = __p - __options._M_align;
|
||||
_Block_record* __block = reinterpret_cast<_Block_record*>(__c);
|
||||
|
||||
if (__gthread_active_p())
|
||||
{
|
||||
// Calculate the number of records to remove from our freelist:
|
||||
|
@ -106,38 +273,13 @@ namespace __gnu_cxx
|
|||
__bin._M_first[0] = __block;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
__pool<false>::_M_reclaim_memory(char* __p, size_t __bytes)
|
||||
{
|
||||
// Round up to power of 2 and figure out which bin to use.
|
||||
const size_t __which = _M_binmap[__bytes];
|
||||
const _Bin_record& __bin = _M_bin[__which];
|
||||
const _Tune& __options = _M_get_options();
|
||||
|
||||
char* __c = __p - __options._M_align;
|
||||
_Block_record* __block = reinterpret_cast<_Block_record*>(__c);
|
||||
|
||||
// Single threaded application - return to global pool.
|
||||
__block->_M_next = __bin._M_first[0];
|
||||
__bin._M_first[0] = __block;
|
||||
}
|
||||
|
||||
#ifdef __GTHREADS
|
||||
char*
|
||||
__pool<true>::_M_reserve_memory(size_t __bytes, const size_t __thread_id)
|
||||
__pool<true>::_M_reserve_block(size_t __bytes, const size_t __thread_id)
|
||||
{
|
||||
// Round up to power of 2 and figure out which bin to use.
|
||||
const size_t __which = _M_binmap[__bytes];
|
||||
|
||||
// If here, there are no blocks on our freelist.
|
||||
const _Tune& __options = _M_get_options();
|
||||
_Block_record* __block = NULL;
|
||||
const _Bin_record& __bin = _M_bin[__which];
|
||||
|
||||
// NB: For alignment reasons, we can't use the first _M_align
|
||||
// bytes, even when sizeof(_Block_record) < _M_align.
|
||||
const size_t __bin_size = ((__options._M_min_bin << __which)
|
||||
+ __options._M_align);
|
||||
size_t __block_count = __options._M_chunk_size / __bin_size;
|
||||
|
@ -152,19 +294,17 @@ namespace __gnu_cxx
|
|||
// no need to lock or change ownership but check for free
|
||||
// blocks on global list (and if not add new ones) and
|
||||
// get the first one.
|
||||
_Bin_record& __bin = _M_bin[__which];
|
||||
_Block_record* __block = NULL;
|
||||
if (__gthread_active_p())
|
||||
{
|
||||
__gthread_mutex_lock(__bin._M_mutex);
|
||||
if (__bin._M_first[0] == NULL)
|
||||
{
|
||||
// No need to hold the lock when we are adding a
|
||||
// whole chunk to our own list.
|
||||
__gthread_mutex_unlock(__bin._M_mutex);
|
||||
|
||||
// No need to hold the lock when we are adding a whole
|
||||
// chunk to our own list.
|
||||
void* __v = ::operator new(__options._M_chunk_size);
|
||||
__bin._M_first[__thread_id] = static_cast<_Block_record*>(__v);
|
||||
__bin._M_free[__thread_id] = __block_count;
|
||||
|
||||
--__block_count;
|
||||
__block = __bin._M_first[__thread_id];
|
||||
while (__block_count-- > 0)
|
||||
|
@ -174,12 +314,20 @@ namespace __gnu_cxx
|
|||
__block = __block->_M_next;
|
||||
}
|
||||
__block->_M_next = NULL;
|
||||
|
||||
__gthread_mutex_lock(__bin._M_mutex);
|
||||
_Block_address* __address = new _Block_address;
|
||||
__address->_M_initial = __v;
|
||||
__address->_M_next = __bin._M_address;
|
||||
__bin._M_address = __address;
|
||||
__gthread_mutex_unlock(__bin._M_mutex);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Is the number of required blocks greater than or
|
||||
// equal to the number that can be provided by the
|
||||
// global free list?
|
||||
// Is the number of required blocks greater than or equal
|
||||
// to the number that can be provided by the global free
|
||||
// list?
|
||||
__gthread_mutex_lock(__bin._M_mutex);
|
||||
__bin._M_first[__thread_id] = __bin._M_first[0];
|
||||
if (__block_count >= __bin._M_free[0])
|
||||
{
|
||||
|
@ -204,10 +352,9 @@ namespace __gnu_cxx
|
|||
else
|
||||
{
|
||||
void* __v = ::operator new(__options._M_chunk_size);
|
||||
__bin._M_first[0] = static_cast<_Block_record*>(__v);
|
||||
|
||||
__block = static_cast<_Block_record*>(__v);
|
||||
__bin._M_first[0] = __block;
|
||||
--__block_count;
|
||||
__block = __bin._M_first[0];
|
||||
while (__block_count-- > 0)
|
||||
{
|
||||
char* __c = reinterpret_cast<char*>(__block) + __bin_size;
|
||||
|
@ -215,6 +362,11 @@ namespace __gnu_cxx
|
|||
__block = __block->_M_next;
|
||||
}
|
||||
__block->_M_next = NULL;
|
||||
|
||||
_Block_address* __address = new _Block_address;
|
||||
__address->_M_initial = __v;
|
||||
__address->_M_next = __bin._M_address;
|
||||
__bin._M_address = __address;
|
||||
}
|
||||
|
||||
__block = __bin._M_first[__thread_id];
|
||||
|
@ -226,53 +378,15 @@ namespace __gnu_cxx
|
|||
--__bin._M_free[__thread_id];
|
||||
++__bin._M_used[__thread_id];
|
||||
}
|
||||
return reinterpret_cast<char*>(__block) + __options._M_align;
|
||||
}
|
||||
#endif
|
||||
|
||||
char*
|
||||
__pool<false>::_M_reserve_memory(size_t __bytes, const size_t __thread_id)
|
||||
{
|
||||
// Round up to power of 2 and figure out which bin to use.
|
||||
const size_t __which = _M_binmap[__bytes];
|
||||
|
||||
// If here, there are no blocks on our freelist.
|
||||
const _Tune& __options = _M_get_options();
|
||||
_Block_record* __block = NULL;
|
||||
const _Bin_record& __bin = _M_bin[__which];
|
||||
|
||||
// NB: For alignment reasons, we can't use the first _M_align
|
||||
// bytes, even when sizeof(_Block_record) < _M_align.
|
||||
const size_t __bin_size = ((__options._M_min_bin << __which)
|
||||
+ __options._M_align);
|
||||
size_t __block_count = __options._M_chunk_size / __bin_size;
|
||||
|
||||
// Not using threads.
|
||||
void* __v = ::operator new(__options._M_chunk_size);
|
||||
__bin._M_first[0] = static_cast<_Block_record*>(__v);
|
||||
|
||||
--__block_count;
|
||||
__block = __bin._M_first[0];
|
||||
while (__block_count-- > 0)
|
||||
{
|
||||
char* __c = reinterpret_cast<char*>(__block) + __bin_size;
|
||||
__block->_M_next = reinterpret_cast<_Block_record*>(__c);
|
||||
__block = __block->_M_next;
|
||||
}
|
||||
__block->_M_next = NULL;
|
||||
|
||||
__block = __bin._M_first[__thread_id];
|
||||
__bin._M_first[__thread_id] = __bin._M_first[__thread_id]->_M_next;
|
||||
return reinterpret_cast<char*>(__block) + __options._M_align;
|
||||
}
|
||||
|
||||
#ifdef __GTHREADS
|
||||
void
|
||||
__pool<true>::_M_initialize(__destroy_handler __d)
|
||||
{
|
||||
// This method is called on the first allocation (when _M_init
|
||||
// is still false) to create the bins.
|
||||
|
||||
// _M_force_new must not change after the first allocate(),
|
||||
// which in turn calls this method, so if it's false, it's false
|
||||
// forever and we don't need to return here ever again.
|
||||
|
@ -282,6 +396,7 @@ namespace __gnu_cxx
|
|||
return;
|
||||
}
|
||||
|
||||
// Create the bins.
|
||||
// Calculate the number of bins required based on _M_max_bytes.
|
||||
// _M_bin_size is statically-initialized to one.
|
||||
size_t __bin_size = _M_options._M_min_bin;
|
||||
|
@ -294,7 +409,6 @@ namespace __gnu_cxx
|
|||
// Setup the bin map for quick lookup of the relevant bin.
|
||||
const size_t __j = (_M_options._M_max_bytes + 1) * sizeof(_Binmap_type);
|
||||
_M_binmap = static_cast<_Binmap_type*>(::operator new(__j));
|
||||
|
||||
_Binmap_type* __bp = _M_binmap;
|
||||
_Binmap_type __bin_max = _M_options._M_min_bin;
|
||||
_Binmap_type __bint = 0;
|
||||
|
@ -320,6 +434,7 @@ namespace __gnu_cxx
|
|||
const size_t __k = sizeof(_Thread_record) * _M_options._M_max_threads;
|
||||
__v = ::operator new(__k);
|
||||
_M_thread_freelist = static_cast<_Thread_record*>(__v);
|
||||
_M_thread_freelist_initial = __v;
|
||||
|
||||
// NOTE! The first assignable thread id is 1 since the
|
||||
// global pool uses id 0
|
||||
|
@ -345,7 +460,9 @@ namespace __gnu_cxx
|
|||
_Bin_record& __bin = _M_bin[__n];
|
||||
__v = ::operator new(sizeof(_Block_record*) * __max_threads);
|
||||
__bin._M_first = static_cast<_Block_record**>(__v);
|
||||
|
||||
|
||||
__bin._M_address = NULL;
|
||||
|
||||
__v = ::operator new(sizeof(size_t) * __max_threads);
|
||||
__bin._M_free = static_cast<size_t*>(__v);
|
||||
|
||||
|
@ -364,9 +481,7 @@ namespace __gnu_cxx
|
|||
#else
|
||||
{ __GTHREAD_MUTEX_INIT_FUNCTION(__bin._M_mutex); }
|
||||
#endif
|
||||
|
||||
for (size_t __threadn = 0; __threadn < __max_threads;
|
||||
++__threadn)
|
||||
for (size_t __threadn = 0; __threadn < __max_threads; ++__threadn)
|
||||
{
|
||||
__bin._M_first[__threadn] = NULL;
|
||||
__bin._M_free[__threadn] = 0;
|
||||
|
@ -375,73 +490,19 @@ namespace __gnu_cxx
|
|||
}
|
||||
}
|
||||
else
|
||||
for (size_t __n = 0; __n < _M_bin_size; ++__n)
|
||||
{
|
||||
_Bin_record& __bin = _M_bin[__n];
|
||||
__v = ::operator new(sizeof(_Block_record*));
|
||||
__bin._M_first = static_cast<_Block_record**>(__v);
|
||||
__bin._M_first[0] = NULL;
|
||||
}
|
||||
_M_init = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
__pool<false>::_M_initialize()
|
||||
{
|
||||
// This method is called on the first allocation (when _M_init
|
||||
// is still false) to create the bins.
|
||||
|
||||
// _M_force_new must not change after the first allocate(),
|
||||
// which in turn calls this method, so if it's false, it's false
|
||||
// forever and we don't need to return here ever again.
|
||||
if (_M_options._M_force_new)
|
||||
{
|
||||
_M_init = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the number of bins required based on _M_max_bytes.
|
||||
// _M_bin_size is statically-initialized to one.
|
||||
size_t __bin_size = _M_options._M_min_bin;
|
||||
while (_M_options._M_max_bytes > __bin_size)
|
||||
{
|
||||
__bin_size <<= 1;
|
||||
++_M_bin_size;
|
||||
}
|
||||
|
||||
// Setup the bin map for quick lookup of the relevant bin.
|
||||
const size_t __j = (_M_options._M_max_bytes + 1) * sizeof(_Binmap_type);
|
||||
_M_binmap = static_cast<_Binmap_type*>(::operator new(__j));
|
||||
|
||||
_Binmap_type* __bp = _M_binmap;
|
||||
_Binmap_type __bin_max = _M_options._M_min_bin;
|
||||
_Binmap_type __bint = 0;
|
||||
for (_Binmap_type __ct = 0; __ct <= _M_options._M_max_bytes; ++__ct)
|
||||
{
|
||||
if (__ct > __bin_max)
|
||||
for (size_t __n = 0; __n < _M_bin_size; ++__n)
|
||||
{
|
||||
__bin_max <<= 1;
|
||||
++__bint;
|
||||
_Bin_record& __bin = _M_bin[__n];
|
||||
__v = ::operator new(sizeof(_Block_record*));
|
||||
__bin._M_first = static_cast<_Block_record**>(__v);
|
||||
__bin._M_first[0] = NULL;
|
||||
__bin._M_address = NULL;
|
||||
}
|
||||
*__bp++ = __bint;
|
||||
}
|
||||
|
||||
// Initialize _M_bin and its members.
|
||||
void* __v = ::operator new(sizeof(_Bin_record) * _M_bin_size);
|
||||
_M_bin = static_cast<_Bin_record*>(__v);
|
||||
|
||||
for (size_t __n = 0; __n < _M_bin_size; ++__n)
|
||||
{
|
||||
_Bin_record& __bin = _M_bin[__n];
|
||||
__v = ::operator new(sizeof(_Block_record*));
|
||||
__bin._M_first = static_cast<_Block_record**>(__v);
|
||||
__bin._M_first[0] = NULL;
|
||||
}
|
||||
_M_init = true;
|
||||
}
|
||||
|
||||
#ifdef __GTHREADS
|
||||
|
||||
size_t
|
||||
__pool<true>::_M_get_thread_id()
|
||||
{
|
||||
|
@ -486,23 +547,6 @@ namespace __gnu_cxx
|
|||
}
|
||||
#endif
|
||||
|
||||
// Definitions for non-exported bits of __common_pool.
|
||||
#ifdef __GTHREADS
|
||||
__pool<true>
|
||||
__common_pool_policy<true>::_S_data = __pool<true>();
|
||||
|
||||
__pool<true>&
|
||||
__common_pool_policy<true>::_S_get_pool() { return _S_data; }
|
||||
#endif
|
||||
|
||||
template<>
|
||||
__pool<false>
|
||||
__common_pool_policy<false>::_S_data = __pool<false>();
|
||||
|
||||
template<>
|
||||
__pool<false>&
|
||||
__common_pool_policy<false>::_S_get_pool() { return _S_data; }
|
||||
|
||||
// Instantiations.
|
||||
template class __mt_alloc<char>;
|
||||
template class __mt_alloc<wchar_t>;
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
//
|
||||
// Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// 20.4.1.1 allocator members
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <ext/malloc_allocator.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
static size_t count;
|
||||
|
||||
struct count_check
|
||||
{
|
||||
count_check() {}
|
||||
~count_check()
|
||||
{
|
||||
if (count != 0)
|
||||
throw std::runtime_error("count isn't zero");
|
||||
}
|
||||
};
|
||||
|
||||
static count_check check;
|
||||
|
||||
void* operator new(size_t size) throw(std::bad_alloc)
|
||||
{
|
||||
printf("operator new is called \n");
|
||||
void* p = malloc(size);
|
||||
if (p == NULL)
|
||||
throw std::bad_alloc();
|
||||
count++;
|
||||
return p;
|
||||
}
|
||||
|
||||
void operator delete(void* p) throw()
|
||||
{
|
||||
printf("operator delete is called \n");
|
||||
if (p == NULL)
|
||||
return;
|
||||
count--;
|
||||
if (count == 0)
|
||||
printf("All memory released \n");
|
||||
else
|
||||
printf("%u allocations to be released \n", count);
|
||||
free(p);
|
||||
}
|
||||
|
||||
typedef char char_t;
|
||||
typedef std::char_traits<char_t> traits_t;
|
||||
typedef __gnu_cxx::malloc_allocator<char_t> allocator_t;
|
||||
typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
|
||||
|
||||
string_t s("bayou bend");
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
//
|
||||
// Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// 20.4.1.1 allocator members
|
||||
|
||||
#include <string>
|
||||
#include <ext/malloc_allocator.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
static size_t alloc_cnt;
|
||||
|
||||
void* operator new(size_t size) throw(std::bad_alloc)
|
||||
{
|
||||
printf("operator new is called \n");
|
||||
void* p = malloc(size);
|
||||
if (p == NULL)
|
||||
throw std::bad_alloc();
|
||||
alloc_cnt++;
|
||||
return p;
|
||||
}
|
||||
|
||||
void operator delete(void* p) throw()
|
||||
{
|
||||
printf("operator delete is called \n");
|
||||
if (p == NULL)
|
||||
return;
|
||||
alloc_cnt--;
|
||||
if (alloc_cnt == 0)
|
||||
printf("All memory released \n");
|
||||
else
|
||||
printf("%u allocations to be released \n", alloc_cnt);
|
||||
free(p);
|
||||
}
|
||||
|
||||
typedef char char_t;
|
||||
typedef std::char_traits<char_t> traits_t;
|
||||
typedef __gnu_cxx::malloc_allocator<char_t> allocator_t;
|
||||
typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
|
||||
|
||||
int main()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
{
|
||||
string_t s;
|
||||
s += "bayou bend";
|
||||
}
|
||||
VERIFY( alloc_cnt == 0 );
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
//
|
||||
// Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// 20.4.1.1 allocator members
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <ext/mt_allocator.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
static size_t count;
|
||||
|
||||
struct count_check
|
||||
{
|
||||
count_check() {}
|
||||
~count_check()
|
||||
{
|
||||
if (count != 0)
|
||||
throw std::runtime_error("count isn't zero");
|
||||
}
|
||||
};
|
||||
|
||||
static count_check check;
|
||||
|
||||
void* operator new(size_t size) throw(std::bad_alloc)
|
||||
{
|
||||
printf("operator new is called \n");
|
||||
void* p = malloc(size);
|
||||
if (p == NULL)
|
||||
throw std::bad_alloc();
|
||||
count++;
|
||||
return p;
|
||||
}
|
||||
|
||||
void operator delete(void* p) throw()
|
||||
{
|
||||
printf("operator delete is called \n");
|
||||
if (p == NULL)
|
||||
return;
|
||||
count--;
|
||||
if (count == 0)
|
||||
printf("All memory released \n");
|
||||
else
|
||||
printf("%u allocations to be released \n", count);
|
||||
free(p);
|
||||
}
|
||||
|
||||
typedef char char_t;
|
||||
typedef std::char_traits<char_t> traits_t;
|
||||
typedef __gnu_cxx::__common_pool_policy<true> pool_t;
|
||||
typedef __gnu_cxx::__mt_alloc<char_t, pool_t> allocator_t;
|
||||
typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
|
||||
|
||||
string_t s("bayou bend");
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
//
|
||||
// Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// 20.4.1.1 allocator members
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <ext/mt_allocator.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
static size_t count;
|
||||
|
||||
struct count_check
|
||||
{
|
||||
count_check() {}
|
||||
~count_check()
|
||||
{
|
||||
if (count != 0)
|
||||
throw std::exception();
|
||||
}
|
||||
};
|
||||
|
||||
static count_check check;
|
||||
|
||||
void* operator new(size_t size) throw(std::bad_alloc)
|
||||
{
|
||||
printf("operator new is called \n");
|
||||
void* p = malloc(size);
|
||||
if (p == NULL)
|
||||
throw std::bad_alloc();
|
||||
count++;
|
||||
return p;
|
||||
}
|
||||
|
||||
void operator delete(void* p) throw()
|
||||
{
|
||||
printf("operator delete is called \n");
|
||||
if (p == NULL)
|
||||
return;
|
||||
count--;
|
||||
if (count == 0)
|
||||
printf("All memory released \n");
|
||||
else
|
||||
printf("%u allocations to be released \n", count);
|
||||
free(p);
|
||||
}
|
||||
|
||||
typedef char char_t;
|
||||
typedef std::char_traits<char_t> traits_t;
|
||||
typedef __gnu_cxx::__common_pool_policy<false> pool_t;
|
||||
typedef __gnu_cxx::__mt_alloc<char_t, pool_t> allocator_t;
|
||||
typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
|
||||
|
||||
string_t s("bayou bend");
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
//
|
||||
// Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// 20.4.1.1 allocator members
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <ext/mt_allocator.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
static size_t count;
|
||||
|
||||
struct count_check
|
||||
{
|
||||
count_check() {}
|
||||
~count_check()
|
||||
{
|
||||
if (count != 0)
|
||||
throw std::runtime_error("count isn't zero");
|
||||
}
|
||||
};
|
||||
|
||||
static count_check check;
|
||||
|
||||
void* operator new(size_t size) throw(std::bad_alloc)
|
||||
{
|
||||
printf("operator new is called \n");
|
||||
void* p = malloc(size);
|
||||
if (p == NULL)
|
||||
throw std::bad_alloc();
|
||||
count++;
|
||||
return p;
|
||||
}
|
||||
|
||||
void operator delete(void* p) throw()
|
||||
{
|
||||
printf("operator delete is called \n");
|
||||
if (p == NULL)
|
||||
return;
|
||||
count--;
|
||||
if (count == 0)
|
||||
printf("All memory released \n");
|
||||
else
|
||||
printf("%u allocations to be released \n", count);
|
||||
free(p);
|
||||
}
|
||||
|
||||
typedef char char_t;
|
||||
typedef std::char_traits<char_t> traits_t;
|
||||
typedef __gnu_cxx::__per_type_pool_policy<char_t, true> pool_t;
|
||||
typedef __gnu_cxx::__mt_alloc<char_t, pool_t> allocator_t;
|
||||
typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
|
||||
|
||||
string_t s("bayou bend");
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
//
|
||||
// Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// 20.4.1.1 allocator members
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <ext/mt_allocator.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
static size_t count;
|
||||
|
||||
struct count_check
|
||||
{
|
||||
count_check() {}
|
||||
~count_check()
|
||||
{
|
||||
if (count != 0)
|
||||
throw std::runtime_error("count isn't zero");
|
||||
}
|
||||
};
|
||||
|
||||
static count_check check;
|
||||
|
||||
void* operator new(size_t size) throw(std::bad_alloc)
|
||||
{
|
||||
printf("operator new is called \n");
|
||||
void* p = malloc(size);
|
||||
if (p == NULL)
|
||||
throw std::bad_alloc();
|
||||
count++;
|
||||
return p;
|
||||
}
|
||||
|
||||
void operator delete(void* p) throw()
|
||||
{
|
||||
printf("operator delete is called \n");
|
||||
if (p == NULL)
|
||||
return;
|
||||
count--;
|
||||
if (count == 0)
|
||||
printf("All memory released \n");
|
||||
else
|
||||
printf("%u allocations to be released \n", count);
|
||||
free(p);
|
||||
}
|
||||
|
||||
typedef char char_t;
|
||||
typedef std::char_traits<char_t> traits_t;
|
||||
typedef __gnu_cxx::__per_type_pool_policy<char_t, false> pool_t;
|
||||
typedef __gnu_cxx::__mt_alloc<char_t, pool_t> allocator_t;
|
||||
typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
|
||||
|
||||
string_t s("bayou bend");
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// 20.4.1.1 allocator members
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <ext/mt_allocator.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
static size_t count;
|
||||
|
||||
struct count_check
|
||||
{
|
||||
count_check() {}
|
||||
~count_check()
|
||||
{
|
||||
if (count != 0)
|
||||
throw std::runtime_error("count isn't zero");
|
||||
}
|
||||
};
|
||||
|
||||
static count_check check;
|
||||
|
||||
void* operator new(size_t size) throw(std::bad_alloc)
|
||||
{
|
||||
printf("operator new is called \n");
|
||||
void* p = malloc(size);
|
||||
if (p == NULL)
|
||||
throw std::bad_alloc();
|
||||
count++;
|
||||
return p;
|
||||
}
|
||||
|
||||
void operator delete(void* p) throw()
|
||||
{
|
||||
printf("operator delete is called \n");
|
||||
if (p == NULL)
|
||||
return;
|
||||
count--;
|
||||
if (count == 0)
|
||||
printf("All memory released \n");
|
||||
else
|
||||
printf("%u allocations to be released \n", count);
|
||||
free(p);
|
||||
}
|
||||
|
||||
typedef char char_t;
|
||||
typedef std::char_traits<char_t> traits_t;
|
||||
typedef __gnu_cxx::__common_pool_policy<true> pool_t;
|
||||
typedef __gnu_cxx::__mt_alloc<char_t, pool_t> allocator_t;
|
||||
typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
|
||||
|
||||
int main()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
{
|
||||
string_t s;
|
||||
s += "bayou bend";
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// 20.4.1.1 allocator members
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <ext/mt_allocator.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
static size_t count;
|
||||
|
||||
struct count_check
|
||||
{
|
||||
count_check() {}
|
||||
~count_check()
|
||||
{
|
||||
if (count != 0)
|
||||
throw std::runtime_error("count isn't zero");
|
||||
}
|
||||
};
|
||||
|
||||
static count_check check;
|
||||
|
||||
void* operator new(size_t size) throw(std::bad_alloc)
|
||||
{
|
||||
printf("operator new is called \n");
|
||||
void* p = malloc(size);
|
||||
if (p == NULL)
|
||||
throw std::bad_alloc();
|
||||
count++;
|
||||
return p;
|
||||
}
|
||||
|
||||
void operator delete(void* p) throw()
|
||||
{
|
||||
printf("operator delete is called \n");
|
||||
if (p == NULL)
|
||||
return;
|
||||
count--;
|
||||
if (count == 0)
|
||||
printf("All memory released \n");
|
||||
else
|
||||
printf("%u allocations to be released \n", count);
|
||||
free(p);
|
||||
}
|
||||
|
||||
typedef char char_t;
|
||||
typedef std::char_traits<char_t> traits_t;
|
||||
typedef __gnu_cxx::__common_pool_policy<false> pool_t;
|
||||
typedef __gnu_cxx::__mt_alloc<char_t, pool_t> allocator_t;
|
||||
typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
|
||||
|
||||
int main()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
{
|
||||
string_t s;
|
||||
s += "bayou bend";
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// 20.4.1.1 allocator members
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <ext/mt_allocator.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
static size_t count;
|
||||
|
||||
struct count_check
|
||||
{
|
||||
count_check() {}
|
||||
~count_check()
|
||||
{
|
||||
if (count != 0)
|
||||
throw std::runtime_error("count isn't zero");
|
||||
}
|
||||
};
|
||||
|
||||
static count_check check;
|
||||
|
||||
void* operator new(size_t size) throw(std::bad_alloc)
|
||||
{
|
||||
printf("operator new is called \n");
|
||||
void* p = malloc(size);
|
||||
if (p == NULL)
|
||||
throw std::bad_alloc();
|
||||
count++;
|
||||
return p;
|
||||
}
|
||||
|
||||
void operator delete(void* p) throw()
|
||||
{
|
||||
printf("operator delete is called \n");
|
||||
if (p == NULL)
|
||||
return;
|
||||
count--;
|
||||
if (count == 0)
|
||||
printf("All memory released \n");
|
||||
else
|
||||
printf("%u allocations to be released \n", count);
|
||||
free(p);
|
||||
}
|
||||
|
||||
typedef char char_t;
|
||||
typedef std::char_traits<char_t> traits_t;
|
||||
typedef __gnu_cxx::__per_type_pool_policy<char_t, true> pool_t;
|
||||
typedef __gnu_cxx::__mt_alloc<char_t, pool_t> allocator_t;
|
||||
typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
|
||||
|
||||
int main()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
{
|
||||
string_t s;
|
||||
s += "bayou bend";
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// 20.4.1.1 allocator members
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <ext/mt_allocator.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
static size_t count;
|
||||
|
||||
struct count_check
|
||||
{
|
||||
count_check() {}
|
||||
~count_check()
|
||||
{
|
||||
if (count != 0)
|
||||
throw std::runtime_error("count isn't zero");
|
||||
}
|
||||
};
|
||||
|
||||
static count_check check;
|
||||
|
||||
void* operator new(size_t size) throw(std::bad_alloc)
|
||||
{
|
||||
printf("operator new is called \n");
|
||||
void* p = malloc(size);
|
||||
if (p == NULL)
|
||||
throw std::bad_alloc();
|
||||
count++;
|
||||
return p;
|
||||
}
|
||||
|
||||
void operator delete(void* p) throw()
|
||||
{
|
||||
printf("operator delete is called \n");
|
||||
if (p == NULL)
|
||||
return;
|
||||
count--;
|
||||
if (count == 0)
|
||||
printf("All memory released \n");
|
||||
else
|
||||
printf("%u allocations to be released \n", count);
|
||||
free(p);
|
||||
}
|
||||
|
||||
typedef char char_t;
|
||||
typedef std::char_traits<char_t> traits_t;
|
||||
typedef __gnu_cxx::__per_type_pool_policy<char_t, false> pool_t;
|
||||
typedef __gnu_cxx::__mt_alloc<char_t, pool_t> allocator_t;
|
||||
typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
|
||||
|
||||
int main()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
{
|
||||
string_t s;
|
||||
s += "bayou bend";
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -25,4 +25,9 @@
|
|||
#include <cstdlib>
|
||||
#include <ext/mt_allocator.h>
|
||||
|
||||
template class __gnu_cxx::__mt_alloc<int>;
|
||||
using namespace __gnu_cxx;
|
||||
template class __mt_alloc<int>;
|
||||
template class __mt_alloc<short, __common_pool_policy<true> >;
|
||||
template class __mt_alloc<short, __common_pool_policy<false> >;
|
||||
template class __mt_alloc<short, __per_type_pool_policy<short, true> >;
|
||||
template class __mt_alloc<short, __per_type_pool_policy<short, false> >;
|
||||
|
|
55
libstdc++-v3/testsuite/ext/new_allocator/check_new.cc
Normal file
55
libstdc++-v3/testsuite/ext/new_allocator/check_new.cc
Normal file
|
@ -0,0 +1,55 @@
|
|||
// 2001-11-25 Phil Edwards <pme@gcc.gnu.org>
|
||||
//
|
||||
// Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// 20.4.1.1 allocator members
|
||||
|
||||
#include <cstdlib>
|
||||
#include <ext/new_allocator.h>
|
||||
#include <testsuite_allocator.h>
|
||||
|
||||
using __gnu_cxx::new_allocator;
|
||||
|
||||
void*
|
||||
operator new(std::size_t n) throw(std::bad_alloc)
|
||||
{
|
||||
new_called = true;
|
||||
requested = n;
|
||||
return std::malloc(n);
|
||||
}
|
||||
|
||||
void
|
||||
operator delete(void *v) throw()
|
||||
{
|
||||
delete_called = true;
|
||||
return std::free(v);
|
||||
}
|
||||
|
||||
// These just help tracking down error messages.
|
||||
bool test01()
|
||||
{
|
||||
typedef new_allocator<unsigned int> allocator_type;
|
||||
return (__gnu_test::check_new<allocator_type, true>() == true);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
return test01();
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
//
|
||||
// Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// 20.4.1.1 allocator members
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <ext/new_allocator.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
static size_t count;
|
||||
|
||||
struct count_check
|
||||
{
|
||||
count_check() {}
|
||||
~count_check()
|
||||
{
|
||||
if (count != 0)
|
||||
throw std::runtime_error("count isn't zero");
|
||||
}
|
||||
};
|
||||
|
||||
static count_check check;
|
||||
|
||||
void* operator new(size_t size) throw(std::bad_alloc)
|
||||
{
|
||||
printf("operator new is called \n");
|
||||
void* p = malloc(size);
|
||||
if (p == NULL)
|
||||
throw std::bad_alloc();
|
||||
count++;
|
||||
return p;
|
||||
}
|
||||
|
||||
void operator delete(void* p) throw()
|
||||
{
|
||||
printf("operator delete is called \n");
|
||||
if (p == NULL)
|
||||
return;
|
||||
count--;
|
||||
if (count == 0)
|
||||
printf("All memory released \n");
|
||||
else
|
||||
printf("%u allocations to be released \n", count);
|
||||
free(p);
|
||||
}
|
||||
|
||||
typedef char char_t;
|
||||
typedef std::char_traits<char_t> traits_t;
|
||||
typedef __gnu_cxx::new_allocator<char_t> allocator_t;
|
||||
typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
|
||||
|
||||
string_t s("bayou bend");
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
65
libstdc++-v3/testsuite/ext/new_allocator/deallocate_local.cc
Normal file
65
libstdc++-v3/testsuite/ext/new_allocator/deallocate_local.cc
Normal file
|
@ -0,0 +1,65 @@
|
|||
//
|
||||
// Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// 20.4.1.1 allocator members
|
||||
|
||||
#include <string>
|
||||
#include <ext/new_allocator.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
static size_t alloc_cnt;
|
||||
|
||||
void* operator new(size_t size) throw(std::bad_alloc)
|
||||
{
|
||||
printf("operator new is called \n");
|
||||
void* p = malloc(size);
|
||||
if (p == NULL)
|
||||
throw std::bad_alloc();
|
||||
alloc_cnt++;
|
||||
return p;
|
||||
}
|
||||
|
||||
void operator delete(void* p) throw()
|
||||
{
|
||||
printf("operator delete is called \n");
|
||||
if (p == NULL)
|
||||
return;
|
||||
alloc_cnt--;
|
||||
if (alloc_cnt == 0)
|
||||
printf("All memory released \n");
|
||||
else
|
||||
printf("%u allocations to be released \n", alloc_cnt);
|
||||
free(p);
|
||||
}
|
||||
|
||||
typedef char char_t;
|
||||
typedef std::char_traits<char_t> traits_t;
|
||||
typedef __gnu_cxx::new_allocator<char_t> allocator_t;
|
||||
typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
|
||||
|
||||
int main()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
{
|
||||
string_t s;
|
||||
s += "bayou bend";
|
||||
}
|
||||
VERIFY( alloc_cnt == 0 );
|
||||
return 0;
|
||||
}
|
28
libstdc++-v3/testsuite/ext/new_allocator/instantiate.cc
Normal file
28
libstdc++-v3/testsuite/ext/new_allocator/instantiate.cc
Normal file
|
@ -0,0 +1,28 @@
|
|||
// { dg-do compile }
|
||||
|
||||
// 2001-11-25 Phil Edwards <pme@gcc.gnu.org>
|
||||
//
|
||||
// Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// 20.4.1.1 allocator members
|
||||
|
||||
#include <cstdlib>
|
||||
#include <ext/new_allocator.h>
|
||||
|
||||
template class __gnu_cxx::new_allocator<int>;
|
Loading…
Add table
Reference in a new issue